OpenGL学习笔记(七)座标系统的运用

对我们来说,座标系统大致分为5个不同的座标系统:

局部空间(Local Space,或者称为物体空间(Object Space))
世界空间(World Space)
观察空间(View Space,或者称为视觉空间(Eye Space))
裁剪空间(Clip Space)
屏幕空间(Screen Space)
在这里插入图片描述
上图有点类似于shader的流水线操作:
1,局部座标是对象相对于局部原点的座标,也是物体起始的座标。
2,下一步是将局部座标变换为世界空间座标,世界空间座标是处于一个更大的空间范围的。这些座标相对于世界的全局原点,它们会和其它物体一起相对于世界的原点进行摆放。
3,接下来我们将世界座标变换为观察空间座标,使得每个座标都是从摄像机或者说观察者的角度进行观察的。
4,座标到达观察空间之后,我们需要将其投影到裁剪座标。裁剪座标会被处理至-1.0到1.0的范围内,并判断哪些顶点将会出现在屏幕上。
5,最后,我们将裁剪座标变换为屏幕座标,我们将使用一个叫做视口变换(Viewport Transform)的过程。视口变换将位于-1.0到1.0范围的座标变换到由glViewport函数所定义的座标范围内。最后变换出来的座标将会送到光栅器,将其转化为片段。
以前我们都是画的二维图像,现在这次就要开始画3维的了。
老样子先开始shader的修改:
这次的fragmentSource没有什么改变,改变的只有vertexSource:

#version 330 core                     
out vec4 vertexColor; 
out vec2 TextureCoord;
layout(location = 3) in vec3 aPos;							
layout(location = 4) in vec3 aColor;	
layout(location = 5) in vec2 aTextureCoord;	
uniform mat4 transform;
uniform mat4 modelMat;
uniform mat4 viewMat;
uniform mat4 projMat;
void main(){	
//这个乘以的顺序一定不能错,否则就会失败还没有提示
gl_Position = projMat*viewMat*modelMat*vec4(aPos.x, aPos.y, aPos.z, 1.0);
 vertexColor=vec4(aColor,1.0f);
  TextureCoord=aTextureCoord;
}

接下来是main.cpp
先是变一下顶点数组,以及添加一个位置数组

float vertices[] = {
	-0.5f, -0.5f, -0.5f,  0.0f, 0.0f,
	 0.5f, -0.5f, -0.5f,  1.0f, 0.0f,
	 0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
	 0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
	-0.5f,  0.5f, -0.5f,  0.0f, 1.0f,
	-0.5f, -0.5f, -0.5f,  0.0f, 0.0f,

	-0.5f, -0.5f,  0.5f,  0.0f, 0.0f,
	 0.5f, -0.5f,  0.5f,  1.0f, 0.0f,
	 0.5f,  0.5f,  0.5f,  1.0f, 1.0f,
	 0.5f,  0.5f,  0.5f,  1.0f, 1.0f,
	-0.5f,  0.5f,  0.5f,  0.0f, 1.0f,
	-0.5f, -0.5f,  0.5f,  0.0f, 0.0f,

	-0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
	-0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
	-0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
	-0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
	-0.5f, -0.5f,  0.5f,  0.0f, 0.0f,
	-0.5f,  0.5f,  0.5f,  1.0f, 0.0f,

	 0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
	 0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
	 0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
	 0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
	 0.5f, -0.5f,  0.5f,  0.0f, 0.0f,
	 0.5f,  0.5f,  0.5f,  1.0f, 0.0f,

	-0.5f, -0.5f, -0.5f,  0.0f, 1.0f,
	 0.5f, -0.5f, -0.5f,  1.0f, 1.0f,
	 0.5f, -0.5f,  0.5f,  1.0f, 0.0f,
	 0.5f, -0.5f,  0.5f,  1.0f, 0.0f,
	-0.5f, -0.5f,  0.5f,  0.0f, 0.0f,
	-0.5f, -0.5f, -0.5f,  0.0f, 1.0f,

	-0.5f,  0.5f, -0.5f,  0.0f, 1.0f,
	 0.5f,  0.5f, -0.5f,  1.0f, 1.0f,
	 0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
	 0.5f,  0.5f,  0.5f,  1.0f, 0.0f,
	-0.5f,  0.5f,  0.5f,  0.0f, 0.0f,
	-0.5f,  0.5f, -0.5f,  0.0f, 1.0f
};
glm::vec3 cubePositions[] = {
  glm::vec3(0.0f,  0.0f,  0.0f),
  glm::vec3(2.0f,  5.0f, -15.0f),
  glm::vec3(-1.5f, -2.2f, -2.5f),
  glm::vec3(-3.8f, -2.0f, -12.3f),
  glm::vec3(2.4f, -0.4f, -3.5f),
  glm::vec3(-1.7f,  3.0f, -7.5f),
  glm::vec3(1.3f, -2.0f, -2.5f),
  glm::vec3(1.5f,  2.0f, -2.5f),
  glm::vec3(1.5f,  0.2f, -1.5f),
  glm::vec3(-1.3f,  1.0f, -1.5f)
};

