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

标签 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;
}

测试片段:

#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/

相关文章:

java - 安卓显卡0x1​​04567911

Python 3.2.1 : Can't Index Shape, 稍后需要访问特定矩形

ios - 为什么文本不从 0,0 开始?

c++ - 多重转换规则 C++

c++ - 无法实现单例模式

C++ 创建一个函数来读取 .txt 文件并检查以确保文件存在,但我的循环不工作

python - PyOpenGL,使用 glFrustum 和 glTranslate 在屏幕上出现 3D 图形问题

c++ - OpenGL 无缘无故地裁剪一个对象

c++ - 如何在密度函数的特定值处有效地绘制二维正态分布的等值线?

macos - GLSL: "Invalid call of undeclared identifier ' 纹理 2D'"