[英]How to use GLM with OpenGL?
我正在嘗試使用GLM渲染對象以進行矩陣轉換,但是我得到了這一點:
編輯:忘記提及我要渲染的對象是一個簡單的Torus。
我做了很多研究,發現一件事是glGetUniformLocation(program, "mvp")
返回-1
。 文檔說如果着色器中沒有使用統一變量,即使聲明了它,它將返回-1
。 如下所示,它已被聲明並在頂點着色器中使用。 我檢查了program
以確保它是有效的,等等。
所以我的問題是:
為什么glGetUniformLocation(program, "mvp")
返回-1
即使它已被聲明並在頂點着色器中使用?
我還不太清楚的另一件事。 我的GameObject類具有一個名為Mesh的結構,具有變量GLuint vao
和GLuint[4] vbo
(頂點數組對象)和(頂點緩沖區對象)。 我正在使用Assimp,而我的GameObject類基於本教程 。 使用與教程相同的方式渲染網格。
glBindVertexArray(vao);
glDrawElements(GL_TRIANGLES, elementCount, GL_UNSIGNED_INT, NULL);
我不確定VAO和VBO的工作方式。 我發現,如果要在整個程序中訪問頂點數組,則使用VAO;如果只想將其發送到圖形卡,而不要再次觸摸它,則使用VBO(如果我錯了,請糾正我)這里)。 那么,為什么本教程將它們混合在一起呢? 在網格的構造函數中,它創建並綁定VAO,然后在其余構造函數中不使用它(除非創建和綁定VBO對當前綁定的VAO產生影響)。 然后,它繼續為頂點緩沖區,法線緩沖區,紋理坐標緩沖區和索引緩沖區創建並綁定VBO。 為了渲染對象,它綁定了VAO並調用glDrawElements
。 我感到困惑的是OpenGL如何/在何處訪問VBO,如果不能通過本教程中的設置進行訪問(我很確定可以),則需要更改什么?
void GameObject::render() {
GLuint program = material->shader->program;
glUseProgram(program);
glm::mat4 mvp = Game::camera->mvpMatrix(this->position);
GLuint mvpLoc = glGetUniformLocation(program, "mvp");
printf("MVP Location: %d\n", mvpLoc); // prints -1
glUniformMatrix4fv(mvpLoc, 1, GL_FALSE, &mvp[0][0]);
for (unsigned int i = 0; i < meshes.size(); i++) {
meshes.at(i)->render(); // renders element array for each mesh in the GameObject
}
}
頂點着色器(簡單的未點亮紅色):
#version 330 core
layout(location = 0) in vec3 position;
uniform mat4 mvp;
out vec3 vertColor;
void main(void) {
gl_Position = mvp * vec4(position, 1);
vertColor = vec3(1, 0, 0);
}
片段着色器:
#version 330 core
in vec3 vertColor;
out vec3 color;
void main(void) {
color = vertColor;
}
問題1
您已經親自回答了這個問題。 glGetUniformLocation(program, name)
獲取着色器程序program
中的統一"mvp"
的位置,如果未聲明(或不使用)統一,則返回-1:如果不使用它,則不會對其進行編譯)。 您的着色器確實聲明並使用了mvp,這強烈表明編譯程序存在問題。 您確定在程序中使用此着色器嗎?
問題2
VBO存儲GPU將使用的數據值。 這些可以是顏色值,法線,紋理坐標,無論您喜歡什么。 VAO用於表示VBO的布局-將其視為地圖,向您的程序指示在VBO中可以找到數據的位置。
該示例程序在調用glVertexAttribPointer時確實會觸摸VAO,例如
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
這與您丟失的制服無關。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.