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

VS2012下基于Glut OpenGL GL_POLYGON_STIPPLE示例程序:

2013-06-16 14:33 232 查看
直线可以被画成虚线,而多边形则可以进行镂空。

首先,使用glEnable(GL_POLYGON_STIPPLE);来启动镂空模式(使用glDisable(GL_POLYGON_STIPPLE)可以关闭之)。

然后,使用glPolygonStipple来设置镂空的样式。

void glPolygonStipple(const GLubyte *mask);

其中的参数mask指向一个长度为128字节的空间,它表示了一个32*32的矩形应该如何镂空。其中:第一个字节表示了最左下方的从左到右(也可以是从右到左,这个可以修改)8个像素是否镂空(1表示不镂空,显示该像素;0表示镂空,显示其后面的颜色),最后一个字节表示了最右上方的8个像素是否镂空。



Demo的显示效果如下:可以发现即使是在旋转坐标系时图案还是平面填充的,和纹理不一样。




源代码如下所示:

// GlutPolygonStippleDemo.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <gl/glut.h>
#include <math.h>

//圆周率宏
#define GL_PI 3.1415f
GLubyte stippledata[128] = { //第一个矩形点画模式的mask值
0x00, 0x00, 0xff, 0xff,
0x00, 0x00, 0xff, 0xff,
0x00, 0x00, 0xff, 0xff,
0x00, 0x00, 0xff, 0xff,
0x00, 0x00, 0xff, 0xff,
0x00, 0x00, 0xff, 0xff,
0x00, 0x00, 0xff, 0xff,
0x00, 0x00, 0xff, 0xff,
0x00, 0x00, 0xff, 0xff,
0x00, 0x00, 0xff, 0xff,
0x00, 0x00, 0xff, 0xff,
0x00, 0x00, 0xff, 0xff,
0x00, 0x00, 0xff, 0xff,
0x00, 0x00, 0xff, 0xff,
0x00, 0x00, 0xff, 0xff,
0x00, 0x00, 0xff, 0xff,

0xff, 0xff, 0x00, 0x00,
0xff, 0xff, 0x00, 0x00,
0xff, 0xff, 0x00, 0x00,
0xff, 0xff, 0x00, 0x00,
0xff, 0xff, 0x00, 0x00,
0xff, 0xff, 0x00, 0x00,
0xff, 0xff, 0x00, 0x00,
0xff, 0xff, 0x00, 0x00,
0xff, 0xff, 0x00, 0x00,
0xff, 0xff, 0x00, 0x00,
0xff, 0xff, 0x00, 0x00,
0xff, 0xff, 0x00, 0x00,
0xff, 0xff, 0x00, 0x00,
0xff, 0xff, 0x00, 0x00,
0xff, 0xff, 0x00, 0x00,
0xff, 0xff, 0x00, 0x00,
};
GLubyte flydata[128] = { //第二个矩形点画模式的mask值
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x03, 0x80, 0x01, 0xC0,
0x06, 0xC0, 0x03, 0x60,
0x04, 0x60, 0x06, 0x20,
0x04, 0x30, 0x0C, 0x20,
0x04, 0x18, 0x18, 0x20,
0x04, 0x0C, 0x30, 0x20,
0x04, 0x06, 0x60, 0x20,
0x44, 0x03, 0xC0, 0x22,
0x44, 0x01, 0x80, 0x22,
0x44, 0x01, 0x80, 0x22,
0x44, 0x01, 0x80, 0x22,
0x44, 0x01, 0x80, 0x22,
0x44, 0x01, 0x80, 0x22,
0x44, 0x01, 0x80, 0x22,

0x66, 0x01, 0x80, 0x66,
0x33, 0x01, 0x80, 0xCC,
0x19, 0x81, 0x81, 0x98,
0x0C, 0xC1, 0x83, 0x30,
0x07, 0xe1, 0x87, 0xe0,
0x03, 0x3f, 0xfc, 0xc0,
0x03, 0x31, 0x8c, 0xc0,
0x03, 0x33, 0xcc, 0xc0,
0x06, 0x64, 0x26, 0x60,
0x0c, 0xcc, 0x33, 0x30,
0x18, 0xcc, 0x33, 0x18,
0x10, 0xc4, 0x23, 0x08,
0x10, 0x63, 0xC6, 0x08,
0x10, 0x30, 0x0c, 0x08,
0x10, 0x18, 0x18, 0x08,
0x10, 0x00, 0x00, 0x08,
};

