簡體   English   中英

如何不在OpenGL中使用着色器覆蓋頂點顏色?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM