我想在OpenGL中繪製2個對象。窗口/視口是(0,0,950,1050)。我不確定這是否是正確的做法,但我是這麼認爲的。我認爲這個想法是爲每個對象創建一個VBO/VAO,綁定它,設置數據,併爲每個對象重複該操作。在OpenGL4中繪製兩個對象?
然後,當物體被繪製:
- 設置着色器
- 綁定的第一個對象的數據,我們想用它的VBO(比如vbo1)
- 做繪圖調用繪製
- 綁定的下一個對象的數據,我們想用它的VBO繪製(比如vbo2)
- 做繪圖調用
- ...
當我這樣做時,我只能得到第二個對象在屏幕上繪製的點,但是第一個對象的顏色(它是藍色而不是紅色)。
我的錯誤對任何專家都是顯而易見的。我錯過了什麼?
// BLUE -----------------------------------
GLuint vbo1, vao1;
glGenBuffers(1, &vbo1);
glBindBuffer(GL_ARRAY_BUFFER, vbo1);
float arr1[] = { 10, 10, 10, 110, 110, 110, 110, 10 };
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 8, arr1, GL_STATIC_DRAW);
glGenVertexArrays(1, &vao1);
glBindVertexArray(vao1);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, NULL);
glEnableVertexAttribArray(0);
// RED -----------------------------------
GLuint vbo2, vao2;
glGenBuffers(1, &vbo2);
glBindBuffer(GL_ARRAY_BUFFER, vbo2);
float arr2[] = { 400, 400, 400, 800, 800, 800, 800, 400 };
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 8, arr2, GL_STATIC_DRAW);
glGenVertexArrays(1, &vao2);
glBindVertexArray(vao2);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, NULL);
glEnableVertexAttribArray(0);
while (!glfwWindowShouldClose(window))
{
glClearColor(1, 1, 1, 0.1);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(pointShader);
GLint loc;
loc = glGetUniformLocation(pointShader, "pointColor");
// it draws this one but with the color blue!
glBindBuffer(GL_ARRAY_BUFFER, vbo2);
float ptColor2[3] = { 1, 0, 0 };
glUniform3fv(loc, 1, ptColor2);
glDrawArrays(GL_POINTS, 0, 4);
// it doesn't draw this one???
glBindBuffer(GL_ARRAY_BUFFER, vbo1);
float ptColor1[3] = { 0, 0, 1 };
glUniform3fv(loc, 1, ptColor1);
glDrawArrays(GL_POINTS, 0, 4);
glfwSwapBuffers(window);
glfwWaitEvents();
}
EDIT 2工作代碼
非常感謝您對雷託Koradi和Datenwolf兩者。結合答案,有助於得出正確的答案。很遺憾,這些東西在書本上沒有正確解釋。希望這篇文章能夠幫助其他初學者(對不起,如果結果有點誤導,我在問問題的時候換了顏色,以及我什麼時候得到答案)。
// RED -----------------------------------
GLuint vbo1, vao1;
glGenVertexArrays(1, &vao1);
glBindVertexArray(vao1);
glGenBuffers(1, &vbo1);
glBindBuffer(GL_ARRAY_BUFFER, vbo1);
float arr1[] = { 10, 10, 10, 110, 110, 110, 110, 10 };
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 8, arr1, GL_STATIC_DRAW);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, NULL);
glEnableVertexAttribArray(0);
// BLUE -----------------------------------
GLuint vbo2, vao2;
glGenVertexArrays(1, &vao2);
glBindVertexArray(vao2);
glGenBuffers(1, &vbo2);
glBindBuffer(GL_ARRAY_BUFFER, vbo2);
float arr2[] = { 400, 400, 400, 800, 800, 800, 800, 400 };
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 8, arr2, GL_STATIC_DRAW);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, NULL);
glEnableVertexAttribArray(0);
while (!glfwWindowShouldClose(window))
{
float ratio;
int width, height;
glfwGetFramebufferSize(window, &width, &height);
glClearColor(1, 1, 1, 0.1);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(pointShader);
GLint loc;
loc = glGetUniformLocation(pointShader, "pointColor");
// red
glBindVertexArray(vao1);
float ptColor1[3] = { 1, 0, 0 };
glUniform3fv(loc, 1, ptColor1);
glDrawArrays(GL_POINTS, 0, 4);
// blue
glBindVertexArray(vao2);
float ptColor2[3] = { 0, 0, 1 };
glUniform3fv(loc, 1, ptColor2);
glDrawArrays(GL_POINTS, 0, 4);
glfwSwapBuffers(window);
glfwWaitEvents();
}
編輯3
注意,雖然從對VAO/VBO順序聲明的第一個代碼片段的順序也將工作。所以低於上述版本和一個都是有效的:
// RED -----------------------------------
GLuint vbo1, vao1;
glGenBuffers(1, &vbo1);
glBindBuffer(GL_ARRAY_BUFFER, vbo1);
float arr1[] = { 10, 10, 10, 110, 110, 110, 110, 10 };
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 8, arr1, GL_STATIC_DRAW);
glGenVertexArrays(1, &vao1);
glBindVertexArray(vao1);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, NULL);
glEnableVertexAttribArray(0);
// BLUE -----------------------------------
GLuint vbo2, vao2;
glGenBuffers(1, &vbo2);
glBindBuffer(GL_ARRAY_BUFFER, vbo2);
float arr2[] = { 400, 400, 400, 800, 800, 800, 800, 400 };
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 8, arr2, GL_STATIC_DRAW);
glGenVertexArrays(1, &vao2);
glBindVertexArray(vao2);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, NULL);
glEnableVertexAttribArray(0);
這是真正的代碼唯一缺少的是glBindVertexArray
。
謝謝輝煌,我將編輯我的代碼,以工作代碼爲例。非常感謝你。 – user18490 2014-09-21 17:15:15
我不認爲有任何需要更改代碼的設置部分。這看起來非常好,你有它的方式。您可以使用數據填充緩衝區,而無需綁定VAO。 VAO只需在'glVertexAttribPointer()'和'glEnableVertexAttribArray()'過程中進行綁定,這樣做就是正確的。 – 2014-09-21 17:30:02
是的,這是真的。與您的更改的原始代碼實際上工作。不過,我已經做出了改變,並且懶得恢復原狀。爲了完整起見,我現在將添加它。 – user18490 2014-09-21 18:00:44