Tutorial 12 - Perspective Projection
来源:互联网 发布:java实现迭代器 编辑:程序博客网 时间:2024/05/18 01:23
pipeline.h:
#ifndef PIPELINE_H#definePIPELINE_H#include "math_3d.h"class Pipeline{public: Pipeline() { m_scale = Vector3f(1.0f, 1.0f, 1.0f); m_worldPos = Vector3f(0.0f, 0.0f, 0.0f); m_rotateInfo = Vector3f(0.0f, 0.0f, 0.0f); } void Scale(float ScaleX, float ScaleY, float ScaleZ) { m_scale.x = ScaleX; m_scale.y = ScaleY; m_scale.z = ScaleZ; } void WorldPos(float x, float y, float z) { m_worldPos.x = x; m_worldPos.y = y; m_worldPos.z = z; } void Rotate(float RotateX, float RotateY, float RotateZ) { m_rotateInfo.x = RotateX; m_rotateInfo.y = RotateY; m_rotateInfo.z = RotateZ; } void SetPerspectiveProj(float FOV, float Width, float Height, float zNear, float zFar) { m_persProj.FOV = FOV; m_persProj.Width = Width; m_persProj.Height = Height; m_persProj.zNear = zNear; m_persProj.zFar = zFar; } const Matrix4f *GetTrans();private: void InitScaleTransform(Matrix4f &m) const; void InitRotateTransform(Matrix4f &m) const; void InitTranslationTransform(Matrix4f &m) const; //================================================================== //函数名: InitPerspectiveProj //功能: 初始化透视矩阵。根据传入的参数宽高比、垂直视角、近z平面和远z平面值计算出透视矩阵。 //输入参数:Matrix4f& m //返回值: void //================================================================== void InitPerspectiveProj(Matrix4f &m) const; Vector3f m_scale; Vector3f m_worldPos; Vector3f m_rotateInfo; //透视投影参数 struct { float FOV;//摄像机观察垂直视角的大小。 float Width;//投影区域(四边形)的宽 float Height;//投影区域(四边形)的高 float zNear;//近z平面到视点的距离。 float zFar;//远z平面到视点距离。 } m_persProj; Matrix4f m_transformation;};#endif/* PIPELINE_H */
pipeline.cpp:
#include "pipeline.h"void Pipeline::InitScaleTransform(Matrix4f &m) const{ m.m[0][0] = m_scale.x; m.m[0][1] = 0.0f; m.m[0][2] = 0.0f; m.m[0][3] = 0.0f; m.m[1][0] = 0.0f; m.m[1][1] = m_scale.y; m.m[1][2] = 0.0f; m.m[1][3] = 0.0f; m.m[2][0] = 0.0f; m.m[2][1] = 0.0f; m.m[2][2] = m_scale.z; m.m[2][3] = 0.0f; m.m[3][0] = 0.0f; m.m[3][1] = 0.0f; m.m[3][2] = 0.0f; m.m[3][3] = 1.0f;}void Pipeline::InitRotateTransform(Matrix4f &m) const{ Matrix4f rx, ry, rz; const float x = ToRadian(m_rotateInfo.x); const float y = ToRadian(m_rotateInfo.y); const float z = ToRadian(m_rotateInfo.z); rx.m[0][0] = 1.0f; rx.m[0][1] = 0.0f; rx.m[0][2] = 0.0f; rx.m[0][3] = 0.0f; rx.m[1][0] = 0.0f; rx.m[1][1] = cosf(x); rx.m[1][2] = -sinf(x); rx.m[1][3] = 0.0f; rx.m[2][0] = 0.0f; rx.m[2][1] = sinf(x); rx.m[2][2] = cosf(x); rx.m[2][3] = 0.0f; rx.m[3][0] = 0.0f; rx.m[3][1] = 0.0f; rx.m[3][2] = 0.0f; rx.m[3][3] = 1.0f; ry.m[0][0] = cosf(y); ry.m[0][1] = 0.0f; ry.m[0][2] = -sinf(y); ry.m[0][3] = 0.0f; ry.m[1][0] = 0.0f; ry.m[1][1] = 1.0f; ry.m[1][2] = 0.0f; ry.m[1][3] = 0.0f; ry.m[2][0] = sinf(y); ry.m[2][1] = 0.0f; ry.m[2][2] = cosf(y); ry.m[2][3] = 0.0f; ry.m[3][0] = 0.0f; ry.m[3][1] = 0.0f; ry.m[3][2] = 0.0f; ry.m[3][3] = 1.0f; rz.m[0][0] = cosf(z); rz.m[0][1] = -sinf(z); rz.m[0][2] = 0.0f; rz.m[0][3] = 0.0f; rz.m[1][0] = sinf(z); rz.m[1][1] = cosf(z); rz.m[1][2] = 0.0f; rz.m[1][3] = 0.0f; rz.m[2][0] = 0.0f; rz.m[2][1] = 0.0f; rz.m[2][2] = 1.0f; rz.m[2][3] = 0.0f; rz.m[3][0] = 0.0f; rz.m[3][1] = 0.0f; rz.m[3][2] = 0.0f; rz.m[3][3] = 1.0f; m = rz * ry * rx;}void Pipeline::InitTranslationTransform(Matrix4f &m) const{ m.m[0][0] = 1.0f; m.m[0][1] = 0.0f; m.m[0][2] = 0.0f; m.m[0][3] = m_worldPos.x; m.m[1][0] = 0.0f; m.m[1][1] = 1.0f; m.m[1][2] = 0.0f; m.m[1][3] = m_worldPos.y; m.m[2][0] = 0.0f; m.m[2][1] = 0.0f; m.m[2][2] = 1.0f; m.m[2][3] = m_worldPos.z; m.m[3][0] = 0.0f; m.m[3][1] = 0.0f; m.m[3][2] = 0.0f; m.m[3][3] = 1.0f;}void Pipeline::InitPerspectiveProj(Matrix4f &m) const{ const float ar = m_persProj.Width / m_persProj.Height; const float zNear = m_persProj.zNear; const float zFar = m_persProj.zFar; const float zRange = zNear - zFar; const float tanHalfFOV = tanf(ToRadian(m_persProj.FOV / 2.0f)); m.m[0][0] = 1.0f / (tanHalfFOV * ar); m.m[0][1] = 0.0f; m.m[0][2] = 0.0f; m.m[0][3] = 0.0; m.m[1][0] = 0.0f; m.m[1][1] = 1.0f / tanHalfFOV; m.m[1][2] = 0.0f; m.m[1][3] = 0.0; m.m[2][0] = 0.0f; m.m[2][1] = 0.0f; m.m[2][2] = (-zNear - zFar) / zRange ; m.m[2][3] = 2.0f * zFar * zNear / zRange; m.m[3][0] = 0.0f; m.m[3][1] = 0.0f; m.m[3][2] = 1.0f; m.m[3][3] = 0.0;}const Matrix4f *Pipeline::GetTrans(){ Matrix4f ScaleTrans, RotateTrans, TranslationTrans, PersProjTrans; InitScaleTransform(ScaleTrans); InitRotateTransform(RotateTrans); InitTranslationTransform(TranslationTrans); InitPerspectiveProj(PersProjTrans); m_transformation = PersProjTrans * TranslationTrans * RotateTrans * ScaleTrans; return &m_transformation;}
perspectiveProjection.cpp:
/*平行投影,就是把顶点垂直的投向投影平面,常用在cad或者机械制图中。另外一种投影是透视投影,这种投影能较好的使二维投影显示立体感,因为符合人眼观看物体透视原理*///////////////////////////////////////////////////////////////////////*程序内容:学习透视投影 程序分析:1)初始化glut2)设置回调函数3) 初始化glew4)设置清除背景颜色5)创建顶点缓存对象6)创建索引缓冲对象7)编译shader对象8)开始内部循环 程序结果:利用透视投影绘制旋转的四面体*/////////////////////////////////////////////////////////////////////#include <stdio.h>#include <string.h>#include <assert.h>#include <math.h>#include <GL/glew.h>#include <GL/freeglut.h>#include "pipeline.h"#pragma comment(lib, "glew32.lib")#pragma comment(lib, "glew32mx.lib")#pragma comment(lib, "freeglut.lib")#define WINDOW_WIDTH 1024#define WINDOW_HEIGHT 768GLuint VBO;GLuint IBO;GLuint gWorldLocation;/* 投影矩阵乘以顶点位置,这时得到的顶点坐标就为裁剪空间, 再经过透视除法后,就是所谓的归一化裁剪空间。*/static const char *pVS = " \n\#version 330 \n\ \n\layout (location = 0) in vec3 Position; \n\ \n\uniform mat4 gWorld; \n\ \n\out vec4 Color; \n\ \n\void main() \n\{ \n\ gl_Position = gWorld * vec4(Position, 1.0); \n\ Color = vec4(clamp(Position, 0.0, 1.0), 1.0); \n\}";static const char *pFS = " \n\#version 330 \n\ \n\in vec4 Color; \n\ \n\out vec4 FragColor; \n\ \n\void main() \n\{ \n\ FragColor = Color; \n\}";static void RenderSceneCB(){ glClear(GL_COLOR_BUFFER_BIT); static float Scale = 0.0f; Scale += 0.1f; Pipeline p; //设置各个变换矩阵参数 p.Rotate(0.0f, Scale, 0.0f); p.WorldPos(0.0f, 0.0f, 5.0f); //调用设置透视矩阵参数函数 p.SetPerspectiveProj(30.0f, WINDOW_WIDTH, WINDOW_HEIGHT, 1.0f, 100.0f); //传递给Uniform变量 glUniformMatrix4fv(gWorldLocation, 1, GL_TRUE, (const GLfloat *)p.GetTrans()); glEnableVertexAttribArray(0); glBindBuffer(GL_ARRAY_BUFFER, VBO); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO); glDrawElements(GL_TRIANGLES, 12, GL_UNSIGNED_INT, 0); glDisableVertexAttribArray(0); glutSwapBuffers();}static void InitializeGlutCallbacks(){ glutDisplayFunc(RenderSceneCB); glutIdleFunc(RenderSceneCB);}static void CreateVertexBuffer(){ Vector3f Vertices[4]; Vertices[0] = Vector3f(-1.0f, -1.0f, 0.5773f); Vertices[1] = Vector3f(0.0f, -1.0f, -1.15475f); Vertices[2] = Vector3f(1.0f, -1.0f, 0.5773f); Vertices[3] = Vector3f(0.0f, 1.0f, 0.0f); glGenBuffers(1, &VBO); glBindBuffer(GL_ARRAY_BUFFER, VBO); glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW);}static void CreateIndexBuffer(){ unsigned int Indices[] = { 0, 3, 1, 1, 3, 2, 2, 3, 0, 0, 2, 1 }; glGenBuffers(1, &IBO); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(Indices), Indices, GL_STATIC_DRAW);}static void AddShader(GLuint ShaderProgram, const char *pShaderText, GLenum ShaderType){ GLuint ShaderObj = glCreateShader(ShaderType); if (ShaderObj == 0) { fprintf(stderr, "Error creating shader type %d\n", ShaderType); exit(0); } const GLchar *p[1]; p[0] = pShaderText; GLint Lengths[1]; Lengths[0] = strlen(pShaderText); glShaderSource(ShaderObj, 1, p, Lengths); glCompileShader(ShaderObj); GLint success; glGetShaderiv(ShaderObj, GL_COMPILE_STATUS, &success); if (!success) { GLchar InfoLog[1024]; glGetShaderInfoLog(ShaderObj, 1024, NULL, InfoLog); fprintf(stderr, "Error compiling shader type %d: '%s'\n", ShaderType, InfoLog); exit(1); } glAttachShader(ShaderProgram, ShaderObj);}static void CompileShaders(){ GLuint ShaderProgram = glCreateProgram(); if (ShaderProgram == 0) { fprintf(stderr, "Error creating shader program\n"); exit(1); } AddShader(ShaderProgram, pVS, GL_VERTEX_SHADER); AddShader(ShaderProgram, pFS, GL_FRAGMENT_SHADER); GLint Success = 0; GLchar ErrorLog[1024] = { 0 }; glLinkProgram(ShaderProgram); glGetProgramiv(ShaderProgram, GL_LINK_STATUS, &Success); if (Success == 0) { glGetProgramInfoLog(ShaderProgram, sizeof(ErrorLog), NULL, ErrorLog); fprintf(stderr, "Error linking shader program: '%s'\n", ErrorLog); exit(1); } glValidateProgram(ShaderProgram); glGetProgramiv(ShaderProgram, GL_VALIDATE_STATUS, &Success); if (!Success) { glGetProgramInfoLog(ShaderProgram, sizeof(ErrorLog), NULL, ErrorLog); fprintf(stderr, "Invalid shader program: '%s'\n", ErrorLog); exit(1); } glUseProgram(ShaderProgram); gWorldLocation = glGetUniformLocation(ShaderProgram, "gWorld"); assert(gWorldLocation != 0xFFFFFFFF);}int main(int argc, char **argv){ glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA); glutInitWindowSize(WINDOW_WIDTH, WINDOW_HEIGHT); glutInitWindowPosition(100, 100); glutCreateWindow("Tutorial 12"); InitializeGlutCallbacks(); // Must be done after glut is initialized! GLenum res = glewInit(); if (res != GLEW_OK) { fprintf(stderr, "Error: '%s'\n", glewGetErrorString(res)); return 1; } glClearColor(0.0f, 0.0f, 0.0f, 0.0f); CreateVertexBuffer(); CreateIndexBuffer(); CompileShaders(); glutMainLoop(); return 0;}
- Tutorial 12 - Perspective Projection
- Introduction To Perspective Projection
- OpenGL Perspective Projection Matrix
- OpenGL Perspective Projection Matrix
- OpenGL Perspective Projection Matrix
- OpenGL Perspective Projection Matrix
- OpenGL Perspective Projection Matrix
- 透视投影(Perspective Projection)
- II. Positioning---Chapter 4----Perspective Projection
- 笔记3:透视投影变换(perspective projection)
- OpenGL Perspective Projection Matrix (Easy Understood)
- 透视投影(Perspective Projection)变换推导
- PERL tutorial' from Unix Perspective
- DirectX 9.0 C++ 教程 关于Perspective projection,Matrices,摄像头,旋转
- OpenGL ES —— Perspective Projection的推导
- OpenGL ES —— Perspective Projection的推导
- Projection
- 自己的透视投影坐标变换(perspective projection)的推导过程理解
- SCU 4313 把一棵树切成每段K个点 (n%k)剩下的点不管
- Number Sequence_hdu_1005(规律)
- undefined reference to 'pthread_create'
- Application Loader下载安装和上传app程序
- 动态规划——最大子段和问题
- Tutorial 12 - Perspective Projection
- CA证书服务器从2003迁移到2008 R2!
- 关键字volatile的含义及常见用法
- Eratosthenes筛选法
- 面试题-螺旋矩阵
- 符号三角形_hdu_2510(深搜).java
- Mysql开启远程连接方法
- J2EE环境搭建(三)配置Tomcat 7.0的局部数据源
- TCP协议的流量控制、拥塞控制和差错控制