OpenGL照相机

来源:互联网 发布:网络百家家乐公式赢钱 编辑:程序博客网 时间:2024/04/27 17:56

我们这节会创建一个游戏世界,里面有一些游戏模型,可以通过键盘的上下左右键,在游戏世界里面行走。

如下图:



决定一个照相机的因素有三个,照相机的位置,照相机的朝向,照相机的向上的正方向

我们可以通过Opgl的一个类GLFrame来获取一个默认的摄像机的数据结构

GLFrame             cameraFrame;M3DMatrix44f mCamera;cameraFrame.GetCameraMatrix(mCamera);

函数GetCameraMatrix就可以返回一个照相机的矩阵

下面是代码实现


首先是需要包含的头文件 和 全局变量部分

#include <GLTools.h>#include <GLShaderManager.h>#include <GLFrustum.h>#include <GLBatch.h>#include <GLFrame.h>#include <GLMatrixStack.h>#include <GLGeometryTransform.h>#include <StopWatch.h>#include <math.h>#include <stdio.h>#define FREEGLUT_STATIC#include <GL/glut.h>#define NUM_SPHERES 50 //要绘制的小球的数量GLFrame spheres[NUM_SPHERES];GLShaderManagershaderManager;GLMatrixStackmodelViewMatrix;GLMatrixStackprojectionMatrix;GLFrustumviewFrustum;GLGeometryTransformtransformPipeline;GLTriangleBatchtorusBatch; //保存泳圈模型的数据GLBatchfloorBatch; //保存地面的数据GLTriangleBatch     sphereBatch; //保存球体的数据GLFrame             cameraFrame; //照相机实例

主函数main()和上一节的一样,在这里就不贴出代码了


下面是初始化函数SetupRC,基本上每一行都有注释

void SetupRC()    {// 初始化着色器管理类shaderManager.InitializeStockShaders();//开启深度测试glEnable(GL_DEPTH_TEST);//开启线框模式glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);// 创建泳圈模型数据gltMakeTorus(torusBatch, 0.4f, 0.15f, 30, 30);        // T创建球体数据        gltMakeSphere(sphereBatch, 0.1f, 26, 13);        //创建地面floorBatch.Begin(GL_LINES, 324);        for(GLfloat x = -20.0; x <= 20.0f; x+= 0.5) {            floorBatch.Vertex3f(x, -0.55f, 20.0f);            floorBatch.Vertex3f(x, -0.55f, -20.0f);                    floorBatch.Vertex3f(20.0f, -0.55f, x);            floorBatch.Vertex3f(-20.0f, -0.55f, x);        }        floorBatch.End();            // 创建50个其他小球模型数据        for(int i = 0; i < NUM_SPHERES; i++) {            GLfloat x = ((GLfloat)((rand() % 400) - 200) * 0.1f);            GLfloat z = ((GLfloat)((rand() % 400) - 200) * 0.1f);            spheres[i].SetOrigin(x, 0.0f, z);        }    }


下面是窗口改变函数ChangeSize,同样代码都有注释

void ChangeSize(int nWidth, int nHeight)    {glViewport(0, 0, nWidth, nHeight);// 设置视口变换矩阵viewFrustum.SetPerspective(35.0f, float(nWidth)/float(nHeight), 1.0f, 100.0f);//设置模型变换矩阵projectionMatrix.LoadMatrix(viewFrustum.GetProjectionMatrix());    // 把视口变换矩阵 和 模型变换矩阵统一管理起来transformPipeline.SetMatrixStacks(modelViewMatrix, projectionMatrix);    }

下面是渲染函数RenderScene,用到了矩阵的入栈PushMatrix() 和 出栈 PopMatrix()


void RenderScene(void){// 地面颜色static GLfloat vFloorColor[] = { 0.0f, 1.0f, 0.0f, 1.0f};//泳圈模型颜色static GLfloat vTorusColor[] = { 1.0f, 0.0f, 0.0f, 1.0f };//小球颜色static GLfloat vSphereColor[] = { 0.0f, 0.0f, 1.0f, 1.0f };//用来控制泳圈模型旋转的角度static CStopWatchrotTimer;float yRot = rotTimer.GetElapsedSeconds() * 60.0f;glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);//把当前的视图变换矩阵入栈modelViewMatrix.PushMatrix();               //获取当前照相机矩阵M3DMatrix44f mCamera;cameraFrame.GetCameraMatrix(mCamera);//把照相机矩阵 作为 视图变换矩阵入栈modelViewMatrix.PushMatrix(mCamera);// 绘制地面shaderManager.UseStockShader(GLT_SHADER_FLAT, transformPipeline.GetModelViewProjectionMatrix(), vFloorColor);floorBatch.Draw();        //绘制50个小球模型for(int i = 0; i < NUM_SPHERES; i++) {modelViewMatrix.PushMatrix();modelViewMatrix.MultMatrix(spheres[i]);shaderManager.UseStockShader(GLT_SHADER_FLAT, transformPipeline.GetModelViewProjectionMatrix(),vSphereColor);sphereBatch.Draw();modelViewMatrix.PopMatrix();}// 把照相机沿z轴负方向移动2.5个单位modelViewMatrix.Translate(0.0f, 0.0f, -2.5f);    // 保存移动后的矩阵modelViewMatrix.PushMatrix();    //绘制泳圈模型modelViewMatrix.Rotate(yRot, 0.0f, 1.0f, 0.0f);shaderManager.UseStockShader(GLT_SHADER_FLAT, transformPipeline.GetModelViewProjectionMatrix(),vTorusColor);torusBatch.Draw();modelViewMatrix.PopMatrix(); // "Erase" the Rotation from before//绘制旋转的小球模型modelViewMatrix.Rotate(yRot * -2.0f, 0.0f, 1.0f, 0.0f);modelViewMatrix.Translate(0.8f, 0.0f, 0.0f);shaderManager.UseStockShader(GLT_SHADER_FLAT, transformPipeline.GetModelViewProjectionMatrix(), vSphereColor);sphereBatch.Draw();//视图矩阵出栈modelViewMatrix.PopMatrix();    //交换缓冲区glutSwapBuffers();                //刷新界面glutPostRedisplay();    }


下面是响应键盘方向键按下的函数SpecialKeys(int key, int x, int y)

其中cameraFrame.MoveForward(linear)表示照相机前进linear个单位

cameraFrame.RotateWorld(angular, 0.0f, 1.0f, 0.0f); 表示这相机沿y轴旋转angular角度

函数m3dDegToRad表示把弧度转化为角度

void SpecialKeys(int key, int x, int y)    {float linear = 0.1f;float angular = float(m3dDegToRad(5.0f));if (key == GLUT_KEY_UP)cameraFrame.MoveForward(linear);if (key == GLUT_KEY_DOWN)cameraFrame.MoveForward(-linear);if (key == GLUT_KEY_LEFT)cameraFrame.RotateWorld(angular, 0.0f, 1.0f, 0.0f);if (key == GLUT_KEY_RIGHT)cameraFrame.RotateWorld(-angular, 0.0f, 1.0f, 0.0f);    }





0 0
原创粉丝点击