• 基于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();
    }

    忘了还有头文件。

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

  • 相关阅读:
    .Net中的装箱和拆箱
    使用GetThumbnailImage进行图片缩放操作
    潭州课堂25班:Ph201805201 第二课:数据类型和序列类型 (课堂笔记)
    公开课 之 心蓝 数据分析 (课堂笔记)
    潭州课堂25班:Ph201805201 第一课:环境搭建 (课堂笔记)
    Maven笔记
    java中Swing编程再度练习篇
    Swing编程练习。可能这篇会有错误哦
    Swing
    Swing编程把图片放入frame里。先不作为背景图片
  • 原文地址:https://www.cnblogs.com/CodeBlove/p/2134241.html
Copyright © 2020-2023  润新知