OpenGL编程.docx
- 文档编号:10005665
- 上传时间:2023-02-07
- 格式:DOCX
- 页数:152
- 大小:56.68KB
OpenGL编程.docx
《OpenGL编程.docx》由会员分享,可在线阅读,更多相关《OpenGL编程.docx(152页珍藏版)》请在冰豆网上搜索。
OpenGL编程
OPENGL编程类似C编程,实际接口就是C,所以熟悉C是必要的
一般编程可用到的函数库包括:
OPENGL实用库:
函数以glu开头
OPENGL辅助库:
函数以aux开头
Windows专用函数库:
函数以wgl开头
Win32API:
无专用前缀
OPENGL中有115个核心函数,可以在任何OPENGL平台上使用
OPENGL实用库比上面这115个函数高一级,提供高级调用
OPENGL辅助库本来是提供初学者入门的函数,不保证在任何平台的使用
但恰好可以在WIN32下使用,所以本讲座将大量引用
WIN32下OPENGL编程有两个方便途径:
1使用辅助库
2使用C++基于消息驱动的编程
显然1要简单一些,入门从这里开始吧。
[用之前的准备]
1
首先你需要下列*.lib包含在你的工程中:
opengl32.lib glu32.lib glaux.lib
本讲座所有例子“将”在VC5下调试通过,所以从
project->setting->link->general->object/libary modules
中加入上面三个*.lib
(这些LIB,VC4以上版本已经自带,加入即可,不用在四处搜寻文件)
2
另外在你的运行程序路径下或\win95\system\下你需要一些*.dll动态连接库
opengl32.dll glu32.dll rxddi.dll mga.drv
这里我将给出一个小例子让大家熟悉用辅助库的编程结构:
// GLOS.H
//////////////////////////////////////////////////////////
// This is an OS specific header file
//判别操作系统的基本头文件
#include
// disable data conversion warnings
#pragma warning(disable :
4244) // MIPS
#pragma warning(disable :
4136) // X86
#pragma warning(disable :
4051) // ALPHA
//////////////////////////////////////////////////////////
//opengl.cpp
//主程序
#include "glos.h"
#include
#include
#include "windows.h"
void main(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命令所设置的颜色
//即背景色
/*绘图*/
glColor3f(1.0,0.0,0.0);
//选颜色(R,G,B),参数0 glRectf(-0.5,-0.5,0.5,0.5); //画个方块 glFlush(); //强制绘图,不驻留缓存 _sleep(1000); //windows函数,显示1秒(单位是毫秒) } //end of sample 根据注释,应该看出程序功能: 显示红色方块(2D)一秒钟。 主程序结构不外乎: 初始化 + 绘图 + 其它功能调用 现在不用过分追究函数细节,知道是干什么的就可以乐,好吗? 我想结束本节前让大家实现第一个3D的例子,很简单而且好看的, 但是我们必须被迫不得不多学些东东: 1.OPENGL函数、变量命名准则 变量: 前缀 类型 对应C变量 b 8-bit int signed char s 16-bit int short i 32-bit int long f 32-bit float float d 64-bit float double ub 8-bit unsigned int unsigned char us 16-bit unsigned int unsigned short ui 32-bit unsigned int unsigned long 例如1.0f实际就是1.0,一般写成1.0f看上去好辨认一些。 函数: 函数参数类型作为函数后缀 例如: glVertex2i(2,4)表明是opengl基本函数(gl-) 是绘点的函数(-Vertex-) 是两个整型参数(-2i) 将来对一个函数掐头去尾就知道它是干什么的乐。 2.CALLBACK函数 是一些用来让系统调用的函数,系统要调用它们,例如显示、接受键盘输入... 你就好比擂积木一样把它们列在主程序初始化后(顺序一般无关紧要), 系统会自动执行它们,例如: void CALLBACK display(void)中你写好乐想画什么东东,然后主程序中使用 auxMainLoop(display);就可以让这个东东一直显示乐,很类似VC中的OnPaint() 3.OPENGL基本库的绘图方法 glBegin(类型); glColor3f(...); glVertex(...) glColor3f(...); glVertex(...); ... glEnd(); 先由“类型”指定画什么平面: GL_POINTS 单个顶点集 GL_LINES 多组线,2个点一条线 GL_GL_POLYGON 单个简单填充凸多边形 GL_TRAINGLES 多组三角型,3个点一个三角 ...用到在说吧(自己可以在VC HELP INDEX中查找) ////////////////////////////////////////////////////// //sample.cpp #include "glos.h" #include #include #include "windows.h" void myinit(void); void CALLBACK display(void); void CALLBACK reshape(GLsizei w,GLsizei h); //这里不用管reshape(),只是一个用于窗口改变大小时的处理 //与绘图无关,后面会讲到 //这里的重点是display(),请注意绘图的方法 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) { glViewport(0,0,w,h); 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 CALLBACK display(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(); glFlush(); } void main(void) { myinit(); auxReshapeFunc(reshape); auxMainLoop(display); } //end of sample 所谓连续填充就是1、2、3点组成三角1 2、3、4点组成三角2... 这里一共画乐3个向连接的彩色三角,组成乐一个由三个彩色平面 围成的空心三角椎... 上回书说道有个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 "glos.h" #include #include #include "windows.h" 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的编程基本结构描述完毕。 以后 会在这个基础上逐渐深化,不断增添新内容。 这一篇是讲述 键盘操作和动画基础(实际还差的远哪)。 只是个简单的能 由用户控制的动画,让物体前后移动,左右旋转。 是我们自 己的第一个QUAKE! 当然这个版本谁买谁上当,呵呵。 这篇的另一个目的就是加深前面对于CALLBACK函数的认识以 及对于变换的直观解释,任何变换你都可以从屏幕上通过自 己的操作看出来: 我只把和以前变化的部分标记中文解释 ///////////////////////
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- OpenGL 编程