准备知识

伸缩变换非常简单,它的目的是增大或者缩小对象的尺寸。例如:你可能希望用同一个模型创建不同大小的对象(例如形状相同,但大小不同的树木)或者你想改变对象的大小使它和游戏场景匹配。这些例子中你可能需要X、Y、Z三个坐标轴缩放相同的量,但有时候我们只需要沿着一个或者两个轴缩放使模型变“粗”或变“细”。

缩放变换矩阵形式:



(注:原文没有给出缩放变换矩阵一般形式,此处为本人添加,s1,s2,s3分别为三个轴上的缩放比例)

程序代码

  1. /*
  2. Copyright 2010 Etay Meiri
  3. This program is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation, either version 3 of the License, or
  6. (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program. If not, see <http://www.gnu.org/licenses/>.
  13. Tutorial 08 - Scaling Transformation
  14. */
  15. #include "stdafx.h"
  16. #include <stdio.h>
  17. #include <string.h>
  18. #include <assert.h>
  19. #include <math.h>
  20. #include <GL/glew.h>
  21. #include <GL/freeglut.h>
  22. #include "ogldev_math_3d.h"
  23. GLuint VBO;
  24. GLuint gWorldLocation;
  25. const char* pVSFileName = "shader.vs";
  26. const char* pFSFileName = "shader.fs";
  27. static void RenderSceneCB()
  28. {
  29. glClear(GL_COLOR_BUFFER_BIT);
  30. static float Scale = 0.0f;
  31. Scale += 0.001f;
  32. Matrix4f World;
  33. World.m[0][0] = sinf(Scale) ; World.m[0][1] = 0.0f ; World.m[0][2] = 0.0f; World.m[0][3] = 0.0f;
  34. World.m[1][0] = 0.0f ; World.m[1][1] = sinf(Scale); World.m[1][2] = 0.0f; World.m[1][3] = 0.0f;
  35. World.m[2][0] = 0.0f; ; World.m[2][1] = 0.0f; ; World.m[2][2] = sinf(Scale); World.m[2][3] = 0.0f;
  36. World.m[3][0] = 0.0f; ; World.m[3][1] = 0.0f; ; World.m[3][2] = 0.0f; World.m[3][3] = 1.0f;
  37. glUniformMatrix4fv(gWorldLocation, 1, GL_TRUE, &World.m[0][0]);
  38. glEnableVertexAttribArray(0);
  39. glBindBuffer(GL_ARRAY_BUFFER, VBO);
  40. glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
  41. glDrawArrays(GL_TRIANGLES, 0, 3);
  42. glDisableVertexAttribArray(0);
  43. glutSwapBuffers();
  44. }
  45. static void InitializeGlutCallbacks()
  46. {
  47. glutDisplayFunc(RenderSceneCB);
  48. glutIdleFunc(RenderSceneCB);
  49. }
  50. static void CreateVertexBuffer()
  51. {
  52. Vector3f Vertices[3];
  53. Vertices[0] = Vector3f(-1.0f, -1.0f, 0.0f);
  54. Vertices[1] = Vector3f(1.0f, -1.0f, 0.0f);
  55. Vertices[2] = Vector3f(0.0f, 1.0f, 0.0f);
  56. glGenBuffers(1, &VBO);
  57. glBindBuffer(GL_ARRAY_BUFFER, VBO);
  58. glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW);
  59. }
  60. static void AddShader(GLuint ShaderProgram, const char* pShaderText, GLenum ShaderType)
  61. {
  62. GLuint ShaderObj = glCreateShader(ShaderType);
  63. if (ShaderObj == 0) {
  64. fprintf(stderr, "Error creating shader type %d\n", ShaderType);
  65. exit(1);
  66. }
  67. const GLchar* p[1];
  68. p[0] = pShaderText;
  69. GLint Lengths[1];
  70. Lengths[0]= strlen(pShaderText);
  71. glShaderSource(ShaderObj, 1, p, Lengths);
  72. glCompileShader(ShaderObj);
  73. GLint success;
  74. glGetShaderiv(ShaderObj, GL_COMPILE_STATUS, &success);
  75. if (!success) {
  76. GLchar InfoLog[1024];
  77. glGetShaderInfoLog(ShaderObj, 1024, NULL, InfoLog);
  78. fprintf(stderr, "Error compiling shader type %d: '%s'\n", ShaderType, InfoLog);
  79. exit(1);
  80. }
  81. glAttachShader(ShaderProgram, ShaderObj);
  82. }
  83. static void CompileShaders()
  84. {
  85. GLuint ShaderProgram = glCreateProgram();
  86. if (ShaderProgram == 0) {
  87. fprintf(stderr, "Error creating shader program\n");
  88. exit(1);
  89. }
  90. string vs, fs;
  91. if (!ReadFile(pVSFileName, vs)) {
  92. exit(1);
  93. };
  94. if (!ReadFile(pFSFileName, fs)) {
  95. exit(1);
  96. };
  97. AddShader(ShaderProgram, vs.c_str(), GL_VERTEX_SHADER);
  98. AddShader(ShaderProgram, fs.c_str(), GL_FRAGMENT_SHADER);
  99. GLint Success = 0;
  100. GLchar ErrorLog[1024] = { 0 };
  101. glLinkProgram(ShaderProgram);
  102. glGetProgramiv(ShaderProgram, GL_LINK_STATUS, &Success);
  103. if (Success == 0) {
  104. glGetProgramInfoLog(ShaderProgram, sizeof(ErrorLog), NULL, ErrorLog);
  105. fprintf(stderr, "Error linking shader program: '%s'\n", ErrorLog);
  106. exit(1);
  107. }
  108. glValidateProgram(ShaderProgram);
  109. glGetProgramiv(ShaderProgram, GL_VALIDATE_STATUS, &Success);
  110. if (!Success) {
  111. glGetProgramInfoLog(ShaderProgram, sizeof(ErrorLog), NULL, ErrorLog);
  112. fprintf(stderr, "Invalid shader program: '%s'\n", ErrorLog);
  113. exit(1);
  114. }
  115. glUseProgram(ShaderProgram);
  116. gWorldLocation = glGetUniformLocation(ShaderProgram, "gWorld");
  117. assert(gWorldLocation != 0xFFFFFFFF);
  118. }
  119. int _tmain(int argc, _TCHAR* argv[])
  120. {
  121. glutInit(&argc, argv);
  122. glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGBA);
  123. glutInitWindowSize(1024, 768);
  124. glutInitWindowPosition(100, 100);
  125. glutCreateWindow("Tutorial 08");
  126. InitializeGlutCallbacks();
  127. // Must be done after glut is initialized!
  128. GLenum res = glewInit();
  129. if (res != GLEW_OK) {
  130. fprintf(stderr, "Error: '%s'\n", glewGetErrorString(res));
  131. return 1;
  132. }
  133. printf("GL version: %s\n", glGetString(GL_VERSION));
  134. glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
  135. CreateVertexBuffer();
  136. CompileShaders();
  137. glutMainLoop();
  138. return 0;
  139. }

