应gis for net朋友要求,发布一下以前写的相机类源码,这些代码没有经过优化,很粗糙。而且时间很长了,我根据记忆写了一点简单说明,详细的我也忘记了,见谅。
// Camera.cpp: implementation of the CCamera class.////////////////////////////////////////////////////////////////////////#include "stdafx.h"#include "GLCamera.h"#include "math.h"//////////////////////////////////////////////////////////////////////// Construction/Destruction////////////////////////////////////////////////////////////////////////构造函数,初始化视界距离CGLCamera::CGLCamera(){ _ViewFar=10000000.0f; _CVM=1.0f;//视角放大系数,小于1时就缩小视角,相当于放大画面,大于1时相当于广角镜头 this->Init();}CGLCamera::~CGLCamera(){}//初始化GLvoid CGLCamera::Init(GLvoid){ ViewWidth=640;//视口宽度 ViewHeight=480;//视口高度 ViewLeft=0;//相对投影面的左边距离 ViewTop=0;//相对投影面的上边距离 _LensFocus=50.0f;//镜头焦距,这个是我自己设计的一个参数,3D中的视角不方便理解,用照相机镜头就比较有概念了。 this->Focus2Angle();//焦距转换为角度。 _EyePosition.z=10.0;//相机位置的Z坐标 _EyePosition.w=1.0;//设置为坐标 _ViewPoint.w=1.0;//设置为坐标,这个是视点的 //相机方向矢量(单位矢量) _Uy.y=1.0; _Ux.x=1.0; _Uz.z=1.0; _ScrewAngle=0.0;//视角扭角,正为向右倾斜,负数为向左倾斜,模拟人头(相机)左右摇摆Z轴角度 TeleMultiple=10.0f;//最大放大倍数}//开拍,实际就是使用参数设置相机位置方向和视点。游戏循环每次绘制前调用一次,就可以使画面得到正确的视图。GLvoid CGLCamera::Camera(GLvoid){ glMatrixMode(GL_PROJECTION);// 选择投影矩阵 glViewport(ViewLeft, ViewTop, ViewWidth, ViewHeight);// 设置视口 glLoadIdentity();// 重置投影矩阵 // 设置视景体 gluPerspective( _ViewAngle*_CVM,//视角参数与系数相乘得到实际视角 (GLdouble)(ViewWidth-ViewLeft)/ (GLdouble)(ViewHeight-ViewTop), 0.5f, _ViewFar ); gluLookAt( _EyePosition.x,_EyePosition.y,_EyePosition.z, _ViewPoint.x,_ViewPoint.y,_ViewPoint.z, _Uy.x,_Uy.y,_Uy.z);}//变焦,根据不同模式递增/递减视角或按比例放大/缩小视角GLboolean CGLCamera::Zoom(int Mode,GLdouble Value){ GLboolean tmp; switch(Mode) { case ZOOM_ANGLE: _ViewAngle+=Value; break; case ZOOM_SCALE: default: _ViewAngle*=Value; break; } tmp= FixViewAngle(); Angle2Focus();//同步焦距 return tmp;}//限定最大最小视角GLboolean CGLCamera::FixViewAngle(GLvoid){ if (_ViewAngle<1.0f){_ViewAngle=1.0f;return false;} if (_ViewAngle>180){_ViewAngle=180.0f;return false;} return true;}//角度转焦距void CGLCamera::Angle2Focus(){ _LensFocus=FILM_DIAGONAL/2/tan(_ViewAngle*RAD_UNIT/2);}//焦距转角度void CGLCamera::Focus2Angle(){ _ViewAngle=atan(FILM_DIAGONAL/_LensFocus/2.0f)*2/RAD_UNIT;}//设置视角GLboolean CGLCamera::SetViewAngle(GLdouble Value){ GLboolean tmp; _ViewAngle=Value; tmp= FixViewAngle(); Angle2Focus(); return tmp;}GLdouble CGLCamera::GetViewAngle(){ return _ViewAngle;}//设置镜头焦距GLboolean CGLCamera::SetLens(GLdouble Value){ _LensFocus=Value; Focus2Angle(); return FixViewAngle();}GLdouble CGLCamera::GetLens(){ return _LensFocus;}//设置相机位置(坐标对象)GLvoid CGLCamera::SetPosition(CVector p){ CVector t; _EyePosition=p; this->FixUV();}//设置相机位置(坐标分量)GLvoid CGLCamera::SetPosition(GLdouble x,GLdouble y,GLdouble z ){ CVector v; v.x=x; v.y=y; v.z=z; v.w=1.0; SetPosition(v);}//设置视点(坐标对象)GLvoid CGLCamera::SetViewPoint(CVector p){ p.w=1.0; _ViewPoint=p; FixUV();}//设置视点(坐标分量)GLvoid CGLCamera::SetViewPoint(GLdouble x,GLdouble y,GLdouble z){ CVector t; t.x=x; t.y=y; t.z=z; SetViewPoint(t);}//相机与视点一起平移(平移矢量分量)GLvoid CGLCamera::Transfer(GLdouble Vx,GLdouble Vy,GLdouble Vz){ CVector t; this->FixUV(); t=_Ux*Vx+_Uy*Vy+_Uz*Vz; _M.SetTransfer(t.x,t.y,t.z); _EyePosition=_M.Transform(_EyePosition); _ViewPoint=_M.Transform(_ViewPoint);}//相机与视点一起平移(平移矢量对象)GLvoid CGLCamera::Transfer(CVector V){ Transfer(V.x,V.y,V.z);}//设置扭角GLvoid CGLCamera::SetScrewAngle(GLdouble Value){ _ScrewAngle=Value; _Uy.Clear(); _Uy.y=1.0; FixUV(); _M.SetRotateAngle(Value,_Uz); _Uy=_M.Transform(_Uy); _Ux=_M.Transform(_Ux); }GLdouble CGLCamera::GetScrewAngle(){ return _ScrewAngle;}//望远镜效果,当主程序接收到望远镜按键后循环调用此函数,产生逐步变焦效果,释放按键后立刻恢复到50MM标准镜效果。Switch参数就是按键按下标志//如果望远镜按键按住不放,递减放大系数,步进值0.1,直到系数达到TeleMultiple的倒数位置并锁定在0.1,就是视角缩小到当前视角参数_ViewAngle的1/10,画面放大当前设定值的10倍。GLvoid CGLCamera::Telescope(GLboolean Switch){ if (Switch) { if (_LensFocus!=50.0f) { _LensFocus=50.0f; this->Focus2Angle(); } if (_CVM>(1/TeleMultiple))_CVM-=0.1f; } else _CVM=1.0f;}//环视效果(水平旋转角和垂直旋转角)GLvoid CGLCamera::LookAround(GLdouble HAngle, GLdouble VAngle){ CVector v; if (HAngle!=0.0) { v=_ViewPoint-_EyePosition; _M.SetRotateAngle(HAngle,_Uy); _ViewPoint=_M.Transform(v)+_EyePosition; this->FixUV(); } if (VAngle!=0.0) { v=_ViewPoint-_EyePosition; _M.SetRotateAngle(VAngle,_Ux); _ViewPoint=_M.Transform(v)+_EyePosition; this->FixUV(); } }//这个函数是用来绘制三维十字线的,只是为了调试观察用。GLvoid CGLCamera::DrawUV(){CVector t; glBegin(GL_LINES);/* glColor3f(1.0f,1.0f,0.0f); glVertex3f(_ViewPoint.x,_ViewPoint.y,_ViewPoint.z); t=_Ux+_ViewPoint; glVertex3f(t.x,t.y,t.z); glColor3f(0.0f,1.0f,0.0f); t=_Uy+_ViewPoint; glVertex3f(_ViewPoint.x,_ViewPoint.y,_ViewPoint.z); glVertex3f(t.x,t.y,t.z);*/ glColor3f(1.0f,1.0f,0.0f); glVertex3f(0,0,0); t=_Ux; glVertex3f(t.x,t.y,t.z); glColor3f(0.0f,1.0f,0.0f); t=_Uy; glVertex3f(0,0,0); glVertex3f(t.x,t.y,t.z); glColor3f(0.0f,1.0f,1.0f); t=_Uz; glVertex3f(0,0,0); glVertex3f(t.x,t.y,t.z); glEnd();}GLvoid CGLCamera::FixUV(GLvoid){ CVector t; t=_EyePosition-_ViewPoint; _Uz=t.UnitOperation(); _Ux=_Uy.GetCrossMultiply(_Uz); _Ux=_Ux.UnitOperation(); _Uy=_Uz.GetCrossMultiply(_Ux); _Uy=_Uy.UnitOperation();}
忘了还有头文件。
View Code
// CGLCamera.h: interface for the CGLCamera class.////////////////////////////////////////////////////////////////////////#if !defined(AFX_GLCAMERA_H__D5CC9BD0_034C_40DD_AD7F_3604B8B70E29__INCLUDED_)#define AFX_GLCAMERA_H__D5CC9BD0_034C_40DD_AD7F_3604B8B70E29__INCLUDED_#if _MSC_VER > 1000#pragma once#endif // _MSC_VER > 1000#define ZOOM_ANGLE 0#define ZOOM_SCALE 1#define FILM_DIAGONAL 43.267class CGLCamera { public: GLvoid DrawUV();//绘制局部坐标的单位矢量 GLvoid LookAround(GLdouble HAngle,GLdouble VAngle);//环视 GLvoid Telescope(GLboolean Switch);//望远镜效果开/关 GLvoid Init(GLvoid);//初始化 //设置视点 GLvoid SetViewPoint(GLdouble x,GLdouble y,GLdouble z ); GLvoid SetViewPoint(CVector p); //设置位置 GLvoid SetPosition(CVector p); GLvoid SetPosition(GLdouble x,GLdouble y,GLdouble z ); //平移 GLvoid Transfer(GLdouble Vx,GLdouble Vy,GLdouble Vz); GLvoid Transfer(CVector V); //视角 GLdouble GetViewAngle(void); GLboolean SetViewAngle(GLdouble Value); //扭角,以垂直于画面的轴旋转角 GLdouble GetScrewAngle(void); GLvoid SetScrewAngle(GLdouble Value); //焦距 GLdouble GetLens(void); GLboolean SetLens(GLdouble Value); GLsizei ViewLeft; GLsizei ViewTop; GLsizei ViewHeight; GLsizei ViewWidth; //开拍 GLvoid Camera(GLvoid); GLdouble TeleMultiple;//望远倍数 //变焦 GLboolean Zoom(int Mode,GLdouble Value); CGLCamera(); virtual ~CGLCamera(); CVector _EyePosition,_ViewPoint; CVector _Ux,_Uy,_Uz;private: GLvoid FixUV(GLvoid); void Focus2Angle(void); void Angle2Focus(void); GLboolean FixViewAngle(GLvoid); GLdouble _ViewAngle,_CVM; GLdouble _LensFocus; GLdouble _ScrewAngle; GLdouble _ViewFar; GLdouble _LookLength,_LookVAngle,_LookHAngle; CMatrix _M;};#endif // !defined(AFX_GLCAMERA_H__D5CC9BD0_034C_40DD_AD7F_3604B8B70E29__INCLUDED_)
原文链接: https://www.cnblogs.com/CodeBlove/archive/2011/08/10/2134241.html
欢迎关注
微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍
原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/30272
非原创文章文中已经注明原地址,如有侵权,联系删除
关注公众号【高性能架构探索】,第一时间获取最新文章
转载文章受原作者版权保护。转载请注明原作者出处!