如果想着重显示实心物体的边缘,可以先用GL_FILL模式绘制这个物体,然后再GL_LINE下再次用另外一种不同的颜色再次绘制(如右图),但是由于光栅化的方式不完全相同,因此直线和多边形经过计算后的Z值也可能不同 ,也可能向后,这就导致了线和实心忽浓忽暗的效果(右图2)
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glutSolidSphere(1.0, 20, 12);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glutSolidSphere(1.0, 20, 12);
为了解决这个问题可以是重合的Z值适当的偏移下
做法:
1.启用偏移模式
glEnable(GL_POLYGON_OFFSET_LINE|GL_POLYGON_OFFSET_POINT|GL_POLYGON_OFFSET_FILL);
分别对应GL_FILL,GL_POINT,GL_LINE
2.设置偏移量
glPolygonOffset(polyfactor, polyunits);
偏移量算法很复杂建议都设置为1.0
#include "header.h" GLuint list; GLint spinx = 0; GLint spiny = 0; GLfloat tdist = 0.0; GLfloat polyfactor = 1.0; GLfloat polyunits = 1.0; void display (void) { GLfloat gray[] = { 0.8, 0.8, 0.8, 1.0 }; GLfloat black[] = { 0.0, 0.0, 0.0, 1.0 }; glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushMatrix (); glTranslatef (0.0, 0.0, tdist); glRotatef ((GLfloat) spinx, 1.0, 0.0, 0.0); glRotatef ((GLfloat) spiny, 0.0, 1.0, 0.0); glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, gray); glMaterialfv(GL_FRONT, GL_SPECULAR, black); glMaterialf(GL_FRONT, GL_SHININESS, 0.0); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_POLYGON_OFFSET_FILL); glPolygonOffset(polyfactor, polyunits); glCallList (list); glDisable(GL_POLYGON_OFFSET_FILL); glDisable(GL_LIGHTING); glDisable(GL_LIGHT0); glColor3f (1.0, 1.0, 0.0); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); glCallList (list); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glPopMatrix (); glFlush (); } void gfxinit (void) { GLfloat light_ambient[] = { 0.0, 0.0, 0.0, 1.0 }; GLfloat light_diffuse[] = { 1.0, 1.0, 1.0, 1.0 }; GLfloat light_specular[] = { 1.0, 1.0, 1.0, 1.0 }; GLfloat light_position[] = { 1.0, 1.0, 1.0, 0.0 }; GLfloat global_ambient[] = { 0.2, 0.2, 0.2, 1.0 }; glClearColor (0.0, 0.0, 0.0, 1.0); list = glGenLists(1); glNewList (list, GL_COMPILE); glutSolidSphere(1.0, 20, 12); glEndList (); glEnable(GL_DEPTH_TEST); glLightfv (GL_LIGHT0, GL_AMBIENT, light_ambient); glLightfv (GL_LIGHT0, GL_DIFFUSE, light_diffuse); glLightfv (GL_LIGHT0, GL_SPECULAR, light_specular); glLightfv (GL_LIGHT0, GL_POSITION, light_position); glLightModelfv (GL_LIGHT_MODEL_AMBIENT, global_ambient); } void reshape(int width, int height) { glViewport (0, 0, width, height); glMatrixMode (GL_PROJECTION); glLoadIdentity (); gluPerspective(45.0, (GLdouble)width/(GLdouble)height, 1.0, 10.0); glMatrixMode (GL_MODELVIEW); glLoadIdentity (); gluLookAt (0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); } void mouse(int button, int state, int x, int y) { switch (button) { case GLUT_LEFT_BUTTON: switch (state) { case GLUT_DOWN: spinx = (spinx + 5) % 360; glutPostRedisplay(); break; default: break; } break; case GLUT_MIDDLE_BUTTON: switch (state) { case GLUT_DOWN: spiny = (spiny + 5) % 360; glutPostRedisplay(); break; default: break; } break; case GLUT_RIGHT_BUTTON: switch (state) { case GLUT_UP: exit(0); break; default: break; } break; default: break; } } void keyboard (unsigned char key, int x, int y) { switch (key) { case 't': if (tdist < 4.0) { tdist = (tdist + 0.5); glutPostRedisplay(); } break; case 'T': if (tdist > -5.0) { tdist = (tdist - 0.5); glutPostRedisplay(); } break; case 'F': polyfactor = polyfactor + 0.1; printf ("polyfactor is %f\n", polyfactor); glutPostRedisplay(); break; case 'f': polyfactor = polyfactor - 0.1; printf ("polyfactor is %f\n", polyfactor); glutPostRedisplay(); break; case 'U': polyunits = polyunits + 1.0; printf ("polyunits is %f\n", polyunits); glutPostRedisplay(); break; case 'u': polyunits = polyunits - 1.0; printf ("polyunits is %f\n", polyunits); glutPostRedisplay(); break; default: break; } } int main(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH); glutCreateWindow(argv[0]); glutReshapeFunc(reshape); glutDisplayFunc(display); glutMouseFunc(mouse); glutKeyboardFunc(keyboard); gfxinit(); glutMainLoop(); return 0; }
相关推荐
本教程将深入探讨如何使用OpenGL解决在绘制“甜甜圈”时遇到的渲染问题,如黑色部分的出现,以及如何利用正背面剔除、深度测试和多边形偏移等技术优化图形的显示。 首先,我们来看“正背面剔除”(Backface Culling...
通过分析和运行这些代码,学习者可以深入理解OpenGL如何处理多边形的绘制和扫描填充,特别是凹多边形的处理方法。实验过程可能包括设置视口和投影矩阵、创建模型视图矩阵、设置颜色和深度测试等步骤,这些都是在...
在本实例中,我们将深入探讨如何在Qt环境下...通过学习和实践这个项目,你可以掌握OpenGL纹理映射、Qt的OpenGL集成、以及事件驱动的用户交互设计。同时,了解如何组织和管理Qt项目的源代码和构建过程也是相当重要的。
第6章混合、抗锯齿、雾和多边形偏移 第7章显示列表 第8章绘制像素、位图、字体和图像 第9章纹理贴图 第10章帧缓冲区 第11章分格化和二次方程表面 第12章求值器和NURBS 第13章选择和反馈 第14章OpenGL高级技巧 第15章...
在实现多边形碰撞检测时,需要考虑多边形的法线、偏移量和旋转。通常会使用向量和矩阵运算来处理这些问题。例如,可以将多边形的顶点从世界坐标转换到局部坐标,以便更容易地进行碰撞测试。同时,考虑到旋转的影响,...
OpenGL提供了多种方法来实现这一目标,如深度测试(Depth Testing)、模板测试(Stencil Testing)和多边形偏移(Polygon Offset)。深度测试确保了近似物体覆盖远端物体,而模板测试允许我们在渲染时应用复杂的遮罩...
以上是OpenGL三维图形程序设计的一些核心知识点,实际应用中还会涉及更多高级特性,如几何着色器、计算着色器、多边形偏移、法线贴图、GPU粒子系统、着色器存储缓冲等。熟练掌握这些概念和技巧,你就能创造出令人...
9. **高级特性**:可能涵盖混合、多边形偏移、雾化、多重采样抗锯齿等高级技术。 配合源码,你可以通过实践来加深对这些概念的理解。源码示例通常会包含完整的程序,演示了如何将理论知识应用于实际项目。这些代码...
10. **多边形偏移**:防止在深度缓冲区中出现Z-fighting现象,提高近表面细节的可见性。 11. **顶点数组对象(VAO)**:VAO用于保存顶点属性的状态,简化了大量顶点数据的管理。 12. ** instancing**:允许一次...
此外,OpenGL还有许多高级特性,如多边形偏移防止穿透、雾化效果、多重采样抗锯齿、深度缓冲和模板缓冲等,可以提高图像的质量和视觉效果。 最后,OpenGL的示例DEMO通常包含完整的代码实现,用于演示特定功能或技术...
OpenGL是计算机图形学中的一种编程接口,用于生成2D和3D图像。它提供了一系列的API函数,用于控制图形硬件,如显卡,以创建复杂的图形场景。以下是一些常见的OpenGL API函数及其作用的详细解释: 1. **glAccum**: ...
3. `glEnable() / glDisable()`: 启用或禁用特定的OpenGL特性,如深度测试、多边形偏移等。 4. `glUseProgram()`: 加载并激活一个编译好的着色器程序。 5. `glGenVertexArrays() / glBindVertexArray()`: 创建并...
8. **高级主题**:可能包括混合、多边形偏移、遮罩纹理、雾化、着色模型(如Phong模型)以及更复杂的特效。 9. **交互式应用**:学习如何响应用户输入,创建交互式的图形应用程序,如3D模型的旋转、平移和缩放。 ...
3. **Chapter14**和**Chapter16**:可能涵盖了高级图形效果,如混合、抗锯齿、雾化、多边形偏移,以及OpenGL的高级着色技术,如顶点着色器和片段着色器。 4. **Chapter17**和**Chapter18**:可能涉及更复杂的话题,...
第十二章:模板缓冲与多边形偏移 模板缓冲常用于实现阴影效果或其他遮挡检测技术。多边形偏移则用于避免Z-fighting问题,即相近的多边形在屏幕上出现闪烁。glStencilFunc和glStencilOp控制模板测试,glPolygonOffset...