3D中的相机 - 投影矩阵和视图矩阵
3d游戏中,一般通过相机的设置来计算投影矩阵和视图矩阵,比如untiy和cocos,一般情况下我们不用关注如何计算,
可以直接在可视化的编辑器中调整参数就可以了,但是了解下总是好的。
具体计算可以参考:
可以参考现在cocos2dx的代码中的Camera源码,里面有根据相机的设置(位置等)计算上面两个矩阵的代码。
也可以参考下面这个,github上面一个项目,这个项目有很好的参考价值:
https://github.com/wantnon2/3DToolKit-2-for-cocos2dx/blob/master/c3dToolKit/core/c3dCamera.h
```
//
// c3dCamera.h
// HelloCpp
//
// Created by Yang Chao (wantnon) on 14-1-7.
//
//
#ifndef __HelloCpp__c3dCamera__
#define __HelloCpp__c3dCamera__ #include <iostream>
using namespace std;
#include "cocos2d.h"
using namespace cocos2d;
#include "c3dVector.h"
#include "c3dMatrix.h"
#include "c3dGLMath.h"
#include "c3dCommonFunc.h"
#include "c3dMatrixStackInfoGetor.h"
#include "c3dRange.h"
class Cc3dCamera:public CCCamera
{
public:
Cc3dCamera(){
CCSize winSize=CCDirector::sharedDirector()->getWinSize();
m_fovy=;
m_aspect=winSize.width/winSize.height;
m_zNear=;//554/2;//0.5;
m_zFar=; const float w=winSize.width;//11;
const float h=winSize.height;//w*winSize.height/winSize.width;
m_range.init(-w/, -w/+w, -h/, -h/+h,
-,//yeah, better to use negative value
);
m_projectionMode=ec3dPerspectiveMode;
m_isViewMatDirty=false;
m_isViewMatInverseDirty=false; }
virtual ~Cc3dCamera(){ } Cc3dVector4 getEyePos()const;
Cc3dVector4 getCenter()const;
Cc3dVector4 getUp()const;
void setEyePos(const Cc3dVector4&eyePos);
void setCenter(const Cc3dVector4&center);
void setUp(const Cc3dVector4&up);
float getFovy()const {return m_fovy;}
float getAspect()const {return m_aspect;}
float getzNear()const {return m_zNear;}
float getzFar()const {return m_zFar;}
void setFovy(float fovy){m_fovy=fovy;}
void setAspect(float aspect){m_aspect=aspect;}
void setzNear(float zNear){m_zNear=zNear;}
void setzFar(float zFar){m_zFar=zFar;}
Cc3dRange getRange()const {return m_range;}
void setRange(const Cc3dRange&range){m_range=range;}
Cc3dMatrix4 calculateViewMat();
Cc3dMatrix4 calculateViewMatInverse();
Cc3dMatrix4 calculateProjectionMat();
Ec3dProjectionMode getProjectionMode(){return m_projectionMode;}
void setProjectionMode(Ec3dProjectionMode projectionMode){m_projectionMode=projectionMode;}
void applyProjection();
void printProjectionMode()const;
protected:
//projection mode type
Ec3dProjectionMode m_projectionMode;
//perspective projection mode params
float m_fovy;
float m_aspect;
float m_zNear;
float m_zFar;
//Ortho projection mode params
Cc3dRange m_range;//in the camera space
protected:
//cache viewMat
Cc3dMatrix4 m_viewMatCache;
bool m_isViewMatDirty;
Cc3dMatrix4 m_viewMatInverseCache;
bool m_isViewMatInverseDirty; };
#endif /* defined(__HelloCpp__c3dCamera__) */ //
// c3dCamera.cpp
// HelloCpp
//
// Created by Yang Chao (wantnon) on 14-1-7.
//
// #include "c3dCamera.h" Cc3dVector4 Cc3dCamera::getEyePos()const{
//getEyeXYZ is not const, but i want getEyePos to be const
//so i convert this from const to nonconst
float eyex,eyey,eyez;
((Cc3dCamera*)this)->getEyeXYZ(&eyex, &eyey, &eyez);
return Cc3dVector4(eyex,eyey,eyez,);
}
Cc3dVector4 Cc3dCamera::getCenter()const{
//getCenterXYZ is not const, but i want getCenter to be const
//so i convert this from const to nonconst
float centerX,centerY,centerZ;
((Cc3dCamera*)this)->getCenterXYZ(&centerX, &centerY, &centerZ);
return Cc3dVector4(centerX,centerY,centerZ,);
}
Cc3dVector4 Cc3dCamera::getUp()const{
//getUpXYZ is not const, but i want getUp to be const
//so i convert this from const to nonconst
float upX,upY,upZ;
((Cc3dCamera*)this)->getUpXYZ(&upX, &upY, &upZ);
return Cc3dVector4(upX,upY,upZ,);
}
void Cc3dCamera::setEyePos(const Cc3dVector4&eyePos){
this->setEyeXYZ(eyePos.x(), eyePos.y(), eyePos.z());
m_isViewMatDirty=true;
m_isViewMatInverseDirty=true; }
void Cc3dCamera::setCenter(const Cc3dVector4&center){
this->setCenterXYZ(center.x(), center.y(), center.z());
m_isViewMatDirty=true;
m_isViewMatInverseDirty=true; }
void Cc3dCamera::setUp(const Cc3dVector4&up){
this->setUpXYZ(up.x(), up.y(), up.z());
m_isViewMatDirty=true;
m_isViewMatInverseDirty=true;
} Cc3dMatrix4 Cc3dCamera::calculateViewMat(){
//why we not just return CCCamera::m_lookupMatrix?
//because m_lookupMatrix may be dirty (m_lookupMatrix got updated only when locate is called)
//so we calculate view matrix ourselves.
Cc3dMatrix4 ret;
if(m_isViewMatDirty){//dirty
//calculate and cache
ret=::calculateViewMatrix(getEyePos(), getCenter(), getUp());
m_viewMatCache=ret;
}else{//not dirty
//get from cache
ret=m_viewMatCache;
}
return ret; };
Cc3dMatrix4 Cc3dCamera::calculateViewMatInverse(){
Cc3dMatrix4 ret;
if(m_isViewMatInverseDirty){
ret=::calculateViewMatrixInverse(getEyePos(), getCenter(), getUp());
m_viewMatInverseCache=ret;
}else{
ret=m_viewMatInverseCache;
}
return ret;
}
Cc3dMatrix4 Cc3dCamera::calculateProjectionMat(){
Cc3dMatrix4 projectionMat;
switch (m_projectionMode) {
case ec3dPerspectiveMode:
projectionMat=::calculatePerspectiveProjectionMatrix(m_fovy, m_aspect, m_zNear, m_zFar);
break;
case ec3dOrthographicMode:
projectionMat=::calculateOrthoProjectionMatrix(m_range.getMinX(), m_range.getMaxX(), m_range.getMinY(), m_range.getMaxY(), m_range.getMinZ(), m_range.getMaxZ());
break;
default:
assert(false);
break;
}
return projectionMat;
}
void Cc3dCamera::applyProjection()
//note: after apply projection matrix, will be back to modelview matrix stack
{
Cc3dMatrix4 projectionMat=calculateProjectionMat();
kmGLMatrixMode(KM_GL_PROJECTION);
kmGLLoadIdentity();
kmMat4 projMat;
memcpy(projMat.mat, projectionMat.getArray(), *sizeof(float));
kmGLMultMatrix(&projMat);
//restore to model view stack
kmGLMatrixMode(KM_GL_MODELVIEW); };
void Cc3dCamera::printProjectionMode()const{
if(m_projectionMode==ec3dPerspectiveMode){
C3DLOG("projectionMode: perspectiveMode");
}else if(m_projectionMode==ec3dOrthographicMode){
C3DLOG("projectionMode: orthographic");
}else{
assert(false);
}
}
```

