首页 > 代码库 > openGL超级宝典第三章例子——贴花
openGL超级宝典第三章例子——贴花
1、又和上次一样犯了个错误,深度缓冲标识位GL_DEPTH_BUFFER_BIT写成GL_COLOR_BUFFER_BIT。导致图形绘制没有在窗口中出现
2、注释是我的。
3、好消息:code compare插件和工具的使用。之前朋友推荐我使用,一直没有场景。现在知道:svn同文件的不同版本在同一路径下的对比使用smartSVN;不同文件或者不同路径任何版本对比使用code compare工具,比如根据别人的教程写代码或把开源的代码转化为自己的代码这工具很适合。今天就是用这个工具查找到书写错误,这种错误需要用倒校等文字编辑的方式,但是我们是编码设计人员,不应该浪费时间在无谓的事件上。
4、主要的功能时实现贴花绘制和首个3D项目。
#ifdef WIN32 #pragma comment(lib, "freeglut_static.lib") #endif #include <GLTools.h> #include <GLFrustum.h> #include <GLMatrixStack.h> #include <GLFrame.h> #include <GLBatch.h> //Geometry 几何学 #include <GLGeometryTransform.h> #include <GLFrame.h> #include <math.h> #define FREEGLUT_STATIC #include <GL/glut.h> GLShaderManager shaderManager; GLMatrixStack modelViewMatrix; GLMatrixStack projectionMatrix; GLFrame cameraFrame; GLFrame objectFrame; GLFrustum viewFrustum; GLBatch pointBatch; GLBatch lineBatch; GLBatch lineStripBatch; GLBatch lineLoopBatch; GLBatch triangleBatch; GLBatch triangleStripBatch; GLBatch triangleFanBatch; //变换管线 GLGeometryTransform transformPipeline; GLfloat vBlack[] = { 0.0f, 0.0f, 0.0f, 1.0f }; GLfloat vGreen[] = { 0.0f, 1.0f, 0.0f, 1.0f }; int nStep = 0; void SetupRC(void) { //Black background glClearColor(0.7f, 0.7f, 0.7f, 1.0f); //初始化shader shaderManager.InitializeStockShaders(); glEnable(GL_DEPTH_TEST); transformPipeline.SetMatrixStacks(modelViewMatrix, projectionMatrix); cameraFrame.MoveForward(-15.0f); //没理解,其实就是美国佛罗里达地形边框。。 ////////////////////////////////////////////////////////////////////// // Some points, more or less in the shape of Florida GLfloat vCoast[24][3] = { { 2.80, 1.20, 0.0 }, { 2.0, 1.20, 0.0 }, { 2.0, 1.08, 0.0 }, { 2.0, 1.08, 0.0 }, { 0.0, 0.80, 0.0 }, { -.32, 0.40, 0.0 }, { -.48, 0.2, 0.0 }, { -.40, 0.0, 0.0 }, { -.60, -.40, 0.0 }, { -.80, -.80, 0.0 }, { -.80, -1.4, 0.0 }, { -.40, -1.60, 0.0 }, { 0.0, -1.20, 0.0 }, { .2, -.80, 0.0 }, { .48, -.40, 0.0 }, { .52, -.20, 0.0 }, { .48, .20, 0.0 }, { .80, .40, 0.0 }, { 1.20, .80, 0.0 }, { 1.60, .60, 0.0 }, { 2.0, .60, 0.0 }, { 2.2, .80, 0.0 }, { 2.40, 1.0, 0.0 }, { 2.80, 1.0, 0.0 } }; //Load point batch pointBatch.Begin(GL_POINTS, 24); pointBatch.CopyVertexData3f(vCoast); pointBatch.End(); // Load as a bunch聚束 of line segments lineBatch.Begin(GL_LINES, 24); lineBatch.CopyVertexData3f(vCoast); lineBatch.End(); // Load as a single line segment lineStripBatch.Begin(GL_LINE_STRIP, 24); lineStripBatch.CopyVertexData3f(vCoast); lineStripBatch.End(); // Single line, connect first and last points lineLoopBatch.Begin(GL_LINE_LOOP, 24); lineLoopBatch.CopyVertexData3f(vCoast); lineLoopBatch.End(); // For Triangles, we'll make a Pyramid:金字塔,y轴为塔顶。,有个问题,怎么把底部封住? GLfloat vPyramid[12][3] = { -2.0f, 0.0f, -2.0f, 2.0f, 0.0f, -2.0f, 0.0f, 4.0f, 0.0f, 2.0f, 0.0f, -2.0f, 2.0f, 0.0f, 2.0f, 0.0f, 4.0f, 0.0f, 2.0f, 0.0f, 2.0f, -2.0f, 0.0f, 2.0f, 0.0f, 4.0f, 0.0f, -2.0f, 0.0f, 2.0f, -2.0f, 0.0f, -2.0f, 0.0f, 4.0f, 0.0f }; triangleBatch.Begin(GL_TRIANGLES, 12); triangleBatch.CopyVertexData3f(vPyramid); triangleBatch.End(); // For a Triangle fan, just a 6 sided hex. Raise the center up a bit GLfloat vPoints[100][3]; // Scratch array, more than we need // For triangle strips, a little ring or cylinder segment int iCounter = 0; GLfloat radius = 3.0f; for (GLfloat angle = 0.0f; angle <= (2.0f*M3D_PI); angle += 0.3f) { //以z轴为中心,长度为radius,用圆弧滚动0.3f生成间隔点 GLfloat x = radius * sin(angle); GLfloat y = radius * cos(angle); //从计算远点再到近点,组成strip环 // Specify the point and move the Z value up a little vPoints[iCounter][0] = x; vPoints[iCounter][1] = y; vPoints[iCounter][2] = -0.5; iCounter++; vPoints[iCounter][0] = x; vPoints[iCounter][1] = y; vPoints[iCounter][2] = 0.5; iCounter++; } // Close up the loop vPoints[iCounter][0] = vPoints[0][0]; vPoints[iCounter][1] = vPoints[0][1]; vPoints[iCounter][2] = -0.5; iCounter++; vPoints[iCounter][0] = vPoints[1][0]; vPoints[iCounter][1] = vPoints[1][1]; vPoints[iCounter][2] = 0.5; iCounter++; // Load the triangle strip triangleStripBatch.Begin(GL_TRIANGLE_STRIP, iCounter); triangleStripBatch.CopyVertexData3f(vPoints); triangleStripBatch.End(); int nVerts = 0; GLfloat r = 3.0f; for (GLfloat angle = 0; angle < M3D_2PI; angle += M3D_2PI / 6.0f) { nVerts++; vPoints[nVerts][0] = float(cos(angle)) * r; vPoints[nVerts][1] = float(sin(angle)) * r; vPoints[nVerts][2] = -0.5f; } // Close the fan nVerts++; vPoints[nVerts][0] = r; vPoints[nVerts][1] = 0; vPoints[nVerts][2] = 0.0f; // Load it up triangleFanBatch.Begin(GL_TRIANGLE_FAN, 8); triangleFanBatch.CopyVertexData3f(vPoints); triangleFanBatch.End(); } //没有使用现场保留,所以后面多了一堆的代码 void DrawWireFramedBatch(GLBatch * pBatch) { //画绿图 shaderManager.UseStockShader(GLT_SHADER_FLAT, transformPipeline.GetModelViewProjectionMatrix(), vGreen); pBatch->Draw(); //绘制黑线贴花 //Draw black outline glPolygonOffset(-1.0f, -1.0f);//shift depth values glEnable(GL_POLYGON_OFFSET_LINE);//开启线偏移——用于绘制贴花 // Draw lines antialiased 抗锯齿属性 glEnable(GL_LINE_SMOOTH); //混合 glEnable(GL_BLEND); //这样子混合会产生什么样的效果 ??不开启混合则会导致黑线没有完全与相邻的已有像素点(即原模型)贴近,出现一些较明显的间隔 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); //Draw black wireframe version of geometry 画黑线 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); glLineWidth(2.5f); shaderManager.UseStockShader(GLT_SHADER_FLAT, transformPipeline.GetModelViewProjectionMatrix(), vBlack); pBatch->Draw(); // Put everything back the way we found it glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glDisable(GL_POLYGON_OFFSET_LINE); glLineWidth(1.0f); glDisable(GL_BLEND); glDisable(GL_LINE_SMOOTH); } void RenderScene(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); //保存当前场景的信息 modelViewMatrix.PushMatrix(); //设置将要使用的状态机 //设置摄像机,没看懂是怎么设置,当前状态*摄像机,做出什么变化? 待续 M3DMatrix44f mCamera; cameraFrame.GetCameraMatrix(mCamera); modelViewMatrix.MultMatrix(mCamera);//摄像机作用于model坐标系 M3DMatrix44f mObjectFrame; objectFrame.GetMatrix(mObjectFrame); modelViewMatrix.MultMatrix(mObjectFrame);//旋转的是对象坐标,要作用于模型坐标系 //Stock 库存 shaderManager.UseStockShader(GLT_SHADER_FLAT, transformPipeline.GetModelViewProjectionMatrix(), vBlack); switch (nStep) { case 0: glPointSize(4.0f); pointBatch.Draw(); glPointSize(1.0f); break; case 1: glLineWidth(2.0f); lineBatch.Draw(); glLineWidth(1.0f); break; case 2: glLineWidth(2.0f); lineStripBatch.Draw(); glLineWidth(1.0f); break; case 3: glLineWidth(2.0f); lineLoopBatch.Draw(); glLineWidth(1.0f); break; case 4: DrawWireFramedBatch(&triangleBatch); break; case 5: DrawWireFramedBatch(&triangleStripBatch); break; case 6: DrawWireFramedBatch(&triangleFanBatch); break; } modelViewMatrix.PopMatrix(); //Flush drawing commands glutSwapBuffers(); } void ChangeSize(int w, int h) { glViewport(0, 0, w, h); //当发现绘制的图形看不到,多半是视角或摄像机的远近问题。 viewFrustum.SetPerspective(35, (float)w / (float)h, 1.0f, 500.0f); projectionMatrix.LoadMatrix(viewFrustum.GetProjectionMatrix()); modelViewMatrix.LoadIdentity(); } void KeyPressFunc(unsigned char key, int x, int y) { //32是空格 if (key == 32) { ++nStep; if (nStep>6) { nStep = 0; } } switch (nStep) { case 0: glutSetWindowTitle("GL_POINTS"); break; case 1: glutSetWindowTitle("GL_LINES"); break; case 2: glutSetWindowTitle("GL_LINE_STRIPS"); break; case 3: glutSetWindowTitle("GL_LINE_LOOP"); break; case 4: glutSetWindowTitle("GL_TRIANGLES"); break; case 5: glutSetWindowTitle("GL_TRIANGLE_STRIPS"); break; case 6: glutSetWindowTitle("GL_TRIANGLE_FAN"); break; } glutPostRedisplay(); } void SpecialKeys(int key, int x, int y) { if (key == GLUT_KEY_UP) { objectFrame.RotateWorld(m3dDegToRad(-5.0f), 1.0f, 0.0f, 0.0f); } if (key == GLUT_KEY_DOWN) { objectFrame.RotateWorld(m3dDegToRad(5.0f), 1.0f, 0.0f, 0.0f); } if (key == GLUT_KEY_LEFT) { objectFrame.RotateWorld(m3dDegToRad(-5.0f), 0.0f, 1.0f, 0.0f); } if (key == GLUT_KEY_RIGHT) { objectFrame.RotateWorld(m3dDegToRad(5.0f), 0.0f, 1.0f, 0.0f); } glutPostRedisplay(); } int main(int argc, char * argv[]) { gltSetWorkingDirectory(argv[0]); glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH | GLUT_STENCIL); glutInitWindowSize(800, 600); glutCreateWindow("GL_POINTS"); glutReshapeFunc(ChangeSize);//窗口 glutKeyboardFunc(KeyPressFunc);//空白键 glutSpecialFunc(SpecialKeys);//上下左右旋转视角 glutDisplayFunc(RenderScene);//重绘 GLenum err = glewInit(); if (GLEW_OK != err) { fprintf(stderr, "GLEW Error: %s\n", glewGetErrorString(err)); return 1; } SetupRC(); glutMainLoop(); return 0; }
openGL超级宝典第三章例子——贴花
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。