代码解读

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

其余代码和上节相同,这里我们把变换矩阵s1,s2,s3的值指定为sinf(Scale),其值域为[-1,1]你将会看到图形一会变大一会变小。

运行效果

编译运行可以看到三角形大小不断改变。

OpenGL编程逐步深入(八)伸缩变换的更多相关文章

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

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

  2. VS15 openGL 编程指南 配置库 triangle例子

    最近去图书馆借了一本书<OpenGL编程指南(原书第八版)>,今天倒腾了一天才把第一个例子运行出来. 所以,给大家分享一下,希望能快速解决配置问题. 一.下载需要的库文件 首先,我们需要去 ...

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

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

  4. C#编程总结(八)数字签名

    C#编程总结(八)数字签名 在日常工作中,有很多文件需要领导审阅.签名和盖章,由于公司业务开展,跨地域.跨国业务也日益普遍,领导签名盖章变得很麻烦,开始的时候人们通过邮寄.传真等方式来解决,但是耗费时 ...

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

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

  6. IOS编程教程(八):在你的应用程序添加启动画面

    IOS编程教程(八):在你的应用程序添加启动画面   虽然你可能认为你需要编写闪屏的代码,苹果已经可以非常轻松地把它做在Xcode中.不需要任何编码.你只需要做的是设置一些配置. 什么是闪屏 对于那些 ...

  7. 用MFC实现OpenGL编程

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

  8. [转]VS 2012环境下使用MFC进行OpenGL编程

    我就不黏贴复制了,直接给出原文链接:VS 2012环境下使用MFC进行OpenGL编程 其它好文链接: 1.OpenGL系列教程之十二:OpenGL Windows图形界面应用程序

  9. Win32 OpenGL 编程( 1 ) Win32 下的 OpenGL 编程必须步骤

    http://blog.csdn.net/vagrxie/article/details/4602961 Win32 OpenGL 编程( 1 ) Win32 下的 OpenGL 编程必须步骤 wri ...

  10. OpenGL编程(一)渲染一个指定颜色的背景窗口

    上次已经搭好了OpenGL编程的环境.已经成功运行了第一个程序.可只是照搬书上的代码,并没弄懂其中的原理.这次通过一个小程序来解释使用GLUT库编写OpenGL程序的过程. 程序的入口 与其他程序一样 ...

