观察坐标系参数

说明:其中观察方向与+Zview相反。

观察平面法向量

  • 观察方向通常沿着Zview轴,因此观察平面,有时也称投影平面一般假设为与该轴垂直。这样,观察平面的方向 及正Zview轴可定义为观察平面法向量N。

  • OpenGL中不提供对观察平面的选择功能。近裁剪平面永远和观察平面重合,因为裁剪窗口永远位于观察体的近平面上。


观察向上向量

世界坐标系到观察坐标第的变换

  • 平移观察坐标原点到世界坐标系原点。
  • 进行旋转,分别让Xview,Yview,Zview轴对应到世界坐标的Xw,Yw,Zw轴。

在OpenGL中指定观察参数(gluLookAt)时,生成一个矩阵并和当前建模观察矩阵合并。同时,该观察矩阵和任何可能已指定的几何变换矩阵相结合。然后将该组合矩阵用于将世界坐标系的对象描述变换到观察坐标系中。

如:

gluLookAt(500, 500, 0, 500, 500, -1, 0, 1, 0);

生成的矩阵为:

投影变换

观察位置、观察平面(即投影平面)‘、裁剪窗口和裁剪平面都在观察坐标系中指定。

此处使用正投影变换来描述,投影方向平行于Zview轴,正投影的变换公式很简单。如图7.26,

由于屏幕坐标系经常指定为左手系,因此规范化观察体也…

二维裁剪窗口到规范化视口的映射




三维裁剪窗口到规范化


如:

glOrtho(-2634.57, 2634.57, -2000, 2000, -2000, 2000);

生成的规范化矩阵如下

示例代码

