OpenGL编程逐步深入(八)伸缩变换
准备知识
伸缩变换非常简单,它的目的是增大或者缩小对象的尺寸。例如:你可能希望用同一个模型创建不同大小的对象(例如形状相同,但大小不同的树木)或者你想改变对象的大小使它和游戏场景匹配。这些例子中你可能需要X、Y、Z三个坐标轴缩放相同的量,但有时候我们只需要沿着一个或者两个轴缩放使模型变“粗”或变“细”。
缩放变换矩阵形式:
(注:原文没有给出缩放变换矩阵一般形式,此处为本人添加,s1,s2,s3分别为三个轴上的缩放比例)
程序代码
/*
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 08 - Scaling 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] = sinf(Scale) ; World.m[0][1] = 0.0f ; World.m[0][2] = 0.0f; World.m[0][3] = 0.0f;
World.m[1][0] = 0.0f ; World.m[1][1] = sinf(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] = sinf(Scale); 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 08");
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]=sinf(Scale); World.m[0][1]=0.0f; World.m[0][2]=0.0f; World.m[0][3]=0.0f;
World.m[1][0]=0.0f; World.m[1][1]=sinf(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]=sinf(Scale); 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;
其余代码和上节相同,这里我们把变换矩阵s1,s2,s3的值指定为sinf(Scale),其值域为[-1,1]你将会看到图形一会变大一会变小。
运行效果
编译运行可以看到三角形大小不断改变。
OpenGL编程逐步深入(八)伸缩变换的更多相关文章
- 编译opengl编程指南第八版示例代码通过
最近在编译opengl编程指南第八版的示例代码,如下 #include <iostream> #include "vgl.h" #include "LoadS ...
- VS15 openGL 编程指南 配置库 triangle例子
最近去图书馆借了一本书<OpenGL编程指南(原书第八版)>,今天倒腾了一天才把第一个例子运行出来. 所以,给大家分享一下,希望能快速解决配置问题. 一.下载需要的库文件 首先,我们需要去 ...
- OpenGL编程指南(第七版)
OpenGL编程指南(第七版) 转自:http://blog.csdn.net/w540982016044/article/details/21287645 在接触OpenGL中,配置显得相当麻烦,特 ...
- C#编程总结(八)数字签名
C#编程总结(八)数字签名 在日常工作中,有很多文件需要领导审阅.签名和盖章,由于公司业务开展,跨地域.跨国业务也日益普遍,领导签名盖章变得很麻烦,开始的时候人们通过邮寄.传真等方式来解决,但是耗费时 ...
- 在 Mac OS X Yosemite 10.10.5 上配置 OpenGL 编程环境
这个教程主要参考了youtube上的视频 Getting Started in OpenGL with GLFW/GLEW in Xcode 6 ,这个视频有点问题,不能照搬.本人通过自己摸(瞎)索( ...
- IOS编程教程(八):在你的应用程序添加启动画面
IOS编程教程(八):在你的应用程序添加启动画面 虽然你可能认为你需要编写闪屏的代码,苹果已经可以非常轻松地把它做在Xcode中.不需要任何编码.你只需要做的是设置一些配置. 什么是闪屏 对于那些 ...
- 用MFC实现OpenGL编程
一.OpenGL简介 众所周知,OpenGL原先是Silicon Graphics Incorporated(SGI公司)在他们的图形工作站上开发高质量图像的接口.但最近几年它成为一个非常优秀的开放式 ...
- [转]VS 2012环境下使用MFC进行OpenGL编程
我就不黏贴复制了,直接给出原文链接:VS 2012环境下使用MFC进行OpenGL编程 其它好文链接: 1.OpenGL系列教程之十二:OpenGL Windows图形界面应用程序
- Win32 OpenGL 编程( 1 ) Win32 下的 OpenGL 编程必须步骤
http://blog.csdn.net/vagrxie/article/details/4602961 Win32 OpenGL 编程( 1 ) Win32 下的 OpenGL 编程必须步骤 wri ...
- OpenGL编程(一)渲染一个指定颜色的背景窗口
上次已经搭好了OpenGL编程的环境.已经成功运行了第一个程序.可只是照搬书上的代码,并没弄懂其中的原理.这次通过一个小程序来解释使用GLUT库编写OpenGL程序的过程. 程序的入口 与其他程序一样 ...
随机推荐
- 蓝桥杯 - 带分数 (DFS)
历届试题 带分数 时间限制:1.0s 内存限制:256.0MB 问题描写叙述 100 能够表示为带分数的形式:100 = 3 + 69258 / 714. 还能够表示为:10 ...
- mysql安装,数据库连接
安装教程http://jingyan.baidu.com/article/e3c78d64412ae83c4c85f5fd.html 首先打开MySQL官网,找到Downloads标签,点击进入.如果 ...
- html单行、多行文本溢出隐藏
欢迎加入前端交流群来py:749539640 单行: div{/* 单行溢出隐藏 */ width: 150px; white-space: nowrap; overflow: hidden; tex ...
- 【实战经验】64位Win7安装+32位Oracle + PL/SQL 解决方法
软件环境:64位win7.32位Oracle 10g. PL/SQL 9.0.4.1644 前言:以前开发用的都是32位系统,突然换到64位上,安装环境真的有点麻烦了,尤其对于PL/SQL只支持32位 ...
- linux批处理笔记
最近不得不用到Linux批处理,于是把要用到的程序反复研究了一下. #!/bin/bash是指此脚本使用/bin/bash来解释执行. -le -ge分别是小于和大于,这个倒是和latex里面的命令很 ...
- 阿里云ecs : Couldn't connect to host, port: smtp.aliyun.com, 25; timeout -1;
上传到服务器后javamail发邮件异常 链接 原来是ECS基于安全考虑,禁用了端口25. 改成465就可以发邮件了. p.setProperty("mail.smtp.socketFact ...
- 优动漫PAINT基础系列之图层模式
在绘画软件优动漫PAINT中,笔刷工具属性中的消除锯齿变成灰色无法选择了?铅笔绘制没有压感?快来改改图层模式~ 优动漫PAINT下载:http://www.dongmansoft.com/xiazai ...
- ccs元素分类 gcelaor
ccs元素的分类与特点 内联元素特点: 1.和其他元素都在一行上: 2.元素的高度.宽度及顶部和底部边距不可设置: 3.元素的宽度就是它包含的文字或图片的宽度,不可改变. inline-block 元 ...
- Linxu基本指令
一.Linux权限的概念 Linux下有两种用户:普通用户和超级用户(). 普通用户:在linux下做有限的事情: 超级用户:可以在linux系统下做任何事情,不受限制. 普通用户的提示符是“$”,超 ...
- vue-cli3+typescript+路由懒加载报错问题
vue-cli3的版本是3.4.1 出现的情况是网页显示正常,但是终端一直提示找不到模块: 如果去掉路由懒加载的方式,就没有报错: 原因是以前我们习惯直接写文件名而不加后缀, 现在使用ts时就需要写v ...