基于OPENGL使用C++实现相机类

应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();}

忘了还有头文件。
基于OPENGL使用C++实现相机类基于OPENGL使用C++实现相机类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

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月8日 上午7:37
下一篇 2023年2月8日 上午7:37

相关推荐