您的位置:首页 > 运维架构

OpenGL入门13——多边形偏移

2015-03-24 20:29 253 查看
转自:http://blog.csdn.net/augusdi/article/details/23761757

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

#include <stdio.h>
#include <glew.h>
#include <freeglut.h>

#pragma comment( lib, "glew32d.lib")
#pragma comment( lib, "freeglut.lib")
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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: