变换:向量和矩阵
2016-05-22 本文已影响221人
Gaolex
主要使用了:
- 矩阵构造(平移、旋转、综合变换)
- 模型视图矩阵
- 三角形批次类(创建花托)
- 投影矩阵(透视投影)
示例程序绘制了一个在屏幕中间旋转的线框花托。
// ModelviewProjection.cpp
// OpenGL SuperBible
// Demonstrates OpenGL the ModelviewProjection matrix
// Program by Richard S. Wright Jr.
#include <GLTools.h> // OpenGL toolkit
#include <GLMatrixStack.h>
#include <GLFrame.h>
#include <GLFrustum.h>
#include <GLGeometryTransform.h>
#include <GLBatch.h>
#include <StopWatch.h>
#include <math.h>
#ifdef __APPLE__
#include <glut/glut.h>
#else
#define FREEGLUT_STATIC
#include <GL/glut.h>
#endif
// Global view frustum class
//使用GLFrustum类来设置透视投影
GLFrustum viewFrustum;
// The shader manager
//着色器管理器
GLShaderManager shaderManager;
// The torus
//三角形批次类
GLTriangleBatch torusBatch;
// Set up the viewport and the projection matrix
//设置视图和投影矩阵
void ChangeSize(int w, int h)
{
// Prevent a divide by zero
//防止h变为0
if(h == 0)
h = 1;
// Set Viewport to window dimensions
//设置视口窗口尺寸
glViewport(0, 0, w, h);
//SetPerspective函数的参数是一个从顶点方向看去的视场角度(用角度值表示)
//宽度和高度的比值和从近剪切面到原件切面的距离
viewFrustum.SetPerspective(35.0f, float(w)/float(h), 1.0f, 1000.0f);
}
// Called to draw scene
//调用场景
void RenderScene(void)
{
// Set up time based animation
//设置时间为基础的动画
static CStopWatch rotTimer;
float yRot = rotTimer.GetElapsedSeconds() * 60.0f;
// Clear the window and the depth buffer
//清除窗口和深度缓冲区
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Matrix Variables
//矩阵变量
M3DMatrix44f mTranslate, mRotate, mModelview, mModelViewProjection;
// Create a translation matrix to move the torus back and into sight
//创建一个平移矩阵来移动这个圆环面
m3dTranslationMatrix44(mTranslate, 0.0f, 0.0f, -2.5f);
// Create a rotation matrix based on the current value of yRot
//创建一个基于yrot值的旋转矩阵
m3dRotationMatrix44(mRotate, m3dDegToRad(yRot), 0.0f, 1.0f, 0.0f);
// Add the rotation to the translation, store the result in mModelView
//加上旋转的位移,结果存储在mmodelview
m3dMatrixMultiply44(mModelview, mTranslate, mRotate);
// Add the modelview matrix to the projection matrix,
// the final matrix is the ModelViewProjection matrix.
//添加模型视图矩阵的投影矩阵, 最后的矩阵是modelviewprojection矩阵。
m3dMatrixMultiply44(mModelViewProjection, viewFrustum.GetProjectionMatrix(),mModelview);
// Pass this completed matrix to the shader, and render the torus
//把这个已完成的矩阵传递给着色,并渲染这个圆环面
GLfloat vBlack[] = { 0.0f, 0.0f, 0.0f, 1.0f };
shaderManager.UseStockShader(GLT_SHADER_FLAT, mModelViewProjection, vBlack);
torusBatch.Draw();
// Swap buffers, and immediately refresh
//交换缓冲区,并立即刷新
glutSwapBuffers();
glutPostRedisplay();
}
// This function does any needed initialization on the rendering
// context.
//此函数在渲染上下文中需要初始化任何初始化。
void SetupRC()
{
// Black background
glClearColor(0.8f, 0.8f, 0.8f, 1.0f );
glEnable(GL_DEPTH_TEST);
shaderManager.InitializeStockShaders();
// This makes a torus
gltMakeTorus(torusBatch, 0.4f, 0.15f, 30, 30);
//用于控制多边形的显示方式
//表示物体的所有面向面用线段显示
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
}
///////////////////////////////////////////////////////////////////////////////
// Main entry point for GLUT based programs
int main(int argc, char* argv[])
{
gltSetWorkingDirectory(argv[0]);//设置当前工作目录
glutInit(&argc, argv);//传输命令行参数并初始化GLUT库
//使用双缓冲窗口和使用RGBA颜色模式
//GLUT_DEPTH位标志将一个深度缓冲区分配为显示的一部分,因此我们可以执行深度测试
// GLUT_STENCIL确保我们也会有一个可用的模板缓冲区
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH | GLUT_STENCIL);
glutInitWindowSize(800, 600);//窗口大小
glutCreateWindow("ModelViewProjection Example");//窗口标题
glutReshapeFunc(ChangeSize);//改变窗口大小的回调函数
glutDisplayFunc(RenderScene);//OpenGL渲染代码
//初始化glew库
GLenum err = glewInit();
if (GLEW_OK != err) {
fprintf(stderr, "GLEW Error: %s\n", glewGetErrorString(err));
return 1;
}
SetupRC();//RC代表渲染环境(Rendering Context)
glutMainLoop();//主消息循环
return 0;
}
运行结果:
ModelviewProjection