准备知识

这一节我们来看一下旋转变换。旋转变换指的是给我们一个指点的点和角度,我们需要绕着过该点的轴线將对象旋转对应的角度。这里我们只改变X/Y/Z中的两个分量,第三个分量保持不变。这意味着我们的图形只在三个平面内旋转:XY平面(绕着Z轴)、YZ平面(绕着X轴)、XZ(绕着Y轴)。还有更复杂的旋转方式这里我们暂时用不到。

我们来概括性的定义这个问题。考虑下面这样的图形:

我们需要沿着圆把点(x1,y2)移动到(x2,y2),换句话说就是把(x1,y1)旋转a2角度。我们假定圆的半径为1,则有:

使用正余弦展开公式:

可得:

在上面的图形中,Z轴垂直于屏幕,XY平面和屏幕重合。和平移变换一样,我们4x4阶矩阵和顶点分量矩阵乘积的形式表示该变换,可以写成:

绕Y轴选择可以用以下形式表示:

绕X轴旋转:

上面的4x4阶矩阵就是我们的旋转变换矩阵。

程序代码

/*

    Copyright 2010 Etay Meiri

    This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. Tutorial 07 - Rotation transformation
*/
#include "stdafx.h"
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <math.h>
#include <GL/glew.h>
#include <GL/freeglut.h>
#include "ogldev_math_3d.h"
GLuint VBO;
GLuint gWorldLocation; const char* pVSFileName = "shader.vs";
const char* pFSFileName = "shader.fs"; static void RenderSceneCB()
{
glClear(GL_COLOR_BUFFER_BIT); static float Scale = 0.0f; Scale += 0.001f; Matrix4f World; World.m[0][0] = cosf(Scale); World.m[0][1] = -sinf(Scale); World.m[0][2] = 0.0f; World.m[0][3] = 0.0f;
World.m[1][0] = sinf(Scale); World.m[1][1] = cosf(Scale); World.m[1][2] = 0.0f; World.m[1][3] = 0.0f;
World.m[2][0] = 0.0f; World.m[2][1] = 0.0f; World.m[2][2] = 1.0f; World.m[2][3] = 0.0f;
World.m[3][0] = 0.0f; World.m[3][1] = 0.0f; World.m[3][2] = 0.0f; World.m[3][3] = 1.0f; glUniformMatrix4fv(gWorldLocation, 1, GL_TRUE, &World.m[0][0]); glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); glDrawArrays(GL_TRIANGLES, 0, 3); glDisableVertexAttribArray(0); glutSwapBuffers();
} static void InitializeGlutCallbacks()
{
glutDisplayFunc(RenderSceneCB);
glutIdleFunc(RenderSceneCB);
} static void CreateVertexBuffer()
{
Vector3f Vertices[3];
Vertices[0] = Vector3f(-1.0f, -1.0f, 0.0f);
Vertices[1] = Vector3f(1.0f, -1.0f, 0.0f);
Vertices[2] = 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 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(1);
} 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);
}
string vs, fs; if (!ReadFile(pVSFileName, vs)) {
exit(1);
}; if (!ReadFile(pFSFileName, fs)) {
exit(1);
}; AddShader(ShaderProgram, vs.c_str(), GL_VERTEX_SHADER);
AddShader(ShaderProgram, fs.c_str(), 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 _tmain(int argc, _TCHAR* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGBA);
glutInitWindowSize(1024, 768);
glutInitWindowPosition(100, 100);
glutCreateWindow("Tutorial 07"); InitializeGlutCallbacks(); // Must be done after glut is initialized!
GLenum res = glewInit();
if (res != GLEW_OK) {
fprintf(stderr, "Error: '%s'\n", glewGetErrorString(res));
return 1;
} printf("GL version: %s\n", glGetString(GL_VERSION)); glClearColor(0.0f, 0.0f, 0.0f, 0.0f); CreateVertexBuffer(); CompileShaders(); glutMainLoop(); return 0;
}

代码解读

这里我们只把矩阵改成旋转变换矩阵,其余代码和上节相同。

World.m[0][0]=cosf(Scale); World.m[0][1]=-sinf(Scale); World.m[0][2]=0.0f; World.m[0][3]=0.0f;
World.m[1][0]=sinf(Scale); World.m[1][1]=cosf(Scale); World.m[1][2]=0.0f; World.m[1][3]=0.0f;
World.m[2][0]=0.0f; World.m[2][1]=0.0f; World.m[2][2]=1.0f; World.m[2][3]=0.0f;
World.m[3][0]=0.0f; World.m[3][1]=0.0f; World.m[3][2]=0.0f; World.m[3][3]=1.0f;

运行效果

可以看到三角形在屏幕上不停旋转。

