在过去的三个小时里,我试图弄清楚如何在 OpenGL 中使用着色器绘制两个不同颜色的不同三角形,但仍然无法弄清楚。这是我的代码:
void setShaders(void)
{
vshader = loadShader("test.vert", GL_VERTEX_SHADER_ARB);
fshader = loadShader("test.frag", GL_FRAGMENT_SHADER_ARB);
vshader2 = loadShader("test2.vert", GL_VERTEX_SHADER_ARB);
fshader2 = loadShader("test2.frag", GL_FRAGMENT_SHADER_ARB);
shaderProg = glCreateProgramObjectARB();
glAttachObjectARB(shaderProg, vshader);
glAttachObjectARB(shaderProg, fshader);
glLinkProgramARB(shaderProg);
shaderProg2 = glCreateProgramObjectARB();
glAttachObjectARB(shaderProg2, vshader2);
glAttachObjectARB(shaderProg2, fshader2);
glLinkProgramARB(shaderProg2);
}
void makeBuffers(void)
{
// smaller orange triangle
glGenBuffers (1, &vbo);
glBindBuffer (GL_ARRAY_BUFFER, vbo);
glBufferData (GL_ARRAY_BUFFER, sizeof(points), points, GL_STATIC_DRAW);
glGenVertexArrays (1, &vao);
glBindVertexArray (vao);
glEnableVertexAttribArray (0);
glBindBuffer (GL_ARRAY_BUFFER, vbo);
glVertexAttribPointer (0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
// larger purple triangle
glGenBuffers (1, &vbo2);
glBindBuffer (GL_ARRAY_BUFFER, vbo2);
glBufferData (GL_ARRAY_BUFFER, sizeof(points2), points2, GL_STATIC_DRAW);
glGenVertexArrays (1, &vao2);
glBindVertexArray (vao2);
glEnableVertexAttribArray (0);
glBindBuffer (GL_ARRAY_BUFFER, vbo2);
glVertexAttribPointer (0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
}
void window::displayCallback(void)
{
Matrix4 m4; // MT = UT * SpinMatrix
m4 = cube.getMatrix(); // make copy of the cube main matrix
cube.get_spin().mult(m4); // mult
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // clear color and depth buffers
glMatrixMode(GL_MODELVIEW);
glLoadMatrixd(cube.get_spin().getPointer()); // pass the pointer to new MT matrix
// draw smaller orange triangle
glUseProgramObjectARB(shaderProg);
glBindVertexArray(vao);
glDrawArrays (GL_TRIANGLES, 0, 3);
glDeleteObjectARB(shaderProg);
// draw the larger purple triangle
glUseProgramObjectARB(shaderProg2);
glBindVertexArray(vao2);
glDrawArrays (GL_TRIANGLES, 0, 3);
glDeleteObjectARB(shaderProg2);
glFlush();
glutSwapBuffers();
}
着色器:
test.vert 和 test2.vert 是一样的,都是:
#version 120
//varying vec3 vp;
void main()
{
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}
测试片段:
#version 120
void main()
{
gl_FragColor = vec4(1.0, 0.5, 0.0, 1.0);
}
test2.frag:
#version 120
void main()
{
gl_FragColor = vec4(0.5, 0.0, 0.5, 1.0);
}
但我得到的是两个紫色的三角形。我做错了什么导致我的小橙色三角形被重写为紫色?
最佳答案
在 displayCallback()
方法中使用着色器程序后,您将删除它们:
...
glDrawArrays (GL_TRIANGLES, 0, 3);
glDeleteObjectARB(shaderProg);
...
glDrawArrays (GL_TRIANGLES, 0, 3);
glDeleteObjectARB(shaderProg2);
如果 drawCallback()
被调用不止一次,您当然需要预料到这一点,因为一个窗口通常需要多次重绘,着色器将在第一次之后消失。事实上,第二个不会立即删除,因为它是当前事件的程序。这解释了为什么它继续用于两个三角形。
着色器程序仅在调用 glDelete*()
后才会被删除,并且它们不会被引用为事件程序。因此,在您对 shaderProg
的第一个 glDelete*()
调用中,一旦您使 shaderProg2
处于事件状态,该程序就会被删除,因为 shaderProg
然后不再事件,它释放了它的最后一个引用。
在关闭之前,您不应该删除着色器程序,或者直到您不打算再使用它们进行渲染,因为例如你正在创建新的程序。因此,就您而言,您可以在应用程序退出时删除它们。至少这通常被认为是好的风格,即使它在技术上不是必需的。 OpenGL 资源将在应用程序退出时自动清理,类似于常规内存分配。
顺便说一句,如果您至少使用 OpenGL 2.0,则所有使用着色器和程序的调用都是核心功能。无需使用 ARB 版本调用。
关于c++ - 如何不在 OpenGL 中使用着色器覆盖顶点颜色?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27644276/