3D中的相机 - 投影矩阵和视图矩阵的更多相关文章

  1. 视图矩阵的推导-opengl应用

    把物体从世界坐标系转化到视点坐标系的矩阵称为视图矩阵. 下面我们先看下opengl视图矩阵的推导过程: 假设视点或camera的局部坐标系为UVN,UVN分别指向右方.上方和后方从而构成右手坐标系,视 ...

  2. WEBGL学习【四】模型视图矩阵

    <html lang="zh-CN"> <!--服务器运行地址:http://127.0.0.1:8080/webgl/LearnNeHeWebGL/NeHeWe ...

  3. 2d,3d中旋转推导

    二维绕原点旋转,其实点为(x,y),旋转角度为黄色标注的角度. 推导过程如下: x' = r cos(al+be); y' = r sin(al+be);x '= rcosalcosbe-rsinal ...

  4. 3D中的旋转变换

    相比 2D 中的旋转变换,3D 中的旋转变换复杂了很多.关于 2D 空间的旋转,可以看这篇文章.本文主要粗略地探讨一下 3D 空间中的旋转. 旋转的要素 所谓旋转要素就是说,我们只有知道了这些条件,才 ...

  5. [原][osgEarth]在osgearth中添加相机路径动画

    在osg中添加相机动画路径请参考:http://www.cnblogs.com/lyggqm/p/8075277.html 这里的代码是在osgearth中添加相机动画路径漫游器: #include ...

  6. 3D数学读书笔记——3D中的方位与角位移

    本系列文章由birdlove1987编写,转载请注明出处. 文章链接: http://blog.csdn.net/zhurui_idea/article/details/25339595 方位和角位移 ...

  7. WebView中打开相机,文件选择器的问题和解决方法

    近几年前端开发真是越来越火,H5页面开发的移动端页面甚至有夺我原生开发半壁江山的意思,忧伤忧伤.不过从实际情况考虑,H5一套代码到处跑的特性,我们的Android, IOS ...也就只能呵呵了.然而 ...

  8. OpenGL(五) 三维变换之模型视图矩阵

    计算机三维图形学中,一个基本的任务是如何描述三维空间中一个物体位置的变化,也就是如何 描述物体的运动.通常情况下,物体位置的变化包含三个基本的变化:平移.旋转和缩放,物体的运动也可以用这三个基本的运动 ...

  9. 对CSS3中的transform:Matrix()矩阵的一些理解

    只要有CSS基础的人肯定都知道,我们可以通过transform中的translate,scale,rotate,skew这些方法来控制元素的平移,缩放,旋转,斜切,其实这些方法呢都是为了便于开发者使用 ...

