如何在OpenGL中使用着色器覆盖顶点颜色?

时间:2014-12-25 04:44:04

标签: c++ opengl graphics shader

在过去的三个小时里,我试图弄清楚如何使用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);
}

但我得到的是两个呈紫色的三角形。我做错了什么导致我的小橙色三角形被重写为紫色?

1 个答案:

答案 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版本调用。