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();
	}


輸出效果如下:
在這裏插入圖片描述

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