随机推荐

  1. 2019 游族网络java面试笔试题 (含面试题解析)

      本人5年开发经验.18年年底开始跑路找工作,在互联网寒冬下成功拿到阿里巴巴.今日头条.游族网络等公司offer,岗位是Java后端开发,因为发展原因最终选择去了游族网络,入职一年时间了,也成为了面 ...

  2. Spring MVC Web.xml配置

    Web.xml spring&spring mvc 在web.xml中定义contextConfigLocation参数,Spring会使用这个参数去加载所有逗号分隔的xml文件,如果没有这个 ...

  3. 安装vivado 2016.1时出错

    在将vivado 2016.1安装到d:\ xilinx时,发生以下错误: 提取存档D时遇到 错误:\ Xilinx_Vivado_SDK_2016.1_0409_1 \ payload \ rdi_ ...

  4. 基于OpenGL的三维曲面动态显示实现

    在使用Visual C++的MFC AppWizard建立应用程序框架后,生成了多个类,与OpenGL编程相关的类是视图类,主要的显示任务都在其中完成. 1.基于OpenGL绘图的基本设置 1.1 设 ...

  5. 【开发笔记】- 将MySQL数据库表中自增ID从0开始

    命令: 用于清空某表的数据 且让自增的id重新从0开始 truncate table 你的表名

  6. Vue第一天

    什么是 Vue.js? Vue.js是前端的主流框架之一,与 Angular.js.React.js一起,并称为前端三大主流框架 Vue.js是一套构建用户界面的框架,只关注视图层,它不仅易上手,还便 ...

  7. 23、vue实现获取短信验证码

    1.html页面: <el-form-item prop="phoneCode" class="pr"> <el-input placehol ...

  8. 16、css实现div中图片占满整个屏幕

    <div class="img"></div> .img{ background: url("../assets/image/img.png&qu ...

  9. 小型SSM项目出现Failed to load ApplicationContext错误的解决方法(个人向)

    使用单元测试的时候,出现了Failed to load ApplicationContext错误,在添加了一个新的Mapper.xml文件才出现的,在保证其他配置文件没有出错的情况下,检查mapper ...

  10. Haproxy 反向代理

    一.haproxy介绍 HAProxy是一个使用C语言编写的自由及开放源代码软件,其提供高可用性.负载均衡,以及基于TCP和HTTP的应用程序代理. 特点如下: .支持两种代理模式:TCP(四层)和H ...