上回书说道有个reshape需要进一步讲解,这个函数功能是对用户改变窗口大小的操作进行一些重绘
的动作(类似VC中的OnResize)。其中用到了一些变换的概念我希望大家已经具备初步的计算机图形学的知识,这将有利于
这部分的理解。如果还没有,也没关系,我尽量讲解的通俗一些.
对于3D绘图,把其中3D坐标写成齐次坐标系后,是4*4的矩阵形式(详细可以参阅相关文献,后面也会讲到。)任何投影、旋转...操作都可以看
成是矩阵相乘的操作。矩阵操作----这个概念一定要形成!!
例如在2D中普通的旋转变换,可以写成:
|cosθ sinθ 0 |
[x' y' 1] =[x y 1] |-sinθ cosθ 0 |
|0 0 1 |
3D中道理完全一样,一个3D图形的显示包括下面步骤:
1.视点变换(将相机放在合适的地方对准3D景物)
2.模型变换(将3D物体放在合适的地方)
3.投影变换(将相机镜头调整,使3D景物投影在2D胶片上)
4.视口变换(决定胶片大小)
其中1、2并没有本质区别。
里面有几个关键性函数:
一 几何变换
1.
void glTranslated(
GLdouble x,
GLdouble y,
GLdouble z
);
void glTranslatef(
GLfloat x,
GLfloat y,
GLfloat z
);
目标沿X Y Z轴平移 x y z
2.
void glRotated(
GLdouble angle,
GLdouble x,
GLdouble y,
GLdouble z
);
void glRotatef(
GLfloat angle,
GLfloat x,
GLfloat y,
GLfloat z
);
目标分别以X Y Z轴为轴逆时针旋转 x y z
3.
void glScaled(
GLdouble x,
GLdouble y,
GLdouble z
);
void glScalef(
GLfloat x,
GLfloat y,
GLfloat z
);
目标在X Y Z 方向缩放,缩放因子为 x y z
二 投影变换
1.正射投影(即没有“近大远小”)
void glOrtho(GLdouble left,GLdouble right,GLdouble bottom,GLdouble top,
GLdouble near,GLdouble far)
创建一个平行视景体(的矩阵),即投射线是平行线,把第一个矩形视景投影到第二个矩形视景上。并用这个矩阵乘以当前矩阵,以完成变换。
近景第一个矩形的左上角三维空间坐标(left,bottom,-near),右下角的三维空间坐标(right,top,-near);远景第二个矩形左上角三维空间坐标(left,bottom,-far),右下角的三维空间
坐标(right,top,-far);
2.透射投影(“近大远小”)
void glFrustum(
GLdouble left,
GLdouble right,
GLdouble bottom,
GLdouble top,
GLdouble znear,
GLdouble zfar
);
创建一个型如棱台的视景体,其近截取面由left right bottom top znear确定,远截取面由从视点投影近截取面到Z轴zfar位置决定
三 视口变换
void glViewport(GLint x,GLint y,GLsize width,GLsize height);
这个函数定义一个视口,x和y是视口在屏幕窗口坐标系中左上坐标缺省是(0,0)。width height是宽和高。
注意使用中视口长宽比例的调整会导致图象变形。因此reshape()中要检测窗口尺寸,修正视口大小,保证图象不变形。
附:
void glMatrixMode(GLenum mode );
把当前矩阵转换为指定的矩阵类型
这三个函数的利用见例子中的中文说明:
////////////////////////////////////////////////////////////
//sample.cpp
#include "windows.h"
#include <gl/gl.h>
#include <gl/glu.h>
#include <gl/glaux.h>
#pragma comment(lib, "OpenGl32.lib")
#pragma comment(lib, "glu32.lib")
#pragma comment(lib, "glaux.lib")
void myinit(void);
void CALLBACK display(void);
void CALLBACK reshape(GLsizei w,GLsizei h);
/////////////////////////////////////////////////////////////
void myinit(void)
{
/*初始化:*/
auxInitDisplayMode(AUX_SINGLE|AUX_RGBA);
//窗口显示单缓存和RGB(彩色)模式
auxInitPosition(0,0,500,500);
//大小x=500 y=500 (0,0)是屏幕左上点
auxInitWindow("sample1");
//窗口初始化,参数是标题
glClearColor(0.0,0.0,0.0,0.0);
//将窗口清为黑色
glClear(GL_COLOR_BUFFER_BIT);
//将颜色缓存清为glClearColor命令所设置的颜色
//即背景色
}
//////////////////////////////////////////////////
void CALLBACK reshape(GLsizei w,GLsizei h)
{
//设定视口X Y方向不要大于500单位
if(w<=500&&h<=500)
glViewport(0,0,w,h);
if(w>500&&h<=500)
glViewport(0,0,500,h);
if(w<=500&&h>500)
glViewport(0,0,w,500);
if(w>500&&h>500)
glViewport(0,0,500,500);
//进入世界坐标系,准备变换
//必要的步骤,初始化变换矩阵步骤: 1确定类型 2清成单位阵
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
//定义一个合适的视景体
if(w<=h)
glOrtho(-20.0,20.0,-20.0*(GLfloat)h/(GLfloat)w,
20.0*(GLfloat)h/(GLfloat)w,-50.0,50.0);
else
glOrtho(-20.0*(GLfloat)h/(GLfloat)w,
20.0*(GLfloat)h/(GLfloat)w,-20.0,20.0,-50.0,50.0);
//把变换结果返回视点坐标系
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
//////////////////////////////////////
//画三棱锥,功能同上一讲
void draw(void)
{
glBegin(GL_TRIANGLE_STRIP);
glColor3f(1.0,0.0,0.0);
glVertex3f(15.0,0.0,0.0);
glColor3f(0.0,1.0,0.0);
glVertex3f(-15.0,0.0,0.0);
glColor3f(0.0,0.0,1.0);
glVertex3f(0.0,15.0,15.0);
//
glColor3f(0.0,1.0,1.0);
glVertex3f(10.0,15.0,-15.0);
//
glColor3f(1.0,1.0,0.0);
glVertex3f(15.0,0.0,0.0);
//
glEnd();
}
////////////////////////////////////////
void CALLBACK display(void)
{
//按上个例子中方法画第一个三棱锥
glClearColor(0.0,0.0,0.0,1.0);
glClear(GL_COLOR_BUFFER_BIT);
glLoadIdentity();
glTranslatef(0.0,0.0,-25.0);
draw();
//开始画第二个三棱锥
//变换开始,清变换矩阵为单位阵
glLoadIdentity();
//先沿X Y Z平移-5 -10 -4,屏幕上看就是向左下移动
//Z方向由于是平行投影,没有“近大远小”所以看不出效果
glTranslatef(-5.0,-10.0,-4.0);
//再沿Z轴转90度
glRotatef(90,0.0,0.0,1.0);
draw();
//绘图工作完成,强制绘图结束
glFlush();
}
void main(void)
{
myinit();
auxReshapeFunc(reshape);
auxMainLoop(display);
}
//sample ends here
/////////////////////
如果大家运行一下就知道上述函数的作用,无非是把物体移动、转动、变形缩放、透视...
我想有了前3讲,OPENGL的基本原理已经如此了它就是提供了一个标准的计算机图形学所使用的数学模型到显示的接口,
只要具备图形学知识,掌握OPENGL API函数使用,绘图很EASY啦
基础部分已经完毕,慢慢再来谈高级一些的绘图功能如:
纹理、光源、动画...
真诚希望大家提提意见和高论 :)
分享到:
相关推荐
openGL 各种坐标矩阵变换
这是一篇opengl坐标转换的文章,共享下吧。
从屏幕坐标向OpenGL坐标要经过两步,第一步是屏幕坐标向视景体坐标转换,第二步是视景体坐标向OpenGL坐标转换。 参考资料:http://chiefman.blog.hexun.com/5400795_d.html
1.OpenGL坐标系讲解 2.openGL几何变换与Windows屏幕坐标转换 3.OpenGL中关于坐标使用常见问题的分析
OpenGL 有一个限制——在同一个绘制过程中,相同的缓存不能同时作为输入和输出。这意味着如果我们想要在一个顶点缓冲区中更新粒子,我们实际上需要两个 transform feedback 缓存并在它们之间进行切换。在第 N 帧的...
在OpenGL中,一切事物都在3D空间中,但我们的屏幕坐标确实2D像素数组,OpenGL大部分工作就是把3D坐标转换成适应屏幕的2D像素。
OpenGL之坐标转换
opengl画图时,会涉及到坐标变换,此实例会有很好的帮助。
利用OpenGL实现屏幕坐标与世界坐标的相互变换
高手写的opengl的简介,感觉他写的很好!
详细信息请参考:http://blog.csdn.net/u013985004/article/details/40372527
OpenGL通过相机模拟可以实现计算机图形学中最基本的三维变换,即几何变换、投影变换、裁剪变换、视口变换等,同时,OpenGL还实现了矩阵堆栈等。 为了使被显示的三维物体数字化,要在被显示的物体所在的空间中定义一...
屏幕坐标到opengl坐标体系的转换。详细介绍opengl的原理。
基于OpenGL视点坐标系的平移旋转变换,杨艳英,王哲龙,本文基于OpenGL视点坐标系与世界坐标系的相互对应关系,利用视点变换原理实现对三维图形的平移和旋转。并提出一种新的三维图形旋转
OpenGL通过相机模拟、可以实现计算机图形学中最基本的三维变换,即几何变换、投影变换、裁剪变换、视口变换等,同时,OpenGL还实现了矩阵堆栈等。理解掌握了有关坐标变换的内容,就算真正走进了精彩地三维世界。
OpenGL坐标变换及其数学原理,两种摄像机交互模型(附源程序)-附件资源
简单的opengl窗口,绘制了一个矩形并增添了纹理和坐标变换的操作选择。
详解OpenGL的坐标系、投影和几何变换
OpenGL 与W indow s 窗口使用不同的坐标系统, 但是在进行基于OpenGL 的具有灵活和复杂图形人 机交互的系统开发时, 不可避免地要面临坐标转换的问题。为此结合军标系统项目的开发, 采用理论和实践相 结合的方法, 首先...
OpenGL之坐标转换.pdf