我發現在思考現代OpenGL時,最好忘記glMatrixMode
曾經存在過。
考慮到這一點,讓我們回顧一下最基本的繪製操作所需要的:代替gl_ModelViewProjectionMatrix
。顧名思義,這是3種不同矩陣的組合:模型矩陣,視圖矩陣和投影矩陣。
所以你需要在你的着色器中容納這個是3個統一的變量,類型爲mat4
。你會這樣使用:
uniform mat4 projMat;
uniform mat4 viewMat;
uniform mat4 modelMat;
layout (location = 0) in vec3 position;
void main()
{
gl_Position = projMat * viewMat * modelMat * vec4(position, 1.0);
}
這一點的着色器代碼執行相同的功能,你在上面。什麼改變是內置的gl_ModelViewProjectionMatrix
被3個統一變量取代(如果你確保在傳入C++端時自己將它們相乘,可以將它們組合爲一個變量)。內置的gl_Vertex
被輸入變量替換。
在C++方面,你需要做2件事情。首先,您需要獲得位置爲這些制服:
GLuint modelMatIdx = glGetUniformLocation(shaderProgId, "modelMat");
GLuint viewMatIdx = glGetUniformLocation(shaderProgId, "viewMat");
GLuint projMatIdx = glGetUniformLocation(shaderProgId, "projMat");
而與此在手,你可以在每個均勻權值使用glUniformMatrix4fv
繪製前傳現在。
一個特別容易使用的庫是glm。例如,要獲得相同的投影矩陣在你的榜樣,你會怎麼做:
glm::mat4 projMat = glm::frustum(-RProjZ, +RProjZ, -Aspect*RProjZ, +Aspect*RProjZ, 1.0, 32768.0);
,你會在它傳遞像這樣:
glUniformMatrix4fv(projMatIdx, 1, GL_FALSE, glm::value_ptr(projMat));
現在你知道怎麼了,我想解決「什麼時候」的問題。你說你不清楚矩陣模式的東西,這讓我回到我以前的「忘掉它」的說法。矩陣模式在那裏,以便您可以告訴opengl哪些內置應該受到OpenGL矩陣操作(如glTranslate,glFrustum等)的調用的影響,但現在所有這些都消失了。您現在負責管理涉及的(可能很多)矩陣。所有你需要做的就是在你畫畫之前把它們傳進去(正如我上面所顯示的那樣),你會好起來的。在嘗試修改制服之前,確保程序已經綁定。
下面是一個工作示例(如果您驚訝於gl :: ...而不是gl ...這是因爲我使用的是由glLoadGen生成的opengl頭文件,它將所有的opengl API函數放入gl命名空間)。
GLuint simpleProgramID;
// load the shader and make the program
GLuint modelMatIdx = gl::GetUniformLocation(simpleProgramID, "modelMat");
GLuint viewMatIdx = gl::GetUniformLocation(simpleProgramID, "viewMat");
GLuint projMatIdx = gl::GetUniformLocation(simpleProgramID, "projMat");
GLuint vaoID;
gl::GenVertexArrays(1, &vaoID);
gl::BindVertexArray(vaoID);
GLuint vertBufferID, indexBufferID;
gl::GenBuffers(1, &vertBufferID);
gl::GenBuffers(1, &indexBufferID);
struct Vec2 { float x, y; };
struct Vec3 { float x, y, z; };
struct Vert { Vec3 pos; Vec2 tex; };
std::array<Vert, 8> cubeVerts = {{
{ { 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, 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 }, { 1.0f, 0.0f } }
}};
std::array<unsigned int, 36> cubeIdxs = {{
0, 2, 1, 0, 3, 2, // Right
4, 5, 6, 4, 6, 7, // Left
0, 7, 3, 0, 4, 7, // Top
1, 6, 2, 1, 5, 6, // Bottom
0, 5, 1, 0, 4, 5, // Front
3, 7, 6, 3, 6, 2 // Back
}};
// Vertex buffer
gl::BindBuffer(gl::ARRAY_BUFFER, vertBufferID);
gl::BufferData(gl::ARRAY_BUFFER, sizeof(Vert) * cubeVerts.size(), cubeVerts.data(), gl::STATIC_DRAW);
gl::EnableVertexAttribArray(0); // Matches layout (location = 0)
gl::VertexAttribPointer(0, 3, gl::FLOAT, gl::FALSE_, sizeof(Vert), 0);
gl::EnableVertexAttribArray(1); // Matches layout (location = 1)
gl::VertexAttribPointer(1, 2, gl::FLOAT, gl::FALSE_, sizeof(Vert), (GLvoid*)sizeof(Vec3));
// Index buffer
gl::BindBuffer(gl::ELEMENT_ARRAY_BUFFER, indexBufferID);
gl::BufferData(gl::ELEMENT_ARRAY_BUFFER, sizeof(unsigned int) * cubeIdxs.size(), cubeIdxs.data(), gl::STATIC_DRAW);
gl::BindVertexArray(0);
glm::mat4 projMat = glm::perspective(56.25f, 16.0f/9.0f, 0.1f, 100.0f);
glm::mat4 viewMat = glm::lookAt(glm::vec3(5, 5, 5), glm::vec3(0, 0, 0), glm::vec3(0, 0, 1));
glm::mat4 modelMat; // identity
while (!glfwWindowShouldClose(window))
{
gl::Clear(gl::COLOR_BUFFER_BIT | gl::DEPTH_BUFFER_BIT);
gl::UseProgram(simpleProgramID);
gl::UniformMatrix4fv(projMatIdx, 1, gl::FALSE_, glm::value_ptr(projMat));
gl::UniformMatrix4fv(viewMatIdx, 1, gl::FALSE_, glm::value_ptr(viewMat));
gl::UniformMatrix4fv(modelMatIdx, 1, gl::FALSE_, glm::value_ptr(modelMat));
gl::BindVertexArray(vaoID);
gl::DrawElements(gl::TRIANGLES, 36, gl::UNSIGNED_INT, 0);
gl::BindVertexArray(0);
gl::UseProgram(0);
glfwSwapBuffers(window);
glfwPollEvents();
}
相關頂點着色器:
//[VERTEX SHADER]
#version 430
uniform mat4 projMat;
uniform mat4 viewMat;
uniform mat4 modelMat;
layout (location = 0) in vec3 in_position; // matches gl::EnableVertexAttribArray(0);
layout (location = 1) in vec2 in_uv; // matches gl::EnableVertexAttribArray(1);
out vec2 uv;
void main()
{
gl_Position = projMat * viewMat * modelMat * vec4(in_position, 1.0);
uv = in_uv;
}
最後片段着色器:
//[FRAGMENT SHADER]
#version 430
in vec2 uv;
out vec4 color;
void main()
{
color = vec4(uv, 0.0, 1.0);
}
產生的圖像是:
現在有另一種意見在這一點上有相當多的信息,但是幾分鐘前被刪除,而一個-1代替,但我沒有找到時間複製鏈接並閱讀所有信息。我在原來的問題中增加了更多信息,它被刪除了,因爲我認爲這不適合我的問題。 – Gnampf