OpenGL学习记录5

来源:互联网 发布:广东移动网络加速器 编辑:程序博客网 时间:2024/06/01 08:45

Exercise 5:alpha混合

要求:

1.      绘制若干个透明和非透明茶壶,并体现出它们之间正确的混合效果;

考察目的:

1.      OpenGL中alpha混合的使用;

2.      混合绘制透明和不透明物体的正确方法;

3.      运算符的重载和基本STL的使用;


by/scu xx


#include <iostream>#include <gl\glew.h>#include <glut.h>#pragma comment(lib,"glew32.lib")using namespace std;bool isRotatef;  // 控制要旋转整个视图bool isLightOpen;//定义光源是否打开的bool值GLfloat LightPosition[] = {4.0f, 4.0f, 6.0f, 1.0f}; //点光源的位置static int mousePosX = 0, mousePosY = 0, tempX, tempY; bool isMosDownMove=false;//鼠标按下移动时的判断变量void createLight(){glEnable(GL_LIGHTING);glEnable(GL_LIGHT0);GLfloat LightAmbient[]= { 0.0f, 0.5f, 0.5f, 1.0f }; //环境光参数GLfloat LightDiffuse[]= { 1.0f, 1.0f, 1.0f, 1.0f }; //漫射光参数(由参数可知识最亮的漫射光)GLfloat LightSpecular[]= { 0.5f, 0.5f, 0.0f, 1.0f }; //镜面光参数//指定光源属性,3个参数决定了它所指定的哪个光源的属性、具体的属性以及该属性的预想值glLightfv(GL_LIGHT0, GL_AMBIENT,  LightAmbient);glLightfv(GL_LIGHT0, GL_DIFFUSE,  LightDiffuse);glLightfv(GL_LIGHT0, GL_SPECULAR, LightSpecular);}void init(void){glClearColor(0.7f, 0.7f, 0.7f, 0.0f);glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);    isLightOpen = true;  //光源开启glEnable(GL_DEPTH_TEST);glEnable(GL_BLEND);if (GLEW_OK != glewInit()) {cout << "Fail to initialize GLEW!\n";exit(1);}createLight();isRotatef = true; //默认移动鼠标旋转整个视图}void display(void){GLfloat mat_emission1[] = { 0.8, 0.8, 0.8, 1.0 };GLfloat mat_diffuse1[] = { 0.0, 0.0, 0.0, 1.0 };GLfloat mat_emission2[] = { 0.0, 0.8, 0.8, 0.6 };GLfloat mat_diffuse2[] = { 0.0, 0.3, 0.3, 0.6 };GLfloat mat_emission3[] = { 0.4, 0.4, 0.0, 0.4 };GLfloat mat_diffuse3[] = { 0.6, 0.6, 0.0, 0.4 };GLfloat mat_emission4[] = { 0.75, 0.75, 0.0, 0.5 };GLfloat mat_diffuse4[] = { 0.4, 0.0, 0.4, 0.5 };GLfloat mat_emission5[] = { 0.9, 0.9, 0.0, 0.6 };GLfloat mat_diffuse5[] = { 0.0, 0.0, 0.0, 0.6 };GLfloat mat_emission6[] = { 0.0, 0.6, 0.6, 1.0 };GLfloat mat_diffuse6[] = { 0.0, 0.0, 0.0, 1.0 };glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //进行视图变换前调用下面两个函数,接下来的变换函数将影响模型变换矩阵glMatrixMode(GL_MODELVIEW);glLoadIdentity();//3组参数:指定了观察点的位置,定义照相机瞄准的参考点,提示哪个方向是朝上的(3个为一组)//设置照相机的位置  bgluLookAt(0.0f, 0.0f, 20.0f, 0.0f, 0.0f, 0.0f, 0, 1, 0);//通过平移与旋转按照预想的方式移动观察点//glTranslatef(0.0f, 0.0f, 0.0f);/*************************************点光源的处理***********************************************///复制一份当前矩阵,并把这份复制添加到堆栈的顶部(记住自己的位置)glPushMatrix();        glTranslatef(LightPosition[0], LightPosition[1], LightPosition[2]);glDisable(GL_LIGHTING);        //使用glColor3f需要禁用光照if (isLightOpen){glColor3f(1.0f, 0.0f, 1.0f); //打开时颜色变亮}else{glColor3f(0.0f, 0.0f, 0.0f); //关闭时颜色变暗}//用于渲染一个球体 函数原型void glutSolidSphere(GLdouble radius , GLint slices , GLint stacks);//radius球体的半径//slices以Z轴上线段为直径分布的圆周线的条数(将Z轴看成地球的地轴,类似于经线)//stacks围绕在Z轴周围的线的条数(类似于地球上纬线)//一般而言, 后两个参数赋予较大的值, 渲染花费的时间要长, 效果更逼真glutSolidSphere(0.1, 10.0, 10.0);glEnable(GL_LIGHTING);    glLightfv(GL_LIGHT0, GL_POSITION, LightPosition);glPopMatrix(); //丢弃堆栈顶部的那个矩阵(回到原来的位置)if (isRotatef)  //判断是否需要旋转视图{glRotatef((GLfloat) mousePosX, -1.0, 0.0, 0.0);glRotatef((GLfloat) mousePosY, 0.0, -1.0, 0.0);}/****************************************茶壶1************************************************/glPushMatrix();   glTranslatef(-4.0f, 0.0f, 0.0f);glMaterialfv(GL_FRONT, GL_EMISSION, mat_emission1);    glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse1);glEnable(GL_BLEND);glDepthMask(GL_FALSE);//控制深度缓冲区是否可写glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);//选择源混合因子与目标混合因子glutSolidTeapot(0.8);//显示一个茶壶,参数为茶壶的大小glDepthMask(GL_TRUE);glDisable(GL_BLEND);glPopMatrix();/****************************************茶壶2************************************************/    glPushMatrix();glTranslatef(0.0f, 3.0f, -2.0f);glMaterialfv(GL_FRONT, GL_EMISSION, mat_emission2);    glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse2);glEnable(GL_BLEND);glDepthMask(GL_FALSE);glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);glutSolidTeapot(0.8);glDepthMask(GL_TRUE);glDisable(GL_BLEND);glPopMatrix();/****************************************茶壶3************************************************/glPushMatrix(); glTranslatef(4.0f, 0.0f, 0.0f);glMaterialfv(GL_FRONT, GL_EMISSION, mat_emission3);    glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse3);glEnable(GL_BLEND);glDepthMask(GL_FALSE);glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);glutSolidTeapot(0.8);glDepthMask(GL_TRUE);glDisable(GL_BLEND);glPopMatrix();/****************************************茶壶4************************************************/glPushMatrix(); glTranslatef(0.0f, -3.0f, 2.0f);glMaterialfv(GL_FRONT, GL_EMISSION, mat_emission4);    glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse4);glEnable(GL_BLEND);glDepthMask(GL_FALSE);glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);glutSolidTeapot(0.8);glDepthMask(GL_TRUE);glDisable(GL_BLEND);glPopMatrix();  /****************************************茶壶5************************************************/glPushMatrix(); glTranslatef(-8.0f, -3.0f, 2.0f);glMaterialfv(GL_FRONT, GL_EMISSION, mat_emission5);    glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse5);glEnable(GL_BLEND);glDepthMask(GL_FALSE);glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);glutSolidTeapot(0.8);glDepthMask(GL_TRUE);glDisable(GL_BLEND);glPopMatrix();/****************************************茶壶6************************************************/glPushMatrix(); glTranslatef(8.0f, -3.0f, 2.0f);glMaterialfv(GL_FRONT, GL_EMISSION, mat_emission6);    glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse6);glEnable(GL_BLEND);glDepthMask(GL_FALSE);glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);glutSolidTeapot(0.8);glDepthMask(GL_TRUE);glDisable(GL_BLEND);glPopMatrix();glutSwapBuffers();}void reshape(int w, int h){float aspect = (float) w/((h)?h:1);//平截头体的纵横比,也就是宽度除以高度,(h)?h:1意思是若h=0,则h=1glViewport(0,0, w, h);//进行投影变换前调用下面两个函数,接下来的变换函数将影响投影矩阵glMatrixMode(GL_PROJECTION);glLoadIdentity();gluPerspective(45.0f, aspect, 1.0f, 100.0f);glViewport(0,0,w,h);                      glMatrixMode(GL_MODELVIEW);}void keyboard(unsigned char key, int x, int y){                             switch (key){case 'o'://打开/关闭 光源isLightOpen = !isLightOpen;if (!isLightOpen){glDisable(GL_LIGHT0);}else{glEnable(GL_LIGHT0);}break;case 27://退出程序exit(0);break;}}void mouse(int button, int state, int x, int z){switch(button){case GLUT_LEFT_BUTTON:if (state == GLUT_DOWN) {  tempX = x;  tempY = z;  isMosDownMove = true;//鼠标移动时需要用到的判断变量} else {  isMosDownMove = false;}  break;}}void motion(int x, int z){if(isMosDownMove){mousePosY = (mousePosY + (x - tempX))%360;mousePosX = (mousePosX + (z - tempY))%360;tempX = x;tempY = z;glutPostRedisplay();}}void animate(void){//刷新屏幕glutPostRedisplay();}int main(int argc, char* argv[]){glutInit(&argc, argv);glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH | GLUT_RGB);glutInitWindowSize(800, 600);glutInitWindowPosition(100,100);glutCreateWindow("Teaports");init();glutDisplayFunc(display);glutReshapeFunc(reshape);glutKeyboardFunc(keyboard);glutMouseFunc(mouse);glutMotionFunc(motion);glutIdleFunc(animate);glutMainLoop();return 0;}

运行结果:



0 0
原创粉丝点击