[英]How not to overwrite vertex colors using shaders in OpenGL?
在過去的三個小時中,我試圖弄清楚如何使用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);
}
但是我得到的是兩個紫色的三角形。 我在做錯什么導致我的較小的橙色三角形被改寫成紫色?
在displayCallback()
方法中使用着色器程序后,將它們刪除:
...
glDrawArrays (GL_TRIANGLES, 0, 3);
glDeleteObjectARB(shaderProg);
...
glDrawArrays (GL_TRIANGLES, 0, 3);
glDeleteObjectARB(shaderProg2);
如果drawCallback()
調用drawCallback()
(您肯定會期望這樣做,因為通常必須多次重繪窗口),因此着色器將在第一次使用后消失。 實際上,第二個程序不會被立即刪除,因為它是當前活動的程序。 這就解釋了為什么它繼續用於兩個三角形。
僅在對它們着色器程序調用glDelete*()
之后,它們才會被刪除, 並且它們不會作為活動程序被引用。 所以,你的第一個glDelete*()
呼吁shaderProg
,一旦你作出這樣的程序被刪除shaderProg2
活躍,因為shaderProg
是那么不積極了,從而釋放其最后一個引用。
在關閉或不打算再使用着色器程序渲染之前,您不應該刪除它們,因為例如,您正在創建新的程序。 因此,根據您的情況,您可以在應用程序退出時將其刪除。 至少在技術上沒有必要的情況下,通常認為它是好的樣式。 退出常規應用程序時,將在應用程序退出時自動清除OpenGL資源。
順便說一句,如果您至少使用OpenGL 2.0,則所有使用着色器和程序的調用都是核心功能。 無需使用ARB版本調用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.