//获取屏幕的宽度
GLint SCREEN_WIDTH=0;
GLint SCREEN_HEIGHT=0;
//设置程序的窗口大小
GLint windowWidth=400;
GLint windowHeight=400;
//绕x轴旋转角度
GLfloat xRotAngle=0.0f;
//绕y轴旋转角度
GLfloat yRotAngle=0.0f;

//是否打开不显示背面功能
GLint cullFace=0;
//是否打开深度测试功能
GLint depthTest=0;
//背面是采用线条描外框还是使用单色填充 
GLint outLine=0;
//菜单回调函数
void processMenu(int value){
switch(value){
case 1:
depthTest=!depthTest;
break;
case 2:
cullFace=!cullFace;
case 3:
outLine=!outLine;
break;
break;
default:
break;
}
//重新绘制
glutPostRedisplay();
}
//显示回调函数
void renderScreen(void){
GLfloat x,y,z,angle;
//把整个窗口清理为当前清理颜色:黑色
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
//将当前Matrix状态入栈
glPushMatrix();
//坐标系绕x轴旋转xRotAngle
glRotatef(xRotAngle,1.0f,0.0f,0.0f);
//坐标系绕y轴旋转yRotAngle
glRotatef(yRotAngle,0.0f,1.0f,0.0f);
if(depthTest)
glEnable(GL_DEPTH_TEST);//打开深度测试功能
else
glDisable(GL_DEPTH_TEST);//关闭深度测试功能
if(cullFace)
glEnable(GL_CULL_FACE);//打开不显示背面功能
else
glDisable(GL_CULL_FACE);//关闭不显示背面功能
if(outLine)
glPolygonMode(GL_BACK,GL_LINE);//多边形背部使用线条描框
else
glPolygonMode(GL_BACK,GL_FILL);//多边形背部使用单色填充
x=0.0f;
y=0.0f;
z=0.0f;
//进行平滑处理 
glEnable(GL_LINE_SMOOTH);
glHint(GL_LINE_SMOOTH,GL_NICEST);
//蓝色绘制坐标系
glColor3f(0.0f,0.0f,1.0f);
glBegin(GL_LINES);
glVertex3f(-200.0f,0.0f,0.0f);
glVertex3f(200.0f,0.0f,0.0f);
glVertex3f(0.0f,-200.0f,0.0f);
glVertex3f(0.0f,200.0f,0.0f);
glVertex3f(0.0f,0.0f,-200.0f);
glVertex3f(0.0f,0.0f,200.0f);
glEnd();

glPushMatrix();
glTranslatef(200.0f,0.0f,0.0f);
glRotatef(90.0f,0.0f,1.0f,0.0f);
glutWireCone(3,6,10,10);
glPopMatrix();

glPushMatrix();
glTranslatef(0.0f,200.0f,0.0f);
glRotatef(-90.0f,1.0f,0.0f,0.0f);
glutWireCone(3,6,10,10);
glPopMatrix();

glPushMatrix();
glTranslatef(0.0f,0.0f,200.0f);
glRotatef(90.0f,0.0f,0.0f,1.0f);
glutWireCone(3,6,10,10);
glPopMatrix();

//开始白色GL_POLYGON_STIPPLE绘制
glColor3f(1.0f,1.0f,1.0f);
glEnable(GL_POLYGON_STIPPLE);
//黑白交替图案绘制第一个矩形
glPolygonStipple(stippledata);
glRectf(0.0f,0.0f,64.0f,64.0f);
//苍蝇图案绘制第二个矩形
glPolygonStipple(flydata);
glRectf(64.0f,0.0f,128.0f,64.0f);
//结束GL_POLYGON_STIPPLE绘制
glDisable(GL_POLYGON_STIPPLE);

//恢复压入栈的Matrix
glPopMatrix();
//交换两个缓冲区的指针
glutSwapBuffers();
}
//设置Redering State
void setupRederingState(void){
//设置清理颜色为黑色
glClearColor(0.0f,0.0,0.0,1.0f);
//设置绘画颜色为绿色
glColor3f(0.0f,1.0f,0.0f);
//平面填充
glShadeModel(GLU_FLAT);
}
//窗口大小变化回调函数
void changSize(GLint w,GLint h){
//横宽比率
GLfloat ratio;
//设置坐标系为x(-100.0f,100.0f)、y(-100.0f,100.0f)、z(-100.0f,100.0f)
GLfloat coordinatesize=100.0f;
//窗口宽高为零直接返回
if((w==0)||(h==0))
return;
//设置视口和窗口大小一致
glViewport(0,0,w,h);
//对投影矩阵应用随后的矩阵操作
glMatrixMode(GL_PROJECTION);
//重置当前指定的矩阵为单位矩阵 
glLoadIdentity();
ratio=(GLfloat)w/(GLfloat)h;
//正交投影
/*
if(w<h)
glOrtho(-coordinatesize,coordinatesize,-coordinatesize/ratio,coordinatesize/ratio,-coordinatesize,coordinatesize);
else
glOrtho(-coordinatesize*ratio,coordinatesize*ratio,-coordinatesize,coordinatesize,-coordinatesize,coordinatesize);
*/
glOrtho(0.0f,w,0.0f,h,-coordinatesize,coordinatesize);
//对模型视图矩阵堆栈应用随后的矩阵操作
glMatrixMode(GL_MODELVIEW);
//重置当前指定的矩阵为单位矩阵 
glLoadIdentity();
}

