OpenGL 入门教程(四)

来源:互联网 发布:淘宝修改默认付款方式 编辑:程序博客网 时间:2024/05/16 17:37
// Objects.cpp// OpenGL SuperBible, Chapter 4// Demonstrates GLTools built-in objects// Program by Richard S. Wright Jr.#include <GLTools.h>// OpenGL toolkit#include <GLMatrixStack.h>#include <GLFrame.h>#include <GLFrustum.h>#include <GLBatch.h>#include <GLGeometryTransform.h>#include <math.h>#ifdef __APPLE__#include <glut/glut.h>#else#define FREEGLUT_STATIC#include <GL/glut.h>#endif/////////////////////////////////////////////////////////////////////////////////// An assortment of needed classesGLShaderManagershaderManager;GLMatrixStackmodelViewMatrix;GLMatrixStackprojectionMatrix;GLFramecameraFrame;GLFrame             objectFrame;GLFrustumviewFrustum;GLTriangleBatch     sphereBatch;GLTriangleBatch     torusBatch;GLTriangleBatch     cylinderBatch;GLTriangleBatch     coneBatch;GLTriangleBatch     diskBatch;GLGeometryTransformtransformPipeline;M3DMatrix44fshadowMatrix;GLfloat vGreen[] = { 0.0f, 1.0f, 0.0f, 1.0f };GLfloat vBlack[] = { 0.0f, 0.0f, 0.0f, 1.0f };// Keep track of effects stepint nStep = 0;///////////////////////////////////////////////////////////////////////////////// This function does any needed initialization on the rendering context. // This is the first opportunity to do any OpenGL related tasks.void SetupRC(){// Black backgroundglClearColor(0.7f, 0.7f, 0.7f, 1.0f);shaderManager.InitializeStockShaders();glEnable(GL_DEPTH_TEST);//管线对象绑定模型视图矩阵和投影矩阵transformPipeline.SetMatrixStacks(modelViewMatrix, projectionMatrix);//摄像机,视口  摄像机向后移动15cameraFrame.MoveForward(-15.0f);//光栅化// Sphere 球体gltMakeSphere(sphereBatch, 3.0, 10, 20);// Torus 花托gltMakeTorus(torusBatch, 3.0f, 0.75f, 15, 15);// Cylinder 圆柱gltMakeCylinder(cylinderBatch, 2.0f, 2.0f, 3.0f, 13, 2);// Cone 圆锥体gltMakeCylinder(coneBatch, 2.0f, 0.0f, 3.0f, 13, 2);// Disk 磁盘gltMakeDisk(diskBatch, 1.5f, 3.0f, 13, 3);}/////////////////////////////////////////////////////////////////////////void DrawWireFramedBatch(GLTriangleBatch* pBatch){//shaderManager.UseStockShader(GLT_SHADER_FLAT, transformPipeline.GetModelViewProjectionMatrix(), vGreen);pBatch->Draw();// Draw black outlineglPolygonOffset(-1.0f, -1.0f);glEnable(GL_LINE_SMOOTH);glEnable(GL_BLEND);glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);glEnable(GL_POLYGON_OFFSET_LINE);glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);glLineWidth(2.5f);shaderManager.UseStockShader(GLT_SHADER_FLAT, transformPipeline.GetModelViewProjectionMatrix(), vBlack);pBatch->Draw();// Restore polygon mode and depht testingglPolygonMode(GL_FRONT_AND_BACK, GL_FILL);glDisable(GL_POLYGON_OFFSET_LINE);glLineWidth(1.0f);glDisable(GL_BLEND);glDisable(GL_LINE_SMOOTH);}///////////////////////////////////////////////////////////////////////////////// Called to draw scenevoid RenderScene(void){// Clear the window with current clearing colorglClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);modelViewMatrix.PushMatrix();// modelViewMatrix -> cameraFrame -> mCamera (刚开始向后移动了15个单位)M3DMatrix44f mCamera;cameraFrame.GetCameraMatrix(mCamera);//照相机对象绑定mCamera矩阵对象modelViewMatrix.MultMatrix(mCamera);//transformPipeline->模型视图矩阵对象绑定mCamera矩阵对象<-照相机对象//modelViewMatrix -> objectFrame -> mObjectFrame (平移缩放旋转时根据消息动态改变的)M3DMatrix44f mObjectFrame;objectFrame.GetMatrix(mObjectFrame);//对象帧对象绑定mObjectFrame矩阵对象(这个矩阵对象是用于旋转变换用的),连接了该对象就可以选择模型视图了modelViewMatrix.MultMatrix(mObjectFrame);//transformPipeline->modelViewMatrix矩阵对象绑定mObjectFrame矩阵对象<-objectFrame//存储着色器用于绘制,平移,缩放,填充等shaderManager.UseStockShader(GLT_SHADER_FLAT, transformPipeline.GetModelViewProjectionMatrix(), vGreen);switch (nStep) {case 0:DrawWireFramedBatch(&sphereBatch);break;case 1:DrawWireFramedBatch(&torusBatch);break;case 2:DrawWireFramedBatch(&cylinderBatch);break;case 3:DrawWireFramedBatch(&coneBatch);break;case 4:DrawWireFramedBatch(&diskBatch);break;}modelViewMatrix.PopMatrix();// Flush drawing commandsglutSwapBuffers();}// Respond to arrow keys by moving the camera frame of referencevoid 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();}///////////////////////////////////////////////////////////////////////////////// A normal ASCII key has been pressed.// In this case, advance the scene when the space bar is pressedvoid KeyPressFunc(unsigned char key, int x, int y){if (key == 32){nStep++;if (nStep > 4)nStep = 0;}switch (nStep){case 0:glutSetWindowTitle("Sphere");break;case 1:glutSetWindowTitle("Torus");break;case 2:glutSetWindowTitle("Cylinder");break;case 3:glutSetWindowTitle("Cone");break;case 4:glutSetWindowTitle("Disk");break;}glutPostRedisplay();}///////////////////////////////////////////////////////////////////////////////// Window has changed size, or has just been created. In either case, we need// to use the window dimensions to set the viewport and the projection matrix.void ChangeSize(int w, int h){glViewport(0, 0, w, h);viewFrustum.SetPerspective(35.0f, float(w) / float(h), 1.0f, 500.0f);projectionMatrix.LoadMatrix(viewFrustum.GetProjectionMatrix());modelViewMatrix.LoadIdentity();}///////////////////////////////////////////////////////////////////////////////// Main entry point for GLUT based programsint main(int argc, char* argv[]){gltSetWorkingDirectory(argv[0]);glutInit(&argc, argv);glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH | GLUT_STENCIL);glutInitWindowSize(800, 600);glutCreateWindow("Sphere");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;}

原创粉丝点击