我们可以发现顶点数组中,没有颜色数值,所以我们的

glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)0);//从vao里面在0号索引位上拿取三个值
glVertexAttribPointer(4, 3, GL_FLOAT, GL_FALSE, 8* sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));//从vao里面在0号索引位上拿取三个值
glVertexAttribPointer(5, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (GLvoid*)(6 * sizeof(GLfloat)));//从vao里面在0号索引位上拿取三个值
	glEnableVertexAttribArray(3);//启用属性0,因为默认是禁用的
	glEnableVertexAttribArray(4);//启用属性0,因为默认是禁用的
	glEnableVertexAttribArray(5);//启用属性0,因为默认是禁用的

需要改为

glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)0);//从vao里面在0号索引位上拿取三个值
glVertexAttribPointer(5, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));//从vao里面在0号索引位上拿取三个值
	glEnableVertexAttribArray(3);//启用属性0,因为默认是禁用的
	glEnableVertexAttribArray(5);//启用属性0,因为默认是禁用的

再者就是

   //模型举证在后面,主要负责位移,旋转,缩放
    glm::mat4 viewMat;//视图矩阵,其实就是摄像机视角位置
	viewMat = glm::translate(viewMat, glm::vec3(0, 0, -5.0f));
	glm::mat4 projMat;//投影矩阵,通过这个来剪切画面到标准化座标系
	projMat = glm::perspective(glm::radians(45.0f), (float)WIDTH / (float)HEIGHT, 0.01f, 100.0f);//这个是摄像机
	glEnable(GL_DEPTH_TEST);
Shader* myShader = new Shader("vertexSource.txt", "fragmentSource.txt");
	// Game loop
	while (!glfwWindowShouldClose(window))
	{	// 检查事件,调用相应的回调函数,如下文的glfwInput函数
		glfwInput(window);
		
		//trans = glm::translate(trans, glm::vec3(0.01f, 0, 0));

		glClearColor(0.2f, 0.3f, 0.3f, 1.0f);//渲染颜色到后台缓冲
		glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);//清除前台缓冲

		glActiveTexture(GL_TEXTURE0);
		glBindTexture(GL_TEXTURE_2D, texbufferA);//绑定

		glActiveTexture(GL_TEXTURE2);
		glBindTexture(GL_TEXTURE_2D, texbufferB);//绑定

		glBindVertexArray(VAO);//每次循环都调用,绑定函数绑定VAO
		//glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
		for (size_t i = 1; i <= 10; i++)
		{
			glm::mat4 modelMat;//模型矩阵
			modelMat = glm::translate(modelMat, cubePositions[i]);//根据cubPosition定义位置
			if(i==1||i%3==0)//1和能整除3的旋转
			modelMat = glm::rotate(modelMat, (float)glfwGetTime(), glm::vec3(0, 1.0f, 0));
			else
				modelMat = glm::rotate(modelMat, glm::radians(i*10.0f), glm::vec3(0, 1.0f, 0));
				
			myShader->Use();
			glUniform1i(glGetUniformLocation(myShader->ID, "ourTexture"), 0);
			glUniform1i(glGetUniformLocation(myShader->ID, "ourFace"), 2);
			//glUniformMatrix4fv(glGetUniformLocation(myShader->ID,"transform"),1,GL_FALSE,glm::value_ptr(trans));
			glUniformMatrix4fv(glGetUniformLocation(myShader->ID, "modelMat"), 1, GL_FALSE, glm::value_ptr(modelMat));
			glUniformMatrix4fv(glGetUniformLocation(myShader->ID, "viewMat"), 1, GL_FALSE, glm::value_ptr(viewMat));
			glUniformMatrix4fv(glGetUniformLocation(myShader->ID, "projMat"), 1, GL_FALSE, glm::value_ptr(projMat));
			glDrawArrays(GL_TRIANGLES, 0, 36);
		}
	
		//glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);//绘制三角形,根据索引数组绘制6个顶点,索引数组类型为GL_UNSIGNED_INT,偏移值为0
		//glDrawArrays(GL_TRIANGLES, 0, 3);//开始绘制三角形从0起始,画三组数值
		//glBindVertexArray(0);//解绑

		// Swap the screen buffers
		glfwSwapBuffers(window);
		glfwPollEvents();
	}


输出效果如下:
在这里插入图片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章