//按键输入处理回调函数
void specialKey(int key,int x,int y){

if(key==GLUT_KEY_UP){
xRotAngle-=5.0f;
}
else if(key==GLUT_KEY_DOWN){
xRotAngle+=5.0f;
}
else if(key==GLUT_KEY_LEFT){
yRotAngle-=5.0f;
}
else if(key==GLUT_KEY_RIGHT){
yRotAngle+=5.0f;
}
//重新绘制
glutPostRedisplay();
}

int main(int argc, char* argv[])
{
//初始化glut
glutInit(&argc,argv);
//使用双缓冲区模式
glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGBA|GLUT_DEPTH);
//获取系统的宽像素
SCREEN_WIDTH=glutGet(GLUT_SCREEN_WIDTH);
//获取系统的高像素
SCREEN_HEIGHT=glutGet(GLUT_SCREEN_HEIGHT);
//创建窗口,窗口名字为OpenGL TriAngle Demo
glutCreateWindow("OpenGL PloygonStipple Demo");
//菜单回调函数
glutCreateMenu(processMenu);
//添加菜单
glutAddMenuEntry("Toggle depth test",1);
glutAddMenuEntry("Toggle cull face",2);
glutAddMenuEntry("Toggle back outline",3);
//将菜单榜定到鼠标右键上
glutAttachMenu(GLUT_RIGHT_BUTTON);
//设置窗口大小
glutReshapeWindow(windowWidth,windowHeight);
//窗口居中显示
glutPositionWindow((SCREEN_WIDTH-windowWidth)/2,(SCREEN_HEIGHT-windowHeight)/2);
//窗口大小变化时的处理函数
glutReshapeFunc(changSize);
//设置显示回调函数
glutDisplayFunc(renderScreen);
//设置按键输入处理回调函数
glutSpecialFunc(specialKey);
//设置全局渲染参数
setupRederingState();
glutMainLoop();
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: