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);
}
}
```

最新文章

  1. Centos7安装配置NFS服务和挂载
  2. linux应用程序开发-文件编程-库函数
  3. elasticsearch分词插件的安装
  4. GL_Oracle Erp常用的报表(汇总)
  5. Busybox支持中文的解决办法
  6. jsp bean标签
  7. kruskal算法-Pascal
  8. PostgreSQL的 create index concurrently
  9. OpenWRT 编译 error GNU libiconv not in use but included iconv.h is from...
  10. js动态向页面中添加表格
  11. VBA怎样统计同一类型的数据的总和
  12. 使用FSharp 探索Dotnet图像处理功能2--均衡灰度
  13. 【译】The Accidental DBA:Troubleshooting Performance
  14. vue之render基本书写方法
  15. laytpl模板——怎么使用ajax与数据交互
  16. Metrics.NET step by step
  17. Mac休眠后解决卡死转圈问题
  18. java线程和多线程同步
  19. linux下git服务器安装
  20. Bootstrap3基础 thumbnail 圆角类型的div块

热门文章

  1. ProviderManager
  2. 2019 263云通信java面试笔试题 (含面试题解析)
  3. logback配置和使用
  4. 当前标识(IIS APPPOOL\DefaultAppPool)没有对“C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files”的写访问权限
  5. CentOS 7 - 安装Python 3
  6. thinkPHP+LayUI 懒加载实现
  7. ML- 核函数(Kernel) 的 SVM
  8. /bin/false 和 /usr/sbin/nologin
  9. 卓越Code团队SCRUM呕心沥血实践总结
  10. asp.net中的参数传递:Context.Handler 的用法