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

时间:2022-09-10 17:04:58

应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.267

class 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_)