OpenGL备忘6---坐标系统

来源:互联网 发布:人工智能发展 编辑:程序博客网 时间:2024/05/13 21:43
1.经常用到的五个坐标系统
  • 局部空间(Local Space,或者称为物体空间(Object Space))
  • 世界空间(World Space)
  • 观察空间(View Space,或者称为视觉空间(Eye Space))
  • 裁剪空间(Clip Space)

  • 屏幕空间(Screen Space)
概述:
最重要三个矩阵:模型(Model)、视图(View)、投影(Projection)====MVP
coordinate_systems
  1. 局部坐标是对象相对于局部原点的坐标;也是对象开始的坐标。
  2. 将局部坐标转换为世界坐标,世界坐标是作为一个更大空间范围的坐标系统。这些坐标是相对于世界的原点的。
  3. 接下来我们将世界坐标转换为观察坐标,观察坐标是指以摄像机或观察者的角度观察的坐标。
  4. 在将坐标处理到观察空间之后,我们需要将其投影到裁剪坐标。裁剪坐标是处理-1.0到1.0范围内并判断哪些顶点将会出现在屏幕上。
  5. 最后,我们需要将裁剪坐标转换为屏幕坐标,我们将这一过程成为视口变换(Viewport Transform)。视口变换将位于-1.0到1.0范围的坐标转换到由glViewport函数所定义的坐标范围内。最后转换的坐标将会送到光栅器,由光栅器将其转化为片段。
2.正射投影(Orthographic Projection)
orthographic projection frustum
glm::ortho(0.0f,800.0f,0.0f,600.0f,0.1f,100.0f);
前两个参数指定了平截头体的左右坐标,
第三和第四参数指定了平截头体的底部和上部。
通过这四个参数我们定义了近平面和远平面的大小,
然后第五和第六个参数则定义了近平面和远平面的距离。
这个指定的投影矩阵将处于这些x,y,z范围之间的坐标转换到标准化设备坐标系中。

透视投影(Perspective Projection)

 perspective_frustum
glm::mat4 proj = glm::perspective(45.0f, (float)width/(float)height,0.1f,100.0f);


最终应用到顶点组合到一起公式;

注意每个矩阵被运算的顺序是相反的(记住我们需要从右往左乘上每个矩阵)。最后的顶点应该被赋予顶点着色器中的gl_Position且OpenGL将会自动进行透视划分和裁剪。


按照约定,OpenGL是一个右手坐标系。最基本的就是说正x轴在你的右手边,正y轴往上而正z轴是往后的。
coordinate_systems_right_handed

Vertex Shader中应用:
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;

voidmain(){  
// 注意从右向左读  
gl_Position = projection * view * model * vec4(position, 1.0f); 
...
}


传到shader中写法“
GLint modelLoc = glGetUniformLocation(ourShader.Program, "model");
glUniformMatrix4fv(modelLoc,1, GL_FALSE, glm::value_ptr(model));... 
// 观察矩阵和投影矩阵与之类似


常用例子顶点:
绘制一个立方体顶点位置:一共需要36个顶点(6个面 x 每个面有2个三角形组成 x 每个三角形有3个顶点)
glDrawArrays(GL_TRIANGLES,0,36);
GLfloat vertices[] = {  
-0.5f, -0.5f, -0.5f,0.0f,0.0f,  
0.5f, -0.5f, -0.5f,1.0f,0.0f,  
0.5f,0.5f, -0.5f,1.0f,1.0f,  
0.5f,0.5f, -0.5f,1.0f,1.0f,  
-0.5f,0.5f, -0.5f,0.0f,1.0f,  
-0.5f, -0.5f, -0.5f,0.0f,0.0f,  
-0.5f, -0.5f,0.5f,0.0f,0.0f,  
0.5f, -0.5f,0.5f,1.0f,0.0f,  
0.5f,0.5f,0.5f,1.0f,1.0f,  
0.5f,0.5f,0.5f,1.0f,1.0f,  
-0.5f,0.5f,0.5f,0.0f,1.0f,  
-0.5f, -0.5f,0.5f,0.0f,0.0f,  
-0.5f,0.5f,0.5f,1.0f,0.0f,  
-0.5f,0.5f, -0.5f,1.0f,1.0f,  
-0.5f, -0.5f, -0.5f,0.0f,1.0f,  
-0.5f, -0.5f, -0.5f,0.0f,1.0f
-0.5f, -0.5f,0.5f,0.0f,0.0f,  
-0.5f,0.5f,0.5f,1.0f,0.0f,  
0.5f,0.5f,0.5f,1.0f,0.0f,  
0.5f,0.5f, -0.5f,1.0f,1.0f,  
0.5f, -0.5f, -0.5f,0.0f,1.0f,  
0.5f, -0.5f, -0.5f,0.0f,1.0f,  
0.5f, -0.5f,0.5f,0.0f,0.0f,  
0.5f,0.5f,0.5f,1.0f,0.0f,  
-0.5f, -0.5f, -0.5f,0.0f,1.0f
0.5f, -0.5f, -0.5f,1.0f,1.0f
0.5f, -0.5f,0.5f,1.0f,0.0f
0.5f, -0.5f,0.5f,1.0f,0.0f
-0.5f, -0.5f,0.5f,0.0f,0.0f
-0.5f, -0.5f, -0.5f,0.0f,1.0f,
-0.5f,0.5f, -0.5f,0.0f,1.0f,
0.5f,0.5f, -0.5f,1.0f,1.0f
0.5f,0.5f,0.5f,1.0f,0.0f
0.5f,0.5f,0.5f,1.0f,0.0f
-0.5f,0.5f,0.5f,0.0f,0.0f,  
-0.5f,0.5f, -0.5f,0.0f,1.0f};




OpenGL将深度信息储存在Z缓冲区(Z-buffer),允许OpenGl决定何时覆盖一个像素何时不覆盖,使用z--buffer可以设置Opengl进行深度测试
不开启的话会出现:某些本应被遮挡住的面被绘制在了这个立方体的其他面的上面
Z-缓冲区
深度测试(Depth Testing)
glEnable(GL_DEPTH_TEST);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

0 0