最新消息: USBMI致力于为网友们分享Windows、安卓、IOS等主流手机系统相关的资讯以及评测、同时提供相关教程、应用、软件下载等服务。

OpenGL

IT圈 admin 23浏览 0评论

OpenGL

  • 理论基础
    多边形偏移:有时候我们需要着重显示多边形的边缘,一般做法是先绘制实心的再在同一位置绘制空心的,这样就可以突出边缘。但是,由于直线与多边形的光栅化并不完全相同,即使在同一位置绘制它们的深度值也不一定相同,这样绘制的直线可能忽浓忽淡。这时我们就可以激活多边形偏移来解决这个问题,其原理就是给实体或线框的深度加上一个偏移值。即把实体推向远处或把线框拉近,具体偏移值多少是通过设置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;
}

下面是没有开启多边形偏移与开启了多边形偏移下的表现:

OpenGL

  • 理论基础
    多边形偏移:有时候我们需要着重显示多边形的边缘,一般做法是先绘制实心的再在同一位置绘制空心的,这样就可以突出边缘。但是,由于直线与多边形的光栅化并不完全相同,即使在同一位置绘制它们的深度值也不一定相同,这样绘制的直线可能忽浓忽淡。这时我们就可以激活多边形偏移来解决这个问题,其原理就是给实体或线框的深度加上一个偏移值。即把实体推向远处或把线框拉近,具体偏移值多少是通过设置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;
}

下面是没有开启多边形偏移与开启了多边形偏移下的表现:

发布评论

评论列表 (0)

  1. 暂无评论