OpenGL學習 (六)座標系統
參考官方文檔https://learnopengl-cn.github.io/
將座標變換爲標準化設備座標,然後轉換爲屏幕座標的過程是分佈進行的。有5個比較重要的座標系統:
- 局部座標
- 世界座標
- 觀察座標
- 裁剪座標
- 屏幕座標
座標變換的過程中會用到幾個變換矩陣:模型、觀察、投影矩陣。
現在我們可以進行3D繪圖了。
頂點着色器shader.vs
#version 330 core
layout(location=0) in vec3 aPos;
layout(location=1) in vec3 aColor;
layout(location=2) in vec2 aTexCoord;
out vec3 ourColor;
out vec2 TexCoord;
uniform mat4 transform;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
void main(){
gl_Position=projection*view*model*vec4(aPos.x,aPos.y,aPos.z,1.0);
ourColor=aColor;
TexCoord=vec2(aTexCoord.x,1.0-aTexCoord.y);
}
main.cpp
...;
const unsigned int screenWidth = 800, screenHeight = 600;
...;
while(...){
...;
ourShader.use();
//
glm::mat4 model = glm::mat4(1.0f);
model = glm::rotate(model, glm::radians(-55.0f), glm::vec3(1.0f, 0.0f, 0.0f));
glm::mat4 view = glm::mat4(1.0f);
view = glm::translate(view, glm::vec3(0.0f, 0.0f, -3.0f));
glm::mat4 projection = glm::mat4(1.0f);
projection = glm::perspective(glm::radians(45.0f), (float)screenWidth / (float)screenHeight, 0.1f, 100.0f);
int modelLoc = glGetUniformLocation(ourShader.ID, "model");
glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));
int viewLoc = glGetUniformLocation(ourShader.ID, "view");
glUniformMatri![opentk_40](C:\Users\xhh\Pictures\QQ瀏覽器截圖\opentk_40.png)x4fv(viewLoc, 1, GL_FALSE, &view[0][0]);
int projectionLoc = glGetUniformLocation(ourShader.ID, "projection");
glUniformMatrix4fv(projectionLoc, 1, GL_FALSE, glm::value_ptr(projection));
...;
}
...;
最後運行的效果爲:
然後我們來渲染一個立方體:
main.cpp
...;
float vertices[] = {
// ---- 位置 ---- - 紋理座標 -
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, 0.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, 0.0f, 0.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, 0.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, 0.0f, 0.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, 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, 1.0f, 0.0f, // 左上
-0.5f, -0.5f, 0.5f, 1.0f, 1.0f, // 右上
0.5f, -0.5f,0.5f, 0.0f, 1.0f, // 左下
};
...;
while(...){
...;
//每次迭代之前清楚深度緩衝和顏色緩衝
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
//開啓深度測試
glEnable(GL_DEPTH_TEST);
...;
model = glm::rotate(model,(float)glfwGetTime()* glm::radians(55.0f), glm::vec3(0.5f, 1.0f, 0.0f));
...;
glDrawArrays(GL_TRIANGLES, 0, 36);
...;
}
...;
這樣運行的結果如圖
另外,我們還可以在屏幕上顯示更多的立方體:
...;
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)
};
...;
while(...){
...;
glBindVertexArray(VAO);
for (unsigned int i = 0; i < 10; i++)
{
glm::mat4 model=glm::mat4(1.0f);
model = glm::translate(model, cubePositions[i]);
float angle = 20.0f * i;
model = glm::rotate(model,(float)glfwGetTime()* glm::radians(angle), glm::vec3(1.0f, 0.3f, 0.5f));
ourShader.setMat4("model", model);
glDrawArrays(GL_TRIANGLES, 0, 36);
}
...;
}
這樣會得到10個旋轉着的立方體。