随机推荐

  1. 【BZOJ3270】博物馆 概率DP 高斯消元

    链接: #include <stdio.h> int main() { puts("转载请注明出处[辗转山河弋流歌 by 空灰冰魂]谢谢"); puts("网 ...

  2. 【手势交互】9. PS Move

    索尼研发体感控制技术已有10年,在过去那么多年里.尝试了3D摄像头.超声波和电磁感应等各种技术.最后还是觉得眼下的MOVE所使用的技术最为合适.PS Move是索尼于2010年9月份推出.用来让PS3 ...

  3. C#高级编程五十八天----并行集合

    并行集合 对于并行任务,与其相关紧密的就是对一些共享资源,数据结构的并行訪问.常常要做的就是对一些队列进行加锁-解锁,然后运行类似插入,删除等等相互排斥操作. .NET4提供了一些封装好的支持并行操作 ...

  4. svn创建分支的做法

    作者:朱金灿 来源:http://blog.csdn.net/clever101 1.  首先选择你要创建分支的工作目录,如下图: 2.选择要创建分支的路径.注释以及版本,选择HEADrevision ...

  5. POJ 2367 Genealogical tree【拓扑排序】

    题意:大概意思是--有一个家族聚集在一起,现在由家族里面的人讲话,辈分高的人先讲话.现在给出n,然后再给出n行数 第i行输入的数表示的意思是第i行的子孙是哪些数,然后这些数排在i的后面. 比如样例 5 ...

  6. 封装cookie的获取,设置与查找

    //获取cookiefunction getCookie(key,value){ var c = document.cookie; var str = key + '=' + value; var r ...

  7. HDU Integer's Power(容斥原理)

    题意 求[l,r]的最大指数和(1<=l,r<=10^18) 最大指数和(如64=8^2=4^3=2^6,所以64的最大指数和是6) 题解 很明显我们可以先求出[1,n]的最大指数和,然后 ...

  8. 永远不要在MySQL中使用“utf8”

    最近我遇到了一个 bug,我试着通过 Rails 在以“utf8”编码的 MariaDB 中保存一个 UTF-8 字符串,然后出现了一个离奇的错误: Incorrect string value: ‘ ...

  9. Ubuntu16.04 lnmp 环境搭建

    Ubuntu16.04 lnmp 环境搭建 nginx 安装 sudo apt-add-repository ppa:nginx/stablesudo apt-add-repository ppa:o ...

  10. 紫书 习题 11-1 UVa 821 (Floyd)

    水题, Floyd一遍就完了. #include<cstdio> #include<algorithm> #define REP(i, a, b) for(int i = (a ...