#define FREEGLUT_STATIC#include "gl/freeglut.h"
#include <cmath>
#include <memory>
#include <iostream>
#include <iomanip>
#include <vector>//4X4矩阵
class Matrix3d
{public:Matrix3d(){memset(&m_dValues, 0, sizeof(double) * 16);for (int i = 0; i < 4; ++i){m_dValues[i][i] = 1.0;}}virtual ~Matrix3d(){}Matrix3d& postBy(const Matrix3d& mMat){for (int i = 0; i < 4; ++i){for (int j = 0; j < 4; ++j){double dSum = 0;for (int c = 0; c < 4; ++c){dSum += this->m_dValues[i][c] *mMat.m_dValues[c][j];}this->m_dValues[i][j] = dSum;}}return *this;}Matrix3d prevBy(const Matrix3d& mMat){for (int i = 0; i < 4; ++i){for (int j = 0; j < 4; ++j){double dSum = 0.0;for (int c = 0; c < 4; ++c){dSum += mMat.m_dValues[i][c] *this->m_dValues[c][j];}this->m_dValues[i][j] = dSum;}}return *this;}public:double m_dValues[4][4];
};//3维向量
class Vector3d
{public:Vector3d(){m_x = 0;m_y = 0;m_z = 0;}Vector3d(double x, double y, double z){m_x = x;m_y = y;m_z = z;}virtual ~Vector3d(){}//mat * vectorVector3d& transformBy(const Matrix3d& mMat ){m_x = mMat.m_dValues[0][0] * m_x + mMat.m_dValues[0][1] * m_y+ mMat.m_dValues[0][2] * m_z + mMat.m_dValues[0][3];m_y = mMat.m_dValues[1][0] * m_x + mMat.m_dValues[1][1] * m_y+ mMat.m_dValues[1][2] * m_z + mMat.m_dValues[1][3];m_z = mMat.m_dValues[2][0] * m_x + mMat.m_dValues[2][1] * m_y+ mMat.m_dValues[2][2] * m_z + mMat.m_dValues[2][3];return *this;}public:double m_x;double m_y;double m_z;
};#define MY_PI (3.1415926535f)
GLfloat g_dApectRadio = 1.0;
GLfloat g_CurScale = 1.0;void GetOpenGLMatrix(GLenum enMatrixEnum, Matrix3d& mRtMat)
{float m[16] = { 0 }; //用来保存当前矩阵数据  glGetFloatv(enMatrixEnum, m);//观察矩阵的逆矩阵,得到视图矩阵for (int i = 0; i < 16; ++i){mRtMat.m_dValues[i % 4][i / 4] = m[i];}
}void DisplayMatrix(const Matrix3d& mMat)
{for (int i = 0; i < 4; ++i){for (int j = 0; j < 4; ++j){std::cout << std::setw(12) << std::left << std::setprecision(6)<< mMat.m_dValues[i][j];}std::cout << std::endl;}std::cout << std::endl << std::endl;
}void ShowOpenGLMatrix(GLenum enMatrixEnum)
{Matrix3d mMat;GetOpenGLMatrix(enMatrixEnum, mMat);if (enMatrixEnum == GL_MODELVIEW_MATRIX){std::cout << "模型视图矩阵(OpenGL采用前乘,坐标点用列向量):" << std::endl;}else if (enMatrixEnum == GL_PROJECTION_MATRIX){std::cout << "投影矩阵(OpenGL采用前乘,坐标点用列向量):" << std::endl;}DisplayMatrix(mMat);
}void ShowVectorTransform()
{Matrix3d mModelViewMat;GetOpenGLMatrix(GL_MODELVIEW_MATRIX, mModelViewMat);Matrix3d mProjectMat;GetOpenGLMatrix(GL_PROJECTION_MATRIX, mProjectMat);std::cout << "mProjectMat * mModelViewMat:" << std::endl;Matrix3d mTempMat = mModelViewMat;mTempMat.prevBy(mProjectMat);DisplayMatrix(mTempMat);std::vector<Vector3d> mPoints;mPoints.push_back(Vector3d(-2000, -4000, -2000));mPoints.push_back(Vector3d(2000, 4000, 2000));mPoints.push_back(Vector3d(0, 0, 0));mPoints.push_back(Vector3d(1000, 0, 0));mPoints.push_back(Vector3d(1000, 1000, 0));mPoints.push_back(Vector3d(0, 1000, 0));for (auto it = mPoints.begin(); it != mPoints.end(); ++it){Vector3d ptTemp = *it;std::cout << "point( " << ptTemp.m_x << "," << ptTemp.m_y<< "," << ptTemp.m_z << ")" << std::endl;ptTemp.transformBy(mProjectMat);std::cout << "\tpoint( " << ptTemp.m_x << "," << ptTemp.m_y<< "," << ptTemp.m_z << ")" << std::endl;}
}void OnDisplay()
{glMatrixMode(GL_PROJECTION);glLoadIdentity();double fRange = 2000 * g_CurScale; //正交投影,通过投影矩阵来达到缩放的效果if (g_dApectRadio > 1.0){glOrtho(-fRange*g_dApectRadio, fRange * g_dApectRadio, -fRange, fRange, -2000, 2000);std::cout << "left=" << -fRange*g_dApectRadio<< ", right=" << fRange*g_dApectRadio<< ", top=" << -fRange<< ", bottom=" << fRange<< ", zNear=-2000, zFar=2000" << std::endl;}else{glOrtho(-fRange, fRange, -fRange / g_dApectRadio, fRange / g_dApectRadio, -2000, 2000);std::cout << "left=" << -fRange<< ", right=" << fRange<< ", top=" << -fRange/g_dApectRadio<< ", bottom=" << fRange/g_dApectRadio<< ", zNear=-2000, zFar=2000" << std::endl;}//俯视glMatrixMode(GL_MODELVIEW);glLoadIdentity();gluLookAt(500, 500, 0, 500, 500, -1, 0, 1, 0);
//  gluLookAt(0, 0, 0, 0, 0, -1, 0, 1, 0);ShowOpenGLMatrix(GL_MODELVIEW_MATRIX);ShowOpenGLMatrix(GL_PROJECTION_MATRIX);ShowVectorTransform();glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);glColor3d(1.0, 0.0, 0.0);glEnable(GL_POLYGON_SMOOTH);glHint(GL_POLYGON_SMOOTH_HINT, GL_FASTEST);glBegin(GL_QUADS);glVertex3d(0, 0, 0);glVertex3d(1000, 0, 0);glVertex3d(1000, 1000, 0);glVertex3d(0, 1000, 0);glEnd();glFlush();
}void OnReSize(int w, int h)
{glViewport(0, 0, w, h);std::cout << "w=" << w << ",h=" << h << std::endl;if (h <= 0) h = 1;g_dApectRadio = 1.0 * w / h;
}void OnSpecialKey(GLint key, GLint x, GLint y)
{GLfloat fStep = 0.2;if (key == GLUT_KEY_UP){g_CurScale *= (1.0 + fStep); //缩小}else if (key == GLUT_KEY_DOWN){g_CurScale *= (1.0 - fStep); //放大}glutPostRedisplay();
}int main(int argc, char** argv)
{glutInit(&argc, argv);glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH | GLUT_MULTISAMPLE);glutInitWindowSize(300, 600);double fWidths[2] = { 0 };glGetDoublev(GL_LINE_WIDTH_RANGE, fWidths);GLfloat fWidthStep = 0;glGetFloatv(GL_LINE_WIDTH_GRANULARITY, &fWidthStep);glutCreateWindow("Ortho3D");glutDisplayFunc(OnDisplay);glutReshapeFunc(OnReSize);glutSpecialFunc(OnSpecialKey);glClearColor(0.0f, 0.0f, 0.0f, 1.0f);glEnable(GL_DEPTH_TEST);glEnable(GL_CULL_FACE);glCullFace(GL_BACK);glDisable(GL_LIGHTING);const char* pszVersion = (const char*)glGetString(GL_VERSION);if (pszVersion){std::cout << pszVersion << std::endl;}glutMainLoop();return 0;
}

