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); } }
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
- OpenGL照相机
- OpenGL边用边学------2 经典照相机模型
- 照相机
- 照相机
- 照相机
- 照相机
- OPENGL中简单点的理解以及关于照相机的简单理解
- windows照相机
- 一次性照相机
- 打开照相机
- J2me 照相机
- 自定义 照相机
- Android照相机
- 自定义照相机
- Android 照相机
- UIImagePickerController(照相机)
- 维度照相机
- android照相机
- Apache多域名映射多个端口
- python if条件判断、for循环和while循环
- struct与class的不同
- 3 Longest Substring Without Repeating Characters
- HDU 4435 charge-station (2012年天津赛区现场赛E题)
- OpenGL照相机
- POJ 2828 Buy Tickets
- Hbase coprocessor获取数据
- HDOJ 4508 湫湫系列故事——减肥记I(完全背包)
- 后缀数组
- Word Search
- [leetcode]Contains Duplicate C语言
- 多线程基础
- 之前UI的小练习