如果想着重显示实心物体的边缘,可以先用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的“甜甜圈”的绘制和渲染,以及在旋转的过程中却出现了黑色部分的问题的分析和解决,引发“正背面剔除”的渲染技巧,以及“深度测试”、“多边形偏移”等诸多技术的探讨。
第6章混合、抗锯齿、雾和多边形偏移 第7章显示列表 第8章绘制像素、位图、字体和图像 第9章纹理贴图 第10章帧缓冲区 第11章分格化和二次方程表面 第12章求值器和NURBS 第13章选择和反馈 第14章OpenGL高级技巧 第15章...
在分析了三维非均匀FDTD网格图形性质及计算数据结构特点的基础上,提出了一种基于OpenGL深度缓冲机制的绘图方法,采用多边形深度偏移量修正法进行精细化的消隐修正,实现了网格图形的快速生成与高效消隐,大大提高了...
·第6章描述创建逼真场景所需要的一些基本技巧:alpha混合(创建透明物体)、抗锯齿(消除锯齿状边缘)、大气效果(模拟雾和烟雾)以及多边形偏移(在着重显示填充多边形的边框时消除不良视觉效果)。 ·第7章...
ClipperOffset.Execute中的错误修复,其中Polytree.IsHole属性返回带有负偏移量的不正确值 在ClipperOffset中加入舍入的很小的改进 修复了CPP OpenGL演示。 v6.2.0(2014年10月17日)477版 许多次要的错误修正,太...
多边形裁剪和偏移。 本机文件打开/保存对话框。 时钟,计时器,协程,事件,格式等。 一体化 该库很小,可以与CMake的一起使用: include (FetchContent) FetchContent_Declare(mahi-gui GIT_REPOSITORY ...
多边形裁剪和偏移。本机文件打开/保存对话框。时钟,计时器,协程,事件,格式等。一体化该库很小,可以与CMake的一起使用: include (FetchContent) FetchContent_Declare(mahi-gui GIT_REPOSITORY ...
6.0.6-7-向SpectrumAnalizyz添加了选项“ opacity”-默认情况下将ProceduralTerrain设置为较低的多边形(您仍然可以在场景设置中选择所需的多边形分辨率)-添加了选项“ FadeControls”(当鼠标不在上方时淡入淡出...