OpenGL编程逐步深入(七)旋转变换的更多相关文章

  1. 《OpenGL编程指南第七版》学习——编译时提示“error C2381: “exit” : 重定义;__declspec(noreturn) 不同”错误的解决办法

    解决办法一. #if defined(_WIN32) # ifndef GLUT_BUILDING_LIBextern _CRTIMP void __cdecl exit(int); 上面是glut. ...

  2. opengl编程指南 第七版 源代码bug Page35 lines.c 红宝书

    问题1:根据源代码时,我发现的时候去敲门.不正确实施效果.哪里是不正确?没有源代码glPushAttrib(GL_LINE_STIPPLE) glPopAttrib().所以会出现最后的下一次抽奖提供 ...

  3. OpenGL编程指南(第七版)

    OpenGL编程指南(第七版) 转自:http://blog.csdn.net/w540982016044/article/details/21287645 在接触OpenGL中,配置显得相当麻烦,特 ...

  4. 编译opengl编程指南第八版示例代码通过

    最近在编译opengl编程指南第八版的示例代码,如下 #include <iostream> #include "vgl.h" #include "LoadS ...

  5. C#编程总结(七)数据加密——附源码

    C#编程总结(七)数据加密——附源码 概述 数据加密的基本过程就是对原来为明文的文件或数据按某种算法进行处理,使其成为不可读的一段代码,通常称为“密文”,使其只能在输入相应的密钥之后才能显示出本来内容 ...

  6. 在 Mac OS X Yosemite 10.10.5 上配置 OpenGL 编程环境

    这个教程主要参考了youtube上的视频 Getting Started in OpenGL with GLFW/GLEW in Xcode 6 ,这个视频有点问题,不能照搬.本人通过自己摸(瞎)索( ...

  7. 用MFC实现OpenGL编程

    一.OpenGL简介 众所周知,OpenGL原先是Silicon Graphics Incorporated(SGI公司)在他们的图形工作站上开发高质量图像的接口.但最近几年它成为一个非常优秀的开放式 ...

  8. cesium编程入门(七)3D Tiles,模型旋转

    cesium编程入门(七)3D Tiles,模型旋转 上一节介绍了3D Tiles模型的位置移动,和贴地的操作,这一节来聊一聊模型的旋转, 参考<WebGl编程指南>的第四章 假设在X轴和 ...

  9. 解读经典《C#高级编程》第七版 Page79-93.对象和类型.Chapter3

    前言 本篇我们继续讲解本章其余的部分:构造函数.只读字段.匿名类型.结构详解.部分类.静态类.Object类.扩展方法,等. 01 类 构造函数 构造函数是一种特殊的方法: 与类同名 没有返回值,甚至 ...

  10. 解读经典《C#高级编程》第七版 Page68-79.对象和类型.Chapter3

    前言 新年好,本篇开始进入第三章,<对象和类型>,深刻理解C#的对象,对于使用好.Net类库非常重要. 01 类和结构 从使用角度看,结构和类的区别很小,比如,将结构定义转换为类,只需要将 ...

随机推荐

  1. JBoss AS 7之文件夹结构(The Return Of The King)

    1.2 JBoss As 7体系结构 以下介绍一下JBoss的体系结构,详细的文件夹结构. 假设熟悉曾经JBoss版本号的人,一定会发现JBoss AS 7与之前的JBoss的文件夹结构有了非常大的不 ...

  2. ZooKeeper伪集群环境搭建

    1.从官网下载程序包. 2.解压. [dev@localhost software]$ tar xzvf zookeeper-3.4.6.tar.gz 3.进入zookeeper文件夹后创建data文 ...

  3. Java -- XML解析工具dom4j

    前言 XML现已成为一种通用的数据交流方式,它的平台无关性.语言无关性.系统无关性.给数据集成与交互带来了极大的方便,对于XML的解析有四种方式:DOM生成和解析XML文档,SAX生成和解析XML文件 ...

  4. ThinkPHP5.0框架开发--第5章 TP5.0 控制器

    ThinkPHP5.0框架开发--第5章 TP5.0 控制器 第5章 TP5.0 控制器 ============================================== 上次复习 1.路 ...

  5. ThinkPHP5.0最最最最最简单实例

    ThinkPHP5.0最最最最最简单实例 一.效果图 二.操作步骤 1.用mysql数据库建立数据库 2.按照ThinkPHP官网的指示装好ThinkPHP5.0 tp5里面的目录结构如下: 3.配置 ...

  6. 10.ref regex unordered_set smartpoint

    ref引用不可以复制的对象 void print(std::ostream &os, int i) { os << i << endl; } //ref引用不可以复制的 ...

  7. BZOJ 2190 欧拉函数

    思路: 递推出来欧拉函数 搞个前缀和 sum[n-1]*2+3就是答案 假设仪仗队是从零开始的 视线能看见的地方就是gcd(x,y)=1的地方 倒过来一样 刨掉(1,1) 就是ans*2+1 再加一下 ...

  8. Kettle学习系列之数据仓库、数据整合、ETL、ELT和EII之间的区别?

    不多说,直接上干货! 在数据仓库领域里,的一个重要概念就是数据整合(data intergration).数据整合它就是把不同数据库中的数据整合到一起,对外提供统一的数据视图. 数据整合最典型的案例就 ...

  9. http请求post,返回excel文件,并接收

    1.post的方法里要加responseType: 'arraybuffer'参数,不然下载的excel会乱码 2.使用{type: "application/vnd.ms-excel&qu ...

  10. 解决win8.1下sql配置iis的问题

    在配置iis8.5时,ISAPI和CGI限制中没有ASP.NET v4.0.30319, 所以要注册.net 4.0 注册方法为在“运行”中输入cmd,然后在命令行中输入: C:\WINDOWS\Mi ...