在过去的三个小时里,我试图弄清楚如何使用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;
}
test.frag:
#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);
}
但我得到的是两个呈紫色的三角形。我做错了什么导致我的小橙色三角形被重写为紫色?
答案 0 :(得分:3)
在displayCallback()
方法中使用后,您正在删除着色器程序:
...
glDrawArrays (GL_TRIANGLES, 0, 3);
glDeleteObjectARB(shaderProg);
...
glDrawArrays (GL_TRIANGLES, 0, 3);
glDeleteObjectARB(shaderProg2);
如果drawCallback()
被多次调用,您肯定需要预期,因为窗口通常需要多次重绘,着色器将在第一次之后消失。实际上,第二个不会被立即删除,因为它是当前活动的程序。这解释了为什么它继续用于两个三角形。
着色器程序仅在调用glDelete*()
后删除,和它们不会被引用为活动程序。因此,在您glDelete*()
shaderProg
的第一次shaderProg2
调用中,一旦您shaderProg
处于活动状态,该程序就会被删除,因为{{1}}将不再处于活动状态,这将释放其最后一个引用。< / p>
您不应该在关闭之前删除着色器程序,或者直到您不打算再使用它们进行渲染,例如,你正在创造新的prgrams。因此,在您的情况下,您可以在应用程序退出时删除它们。至少那些通常被认为是好的风格,即使它在技术上不是必需的。当应用程序退出时,OpenGL资源将自动清理,类似于常规内存分配。
BTW,如果您至少使用OpenGL 2.0,那么使用着色器和程序的所有调用都是核心功能。无需使用ARB版本调用。