如何在Legacy OpenGL(Freeglut+Glew)场景中单独修改单个实体颜色?
如何在Legacy OpenGL中为单个多边形单独着色?
你遇到的问题根源在于Legacy OpenGL是一个状态机——一旦你设置了某个状态(比如当前颜色),它会一直保持下去,所有后续的绘制操作(包括你的文本)都会沿用这个状态,除非你主动修改它。
解决这个问题有两种简单且常用的方法:
方法1:手动保存并恢复颜色状态
在绘制四边形之前,先保存当前的颜色值,等四边形绘制完成后,再把颜色恢复回去。这样后续的文本就会使用原来的绿色了。
修改后的代码如下:
void drawScene(void) { // Cleaning procedures glClear(GL_COLOR_BUFFER_BIT); // Setting the color of the models as green GLfloat originalColor[4]; glGetFloatv(GL_CURRENT_COLOR, originalColor); // 保存当前的绿色状态 glColor3f(0.0, 1.0, 0.0); // Drawing a square that will rotate based on the mouse coord on the screen glPushMatrix(); glRotated(theta, 0.0, 0.0, 1.0); glBegin(GL_QUADS); // 设置四边形的自定义颜色 glColor3f(colors.r, colors.g, colors.b); glVertex3f(-2.0, 2.0, 0.0); glVertex3f(-2.0, -2.0, 0.0); glVertex3f(2.0, -2.0, 0.0); glVertex3f(2.0, 2.0, 0.0); glEnd(); glPopMatrix(); // 恢复之前保存的绿色 glColor3fv(originalColor); // Text formatting auto coords = std::format("Mouse coordinate is x ({}) , y ({})", xm, ym); auto angle = std::format("Rotation angle is {}", xm/10); glRasterPos3f(-6.0, -6.0, 0.0); writeBitmapString(GLUT_BITMAP_9_BY_15, coords.data()); glRasterPos3f(-6.0, -8.0, 0.0); writeBitmapString(GLUT_BITMAP_9_BY_15, angle.data()); // Swapping buffer to the back and front glutSwapBuffers(); }
方法2:使用属性栈自动保存/恢复状态
Legacy OpenGL提供了glPushAttrib()和glPopAttrib()函数,专门用来保存和恢复一组状态属性。对于颜色来说,我们可以使用GL_CURRENT_BIT标记来保存当前的颜色状态,这样就不用手动记录颜色值了,代码会更简洁优雅。
修改后的代码如下:
void drawScene(void) { // Cleaning procedures glClear(GL_COLOR_BUFFER_BIT); // Setting the color of the models as green glColor3f(0.0, 1.0, 0.0); // Drawing a square that will rotate based on the mouse coord on the screen glPushMatrix(); glRotated(theta, 0.0, 0.0, 1.0); // 保存当前的颜色状态到属性栈 glPushAttrib(GL_CURRENT_BIT); glBegin(GL_QUADS); // 设置四边形的自定义颜色 glColor3f(colors.r, colors.g, colors.b); glVertex3f(-2.0, 2.0, 0.0); glVertex3f(-2.0, -2.0, 0.0); glVertex3f(2.0, -2.0, 0.0); glVertex3f(2.0, 2.0, 0.0); glEnd(); // 从属性栈恢复之前的颜色状态(也就是绿色) glPopAttrib(); glPopMatrix(); // Text formatting auto coords = std::format("Mouse coordinate is x ({}) , y ({})", xm, ym); auto angle = std::format("Rotation angle is {}", xm/10); glRasterPos3f(-6.0, -6.0, 0.0); writeBitmapString(GLUT_BITMAP_9_BY_15, coords.data()); glRasterPos3f(-6.0, -8.0, 0.0); writeBitmapString(GLUT_BITMAP_9_BY_15, angle.data()); // Swapping buffer to the back and front glutSwapBuffers(); }
补充说明
如果你的需求是给多边形的不同顶点设置不同颜色,直接在glBegin()和glEnd()之间,每个glVertex3f()之前调用glColor3f()就可以了——OpenGL会自动进行平滑着色(如果启用了GL_SMOOTH,这是默认状态)。但在你的场景里,整个四边形需要统一颜色,上面两种方法就完全够用了。
内容的提问来源于stack exchange,提问作者Asynchronousx
相关产品推荐
相关产品推荐