OpenGL笔记:观察坐标系(模型视图矩阵)、投影变换相关推荐

  1. 【OpenGL】十、OpenGL 绘制点 ( 初始化 OpenGL 矩阵 | 设置投影矩阵 | 设置模型视图矩阵 | 绘制点 | 清除缓冲区 | 设置当前颜色值 | 设置点大小 | 绘制点 )

    文章目录 一.初始化 OpenGL 矩阵 1.设置投影矩阵 2.设置模型视图矩阵 二.绘制点 1.清除缓冲区 2.设置当前颜色值 3.设置绘制点的大小 4.绘制点 5.将缓冲区绘制到前台 三.部分代码 ...

  2. ModelMatrix、ModelViewMatrix、ProjectionMatrix、NormalMatrix模型矩阵、模型视图矩阵、投影矩阵、正规矩阵详解

    ModelMatrix.ModelViewMatrix.ProjectionMatrix.ModelMatrix模型矩阵.模型视图矩阵.投影矩阵.正规矩阵详解 1. 前言 在openGL经常用到Mod ...

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

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

  4. OpenGL之利用模型视图矩阵和投影矩阵让球体自动旋转

    核心业务 绘制球体(SetupRC()): // 绘制一个球体gltMakeSphere(torusBatch, 0.5f, 10, 20);glPolygonMode(GL_FRONT_AND_BA ...

  5. OpenGL学习笔记:模型变换、视图变换、投影变换 、视口变换、操作矩阵堆栈

    1. 模型变换和视图变换  从"相对移动"的观点来看,改变观察点的位置与方向和改变物体本身的位置与方向具有等效性.在OpenGL中,实现这两种功能甚至使用的是同样的函数. 由于模型 ...

  6. OpenGL第五讲——模型视图变换和投影变换

    Chapter5 OpenGL变换 几种不同的变换: 视图变换:从不同的位置去观察它 模型变换:移动.旋转.放大.缩放 近大远小的透视效果.投影变换 5.1 模型变换和视图变换 从"相对移动 ...

  7. 实验5 OpenGL模型视图变换

    1.实验目的: 理解掌握OpenGL程序的模型视图变换. 2.实验内容: (1)阅读实验原理,运行示范实验代码,理解掌握OpenGL程序的模型视图变换: (2)根据示范代码,尝试完成实验作业: 3.实 ...

  8. 模型矩阵、视图矩阵、投影矩阵

    模型视图投影矩阵的作用,就是将顶点从局部坐标系转化到规范立方体(Canonical View Volnme)中.总而言之,模型视图投影矩阵=投影矩阵×视图矩阵×模型矩阵,模型矩阵将顶点从局部坐标系转化 ...

  9. WEBGL学习【八】模型视图投影矩阵

    版权声明:本文为博主原创文章,未经博主允许不得转载.更多学习资料请访问我爱科技论坛:www.52tech.tech https://blog.csdn.net/m0_37981569/article/ ...

最新文章

  1. Mockito cannot mock/spy because : - final class 问题
  2. 接口隔离原则_设计模式六大原则
  3. win7装64位oracle和PLSQL
  4. Flex与.NET互操作(九):FluorineFx.NET的认证(Authentication )与授权(Authorization)
  5. android编程中setLayoutParams方法设置
  6. 央行变相降准祭出又一新手段 引发同业套利之忧
  7. MySQL JDBC URL各参数详解
  8. 运行指定代码_JavaScript 运行机制(Event Loop)详解
  9. 【CodeVS2226】飞行棋
  10. jquery 根据样式或者名称获取 对象遍历赋值
  11. MTOM以及在WCF中的应用
  12. C# WPF仿360安全卫士11
  13. jquery填充列表内容
  14. EVE上传Dynamips和IOL
  15. Wi-Fi当前的趋势及对IT和物联网的影响
  16. 电商后台设计:品类管理
  17. GitOps最强工具-2. Argo CD安装
  18. Android的Elevation与TranslationZ探索
  19. 大脑像一台计算机的数学家,计算机之父冯·诺依曼|他的大脑就是一台超级计算机...
  20. STM32芯片超低功耗设计思路

热门文章

  1. Terminal 中使用vi的快捷方式
  2. 【C程序】逻辑判断真假话问题:3人说真话,1人说假话
  3. C盘垃圾文件清理方法
  4. Survey of intrusion detection systems:techniques, datasets and challenges
  5. ISME Comm | 机器学习和深度学习在微生物组研究中的应用
  6. Riplus主题下载次数不减少BUG修复了
  7. 寒假作业1:打印沙漏
  8. 【纯干货】Linux内存管理(最透彻的一篇)
  9. ArcGIS Engine开发---图层符号化
  10. 电影票小程序插件 电影票CPS插件 电影票微信小程序插件