12.OpenGL--多边形偏移

来源:互联网 发布:百度软件管理好不好 编辑:程序博客网 时间:2024/06/10 20:27
  • 理论基础 
    多边形偏移:有时候我们需要着重显示多边形的边缘,一般做法是先绘制实心的再在同一位置绘制空心的,这样就可以突出边缘。但是,由于直线与多边形的光栅化并不完全相同,即使在同一位置绘制它们的深度值也不一定相同,这样绘制的直线可能忽浓忽淡。这时我们就可以激活多边形偏移来解决这个问题,其原理就是给实体或线框的深度加上一个偏移值。即把实体推向远处或把线框拉近,具体偏移值多少是通过设置glPolygonOffset(factor,units)算出的,其底层公式是这样:offset = m * factor + r * units.

  • 实例代码
#include "GLTools.h"#include "GLShaderManager.h"#ifdef __APPLE__#include <glut/glut.h>#else#define FREEGLUT_STATIC#include <GL/glut.h>#endifGLuint 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, 1.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_RIGHT_BUTTON:            switch (state) {                case GLUT_DOWN:                    spiny = (spiny + 5) % 360;                    glutPostRedisplay();                    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;}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173

下面是没有开启多边形偏移与开启了多边形偏移下的表现: 
这里写图片描述 
这里写图片描述

0 0
原创粉丝点击