`
tiankefeng0520
  • 浏览: 146878 次
  • 性别: Icon_minigender_1
  • 来自: 长春
社区版块
存档分类
最新评论

OpenGL学习十三:多边形偏移

 
阅读更多

如果想着重显示实心物体的边缘,可以先用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;
}

 

  • 大小: 21 KB
  • 大小: 20.2 KB
分享到:
评论

相关推荐

    OpenGL之正背面剔除、深度测试、多边形偏移解决“甜甜圈”的绘制问题.zip

    本教程将深入探讨如何使用OpenGL解决在绘制“甜甜圈”时遇到的渲染问题,如黑色部分的出现,以及如何利用正背面剔除、深度测试和多边形偏移等技术优化图形的显示。 首先,我们来看“正背面剔除”(Backface Culling...

    2018212212162-潘璐婷-实验二_hasfbi_opengl_多边形绘制_多边形扫描_

    通过分析和运行这些代码,学习者可以深入理解OpenGL如何处理多边形的绘制和扫描填充,特别是凹多边形的处理方法。实验过程可能包括设置视口和投影矩阵、创建模型视图矩阵、设置颜色和深度测试等步骤,这些都是在...

    Qt下Opengl纹理映射实例:正方体(可拖动旋转)

    在本实例中,我们将深入探讨如何在Qt环境下...通过学习和实践这个项目,你可以掌握OpenGL纹理映射、Qt的OpenGL集成、以及事件驱动的用户交互设计。同时,了解如何组织和管理Qt项目的源代码和构建过程也是相当重要的。

    OpenGL编程指南.pdf

    第6章混合、抗锯齿、雾和多边形偏移 第7章显示列表 第8章绘制像素、位图、字体和图像 第9章纹理贴图 第10章帧缓冲区 第11章分格化和二次方程表面 第12章求值器和NURBS 第13章选择和反馈 第14章OpenGL高级技巧 第15章...

    OpenGl基础,碰撞检测,

    在实现多边形碰撞检测时,需要考虑多边形的法线、偏移量和旋转。通常会使用向量和矩阵运算来处理这些问题。例如,可以将多边形的顶点从世界坐标转换到局部坐标,以便更容易地进行碰撞测试。同时,考虑到旋转的影响,...

    OpenGL.rar_opengl 反馈_opengl 图像_opengl 放大_opengl 选择_图像 选取

    OpenGL提供了多种方法来实现这一目标,如深度测试(Depth Testing)、模板测试(Stencil Testing)和多边形偏移(Polygon Offset)。深度测试确保了近似物体覆盖远端物体,而模板测试允许我们在渲染时应用复杂的遮罩...

    OpenGL三维图形程序设计

    以上是OpenGL三维图形程序设计的一些核心知识点,实际应用中还会涉及更多高级特性,如几何着色器、计算着色器、多边形偏移、法线贴图、GPU粒子系统、着色器存储缓冲等。熟练掌握这些概念和技巧,你就能创造出令人...

    opengl教程与源码(中文)

    9. **高级特性**:可能涵盖混合、多边形偏移、雾化、多重采样抗锯齿等高级技术。 配合源码,你可以通过实践来加深对这些概念的理解。源码示例通常会包含完整的程序,演示了如何将理论知识应用于实际项目。这些代码...

    opengles3-book_opengl_

    10. **多边形偏移**:防止在深度缓冲区中出现Z-fighting现象,提高近表面细节的可见性。 11. **顶点数组对象(VAO)**:VAO用于保存顶点属性的状态,简化了大量顶点数据的管理。 12. ** instancing**:允许一次...

    OPENGL示例DEMO 三维图形

    此外,OpenGL还有许多高级特性,如多边形偏移防止穿透、雾化效果、多重采样抗锯齿、深度缓冲和模板缓冲等,可以提高图像的质量和视觉效果。 最后,OpenGL的示例DEMO通常包含完整的代码实现,用于演示特定功能或技术...

    OpenGL常用API函数解释

    OpenGL是计算机图形学中的一种编程接口,用于生成2D和3D图像。它提供了一系列的API函数,用于控制图形硬件,如显卡,以创建复杂的图形场景。以下是一些常见的OpenGL API函数及其作用的详细解释: 1. **glAccum**: ...

    Opengl 参考手册

    3. `glEnable() / glDisable()`: 启用或禁用特定的OpenGL特性,如深度测试、多边形偏移等。 4. `glUseProgram()`: 加载并激活一个编译好的着色器程序。 5. `glGenVertexArrays() / glBindVertexArray()`: 创建并...

    [交互式计算机图形学—— 基于OpenGL的自顶向下方法(第4版)]源文件

    8. **高级主题**:可能包括混合、多边形偏移、遮罩纹理、雾化、着色模型(如Phong模型)以及更复杂的特效。 9. **交互式应用**:学习如何响应用户输入,创建交互式的图形应用程序,如3D模型的旋转、平移和缩放。 ...

    opengl高级编程与可视化系统开发光盘

    3. **Chapter14**和**Chapter16**:可能涵盖了高级图形效果,如混合、抗锯齿、雾化、多边形偏移,以及OpenGL的高级着色技术,如顶点着色器和片段着色器。 4. **Chapter17**和**Chapter18**:可能涉及更复杂的话题,...

    opengl超级宝典源码(中)

    第十二章:模板缓冲与多边形偏移 模板缓冲常用于实现阴影效果或其他遮挡检测技术。多边形偏移则用于避免Z-fighting问题,即相近的多边形在屏幕上出现闪烁。glStencilFunc和glStencilOp控制模板测试,glPolygonOffset...

Global site tag (gtag.js) - Google Analytics