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

直线可以被画成虚线,而多边形则可以进行镂空。

首先,使用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;
}




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值