OpenGL学习笔记(七)
来源:互联网 发布:顶级域名证书合法吗 编辑:程序博客网 时间:2024/06/05 01:17
龙云尧个人博客,转载请注明出处。
CSDN地址:http://blog.csdn.net/michael753951/article/details/71511785
个人blog地址:http://yaoyl.cn/nehexue-xi-bi-ji-qi-2017-05-09-20-59/
我们在前六个部分已经尝试了nehe教程中1-8可得所有内容,接下来第七部分将实现一个简单的实验,这个实验将涵盖前面所有的内容,以作为一个前期总结。
前期准备
在实验之前,我们需要知道一个OpenGL中的基本概念。OpenGL中glEnable方法的使用。关于这个功能函数的使用以及参数设定,你可以点击【gl.glenable()介绍】以及【glEnable(GL_DEPTH_TEST) 有什么用?】进行查看。以下关于glenable的内容转载自上述第二篇博客。
在InitGL() 或者类似的初始化OpenGL的地方,会有glEnable(GL_DEPTH_TEST);
启用了之后,OpenGL在绘制的时候就会检查,当前像素前面是否有别的像素,如果别的像素挡道了它,那它就不会绘制,也就是说,OpenGL就只绘制最前面的一层。
当我们需要绘制透明图片时,就需要关闭它
glDisable(GL_DEPTH_TEST);
并且打开混合
glEnable(GL_BLEND);
而且还需要设置使用的透明度
glColor4f(1.0f,1.0f,1.0f,0.5f);
这样就是一半的显示了,设置为1就是不透明
glBlendFunc(GL_SRC_ALPHA,GL_ONE);
基于源像素Alpha通道值的半透明混合函数
在实验一以及后续的几个实验中,我们Enable的都是传入GL_DEPTH_TEST作为参数启用深度测试。并立刻在glEnable方法后面调用glDepthFunc(GL_LEQUAL);方法进行前景像素的显示设置。
这个概念在之前的实验中有所涉及,但是我们当时没有关注,这里我们将将其单独拿出来进行分析。本部分以下部分均为转载。转载来源为【glDepthFunc】
函数原型:
void glDepthFunc(GLenum func);
函数功能:
指定“目标像素与当前像素在z方向上值大小比较”的函数,符合该函数关系的目标像素才进行绘制,否则对目标像素不予绘制。
参数说明:
func指定深度比较函数,GL_NEVER,GL_LESS,GL_EQUAL,GL_LEQUAL,GL_GREATER,GL_NOTE_QUAL,GL_GEQUAL,GL_ALWAYS,缺省值GL_LESS,
GL_NEVER,不通过(输入的深度值不取代参考值)
GL_LESS,如果输入的深度值小于参考值,则通过
GL_EQUAL,如果输入的深度值等于参考值,则通过
GL_LEQUAL,如果输入的深度值小于或等于参考值,则通过
GL_GREATER,如果输入的深度值大于参考值,则通过
GL_NOTE_QUAL,如果输入的深度值不等于参考值,则通过
GL_GEQUAL,如果输入的深度值大于或等于参考值,则通过
GL_ALWAYS,总是通过(输入的深度值取代参考值)
描述:
通过目标像素与当前像素在z方向上值大小的比较是否满足参数指定的条件,来决定在深度(z方向)上是否绘制该目标像素。该函数只有启用“深度测试”时才有效,参考glEnable(GL_DEPTH_TEST)和glDisable(GL_DEPTH_TEST)
代码分析
前期准备能够帮助我们更好的理解作者在代码中的方法调用,,也能帮助我们更加深入的了解OpenGL的运行机制。我们接下来探讨本次实验中的实现方式。
根据Lesson1课程给我们大基建好的框架结构以及我们整理出来的那张结构图,我们可以快速理解本次实验代码。
首先定义了一个stars结构体,用来存放每一个星星的RGB值,与中心点的距离以及选装角度。
typedef struct // Create A Structure For Star{ int r, g, b; // Stars Color GLfloat dist, // Stars Distance From Center angle; // Stars Current Angle}stars;stars star[num]; // Need To Keep Track Of 'num' Stars
接着是LoadBMP和LoadGLTextures,这个和以前的实验代码无异,只需要改一下读入的文件名即可。ReSizeGLScene函数同样不需要修改。
接下来的InitGL开始,将会和第一节课开始出现不一样。
首先我们在前期准备中已经知道了glEnable的意义,并且我们也已经知道,深度测试和透明两种功能不能同时开启。而我们在上一次实验中在设置透明的时候,也曾经写过如下代码:
glEnable(GL_BLEND); // Turn Blending On glDisable(GL_DEPTH_TEST); // Turn Depth Testing Off
又因为本次实验需要直接使用透明,所以我们在InitGL中将不再glDisable(GL_BLEND),而是直接glEnable(GL_BLEND)。
接着就是很重要的一个方法了——DrawGLScene,这个地方,作者将星星的旋转以及着色代码在这里进行实现。
int DrawGLScene(GLvoid) // Here's Where We Do All The Drawing{ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear The Screen And The Depth Buffer glBindTexture(GL_TEXTURE_2D, texture[0]); // Select Our Texture for (loop=0; loop<num; loop++) // Loop Through All The Stars { glLoadIdentity(); // Reset The View Before We Draw Each Star glTranslatef(0.0f,0.0f,zoom); // Zoom Into The Screen (Using The Value In 'zoom') glRotatef(tilt,1.0f,0.0f,0.0f); // Tilt The View (Using The Value In 'tilt') glRotatef(star[loop].angle,0.0f,1.0f,0.0f); // Rotate To The Current Stars Angle glTranslatef(star[loop].dist,0.0f,0.0f); // Move Forward On The X Plane glRotatef(-star[loop].angle,0.0f,1.0f,0.0f); // Cancel The Current Stars Angle glRotatef(-tilt,1.0f,0.0f,0.0f); // Cancel The Screen Tilt if (twinkle) { glColor4ub(star[(num-loop)-1].r,star[(num-loop)-1].g,star[(num-loop)-1].b,255); glBegin(GL_QUADS); glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f,-1.0f, 0.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f,-1.0f, 0.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 0.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 0.0f); glEnd(); } glRotatef(spin,0.0f,0.0f,1.0f); glColor4ub(star[loop].r,star[loop].g,star[loop].b,255); glBegin(GL_QUADS); glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f,-1.0f, 0.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f,-1.0f, 0.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 0.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 0.0f); glEnd(); spin+=0.01f; star[loop].angle+=float(loop)/num; star[loop].dist-=0.01f; if (star[loop].dist<0.0f) { star[loop].dist+=5.0f; star[loop].r=rand()%256; star[loop].g=rand()%256; star[loop].b=rand()%256; } } return TRUE; // Everything Went OK}
如果我们在之前的课程中已经很深入的了解了的话,这一次的DrawScene就比较容易理解啦,我也就不在这里重复赘述了。
对winMain稍作修改。
int WINAPI WinMain( HINSTANCE hInstance, // Instance HINSTANCE hPrevInstance, // Previous Instance LPSTR lpCmdLine, // Command Line Parameters int nCmdShow) // Window Show State{ MSG msg; // Windows Message Structure BOOL done=FALSE; // Bool Variable To Exit Loop // Ask The User Which Screen Mode They Prefer if (MessageBox(NULL,"Would You Like To Run In Fullscreen Mode?", "Start FullScreen?",MB_YESNO|MB_ICONQUESTION)==IDNO) { fullscreen=FALSE; // Windowed Mode } // Create Our OpenGL Window if (!CreateGLWindow("NeHe's Animated Blended Textures Tutorial",640,480,16,fullscreen)) { return 0; // Quit If Window Was Not Created } while(!done) // Loop That Runs While done=FALSE { if (PeekMessage(&msg,NULL,0,0,PM_REMOVE)) // Is There A Message Waiting? { if (msg.message==WM_QUIT) // Have We Received A Quit Message? { done=TRUE; // If So done=TRUE } else // If Not, Deal With Window Messages { TranslateMessage(&msg); // Translate The Message DispatchMessage(&msg); // Dispatch The Message } } else // If There Are No Messages { // Draw The Scene. Watch For ESC Key And Quit Messages From DrawGLScene() if ((active && !DrawGLScene()) || keys[VK_ESCAPE]) // Active? Was There A Quit Received? { done=TRUE; // ESC or DrawGLScene Signalled A Quit } else // Not Time To Quit, Update Screen { SwapBuffers(hDC); // Swap Buffers (Double Buffering) if (keys['T'] && !tp) { tp=TRUE; twinkle=!twinkle; } if (!keys['T']) { tp=FALSE; } if (keys[VK_UP]) { tilt-=0.5f; } if (keys[VK_DOWN]) { tilt+=0.5f; } if (keys[VK_PRIOR]) { zoom-=0.2f; } if (keys[VK_NEXT]) { zoom+=0.2f; } if (keys[VK_F1]) // Is F1 Being Pressed? { keys[VK_F1]=FALSE; // If So Make Key FALSE KillGLWindow(); // Kill Our Current Window fullscreen=!fullscreen; // Toggle Fullscreen / Windowed Mode // Recreate Our OpenGL Window if (!CreateGLWindow("NeHe's Animated Blended Textures Tutorial",640,480,16,fullscreen)) { return 0; // Quit If Window Was Not Created } } } } } // Shutdown KillGLWindow(); // Kill The Window return (msg.wParam); // Exit The Program}
同样,很好理解的代码我就不重复解释了。最终运行的结果如图所示。
- OpenGL学习笔记(七)
- OpenGL学习笔记(七)
- openGL之圆环---openGL学习笔记(七)
- OPENGL学习笔记之七
- OpenGL入门笔记(七)
- OpenGL入门学习(七)
- OpenGL入门学习(七)
- OpenGL入门学习(七)
- OpenGL入门学习(七)
- OPENGL视频学习(七)
- OpenGL学习总结(七)
- OpenGL学习笔记(七):创建第一个Qt5.9.3 OpenGL工程模版(与平台无关)
- OpenGL学习(七) 矩阵学习
- OpenGL入门学习(七) 【转】
- 学习OpenGL(七)纹理贴图
- OpenGL入门学习[七]
- 学习笔记(七)
- 初识openGL---openGL学习笔记(一)
- windows10下alexnet模型训练步骤
- IE条件注释学习记录
- 170509 汇编-断点
- 蓝桥杯-K好数(java)
- G480BIOS刷新升级
- OpenGL学习笔记(七)
- bootstrap的两种模态框
- python-函数装饰器的使用-25
- D-4 Values whose Sum is 0
- adD
- 零售心理战-我喜欢的其中几句话
- zookeeper的若干应用场景
- 迁移学习技巧以及如何更好的finetune 模型
- apache的common中常用工具类