OpenGL简介

是在SGI等多家世界闻名的计算机公司的倡导下,以SGI的GL三维图形库为基础制定的一个通用共享的开放式三维图形标准。是图形硬件的一个软件接口。

OpenGL特点

OpenGL是一个开放的三维图形软件包,它独立于窗口系统和操作系统,以它为基础开发的应用程序可以十分方便地在各种平台间移植。
OpenGL可以与Visual C++紧密接口,便于实现有关计算和图形算法,可保证算法的正确性和可靠性。
OpenGL使用简便,效率高。

vs环境下OpenGL函数库配置

加载glut库
把过glut32.lib拷贝到VC的安装目录下的lib文件夹中:如D:\Program Files\Microsoft Visual Studio\VC98\Lib
把glut.h拷贝到VC的安装目录下的Include\GL文件夹中:如:D:\Program Files\Microsoft Visual Studio\VC98\Include\GL
把glut32.dll拷贝到C:\WINDOWS\system32

OpenGL函数的命名规则

一般的函数命名如下:
<前缀><根函数><参数数目><参数类型>

前缀有gl、glu、aux、glut、wgl、glx、agl等等,分别表示该函数属于OpenGL那个开发库等。所谓开发库,要知道原生的OpenGL是跨平台的,跨平台意味着很多功能是无法实现的,比如说Windows和X-Window的窗口实现机制是不同的,OpenGL并不关心这些东西,只管画图。所以,OpenGL并没有窗口函数,比如无法创建窗口,无法获得输入……这些东西都需要其他的函数库来实现。用OpenGL常用的工具函数库来实现。

我们主要使用两种,一个是GLU库,它提供了比较基础的命令的封装,可以很简单的实现比较多的复杂功能;而另外一个就是GLUT,glut是不依赖于窗口平台的OpenGL工具包,目的是隐藏不同窗口平台API的复杂度,提供更为复杂的绘制功能,我们会大量的使用它。

OpenGL内部数据都是以float的形式存放的,如果使用double会对性能有一定的影响。


初始化窗口

glutInit() 是用glut来初始化OpenGL的,所有的问题都交给这个函数吧,基本不用管,虽说可以接受参数的,基本无用。

glutInitDisplayMode(MODE) 非常重要,这里告诉系统我们需要一个怎样显示模式。至于其参数GLUT_RGBA就是使用(red, green, blue)的颜色系统。有没有写错?这里有个A啊,不应该是(red, green, blue, alpha)么?大概是历史原因,GLUT_RGBA和GLUT_RGB是其实是等价的(坑爹啊),要想实现Alpha还得用其他的参数。而GLUT_SINGLE意味着所有的绘图操作都直接在显示的窗口执行,相对的,我们还有一个双缓冲的窗口,对于动画来说非常合适。

glutInitWindowSize(400, 400) 这个函数很容易理解,设置出现的窗口的大小。实际上还有个glutInitWindowPosition()也很常用,用来设置窗口出现的位置。

glutCreateWindow(“First”) ,一旦调用了,就出现一个窗口了,参数就是窗口的标题。

glutDisplayFunc(func) 是glut非常讨人喜欢的一个功能,它注册了一个函数,用来绘制OpenGL窗口,这个函数里就写着很多OpenGL的绘图操作等命令,也就是我们主要要学习的东西。

glutMainLoop() ,主循环,一旦调用了,我们的OpenGL就一直运行下去了。和很多程序中的主循环一样,不停的运行,画出即时的图像,处理输入等。


绘图

看看drawFunc里的几句话,这里是实际绘图的函数。

glClear(GL_COLOR_BUFFER_BIT) 是把先前的画面给清除,这基本是定律,每次重绘之前都要把原来的画面擦除,否则叠加起来什么都看不出了。glClear一看就知道是OpenGL原生的命令,而参数就是指明要清除的buffer。大家一定会有疑问,我们清除,不就是清除屏幕上的画面么,为什么还要指定?OpenGL的博大精深这里就体现出来了,buffer不仅仅有我们看到的那个GL_COLOR_BUFFER_BIT,OpenGL中还有其他的buffer类型,我们会在后面的章节讲到。

glutWireTeapot(0.5) 是glut提供的绘制犹他茶壶的工具函数,茶壶还是相当复杂的一个几何体,用这个函数一下子就画出来了,不过基本也就演示用用。这里是用的线模型,因为没有说光照和材质,如果glutSolidTeapot()画出来就成纸片儿了。

glFlush() 似乎不用多说,画了那么多,自然要刷新一下显示。不过,这里的刷新不仅仅是屏幕上的更新,实际上,它是处理OpenGL的渲染流水线,让所有排队中的命令得到执行。OpenGL的渲染流水线是一个很重要的概念,不过这里暂时还不打算多说明,否则对初学者来说,未免有些麻烦了。
glutSwapBuffers(); 交换缓冲区(使用双缓存GLUT_DOUBLE,必须交换缓存才能显示)


小惊喜

glutIdleFunc(Func) 又是一个激动人心的函数,可以让OpenGL在闲暇之余,调用一下注册的函数,这是是产生动画的绝好方法
gluLookAt(0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
//定义一个视图矩阵,并与当前矩阵相乘(实现漫游)

 void gluLookAt(GLdouble eyex, GLdouble eyey, GLdouble eyez, GLdouble centerx, GLdouble centery, GLdouble centerz, GLdouble upx, GLdouble upy, GLdouble upz);
该 函数定义一个视图 矩阵,并与当前矩阵相乘。
第一组eyex, eyey, eyez 相机在世界坐标的位置
第二组centerx, centery, centerz 相机镜头对准的物体在世界坐标的位置
第三组upx, upy, upz 相机向上的方向在世界坐标中的方向
你把相机想象成为你自己的脑袋:
第一组数据就是脑袋的位置
第二组数据就是眼睛看的物体的位置
第三组就是头顶朝向的方向(因为你可以歪着头看同一个物体)
OpenGL中维持着两套矩阵,一个是模型视图矩阵(model view matrix),另一个是投影矩阵(projection matrix)。
通过对OpenGL这两套矩阵的变换,我们可以得到各种投影效果

一些常用函数

glColor3f(1.0, 0.0, 0.0); //画笔红色
glutReshapeFunc(reshape); //窗口发生改变再渲染
glutMouseFunc(mouse);
glutMotionFunc(motion);
//处理当鼠标键摁下时,鼠标拖动的事件。当鼠标拖动时,将每一帧都调用一次这个函数 glLoadIdentity();
//重置当前模型观察矩阵

glPushMatrix();
//把刚刚的那个位置和角度保存进栈中(主要用于平移,旋转,缩放等)保存当前模型视图 glPopMatrix();
//根据保存的值恢复出位置,角度等 glRotatef(anglex, 1.0, 0.0, 0.0);
//以(x,y,z)向量为旋转轴旋转angle度 glScalef(1.0,1.0,1.0);
//每一点坐标分别乘以x,y,z倍(缩放)

glViewport(0, 0, (GLsizei)w, (GLsizei)h);
//负责把视景体截取的图像按照怎样的高和宽显示到屏幕上 glMatrixMode(GL_PROJECTION);
//设置当前矩阵模式:对投影矩阵应用随后的矩阵操作 与glLoadIdentity()一同使用
glLoadIdentity();
//重置当前模型观察矩阵:将当前的用户坐标系的原点移到了屏幕中心 >>gluPerspective(60.0, (GLfloat)w /(GLfloat)h, 1.0, 20.0);
//创建一个投影矩阵并且与当前矩阵相乘,得到的矩阵设定为当前变换,但要先通过glMatrixMode设定成投影矩阵才会得到想要的投影矩阵变换
glMatrixMode(GL_MODELVIEW);
//设置当前矩阵模式:对模型视景矩阵堆栈应用随后的矩阵操作 另GL_TEXTURE参数,是对纹理矩阵堆栈应用随后的矩阵操作
glLoadIdentity();
//重置当前模型观察矩阵:将当前的用户坐标系的原点移到了屏幕中心
gluLookAt(0.0, 0.0, 5.0, 0.0, 0.0,0.0, 0.0, 1.0, 0.0);`
//定义一个视图 与当阵相乘()


用OpenGL编写程序的模板基本模板

//主函数
int main(int argc, char* argv[])
{glutInit(&argc, argv);glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);        //设置显示模式(颜色、缓冲区等)glutCreateWindow(“A Simple Example”); //创建窗口SetupRC();                      //初始化渲染环境glutDisplayFunc(RenderScene);  //调用场景渲染函数glutReshapeFunc(ChangeSize);   //窗口发生变化glutMainLo();                  //程序开始事件处理}

几何图元的绘制

glBegin(GL_TRIANGLES);      //三角形
glVertex3f(0.0f,1.0f,0.0f);
glVertex3f(-1.0f,-1.0f,0.0f);
glVertex3f(1.0f,-1.0f,0.0f);
glEnd();
glBegin(GL_QUADS);           //四边形
glVertex3f(-1.0f,1.0f,0.0f);
glVertex3f(1.0f,1.0f,0.0f);
glVertex3f(1.0f,-1.0f,0.0f);
glVertex3f(-1.0f,-1.0f,0.0f);
glEnd();

下面是一个完整例子:

3D场景绘制2D透明缩放矩阵信息面板

#include <stdio.h>
#include <Windows.h>
#include <gl/glut.h>//输出模式,0-单缓存模式;非0双缓存模式
#define OUTPUT_MODE 1float scale = 0.0;
bool add = true;unsigned char axle = 'x';void init(void)
{//glClearColor函数设置好清除颜色,glClear利用glClearColor函数设置好的当前清除颜色设置窗口颜色glClearColor(1.0, 1.0, 0.8, 1.0);
}void display(void)
{printf("scale=%f, axle=%c\n", scale, axle);glClear(GL_COLOR_BUFFER_BIT);//配置缩放比例大小scalescale = (add ? scale + 0.1 : scale - 0.1);if (scale >= 2.0){add = false;}else if (scale <= 0.0) {add = true;}//开始绘画glPushMatrix();{if (axle == 'x') {glScalef(scale, 1, 1);}else if (axle == 'y') {glScalef(1, scale, 1);}else if (axle == 'z') {glScalef(1, 1, scale);}else {glScalef(scale, scale, scale);}glColor3f(1.0, 0.0, 1.0); //画笔梅红色glBegin(GL_POLYGON);glVertex2f(-0.2, -0.2);glVertex2f(-0.2, 0.2);glVertex2f(0.2, 0.2);glVertex2f(0.2, -0.2);glEnd();}glPopMatrix();glLoadIdentity();  //加载单位矩阵glColor3f(0.0, 0.0, 1.0); //画笔蓝色//--------画直线START--------//画直线glBegin(GL_LINES);glVertex2f(-0.5, 0);glVertex2f(0.5, 0);glVertex2f(0, 0.5);glVertex2f(0, -0.5);glEnd();//--------画直线E N D--------if (OUTPUT_MODE == 0) {glFlush();//单缓存GLUT_SINGLE时使用}else {glutSwapBuffers();//因为使用的是双缓存GLUT_DOUBLE,所以这里必须要交换缓存才会显示}Sleep(50);
}void reshape(int w, int h)
{int offset = 50;int dis = (w > h ? h : w) - offset * 2;//配置显示物体屏幕的大小glViewport(offset, offset, (GLsizei)dis, (GLsizei)dis);printf("reshape: w=%d, h=%d, dis=%d\n", w, h, dis);glMatrixMode(GL_PROJECTION);glLoadIdentity();glOrtho(-1.5, 1.5, -1.5, 1.5, 0, 10);//gluOrtho2D(-1.5, 1.5, -1.5, 1.5);glMatrixMode(GL_MODELVIEW);glLoadIdentity();
}void keyboard(unsigned char key, int x, int y)
{switch (key) {case 'x':case 'X':axle = 'x';glutPostRedisplay();break;case 'y':case 'Y':axle = 'y';glutPostRedisplay();break;case 'z':case 'Z':axle = 'z';glutPostRedisplay();break;case 'a':case 'A':axle = 'a';glutPostRedisplay();break;default:break;}printf("按键%c\n", key);
}int main(int argc, char *argv[])
{printf("可通过按键xyza控制图形按哪一轴缩放\n");glutInit(&argc, argv);glutInitDisplayMode(GLUT_RGB | (OUTPUT_MODE == 0 ? GLUT_SINGLE : GLUT_DOUBLE));glutInitWindowPosition(100, 100);glutInitWindowSize(400, 400);glutCreateWindow("第一个 OpenGL 程序");init();glutDisplayFunc(&display);glutIdleFunc(display);       //程序空闲的时候调用display(设置不断调用显示函数)glutReshapeFunc(reshape);//  glutKeyboardFunc(keyboard);glutMainLoop();return 0;
}

运行截图

OpenGl入门基础知识-叩开3D的心扉相关推荐

  1. Python培训入门基础知识学什么?

    Python培训基础知识主要是针对一些零基础的同学安排的,虽说Python是相对比较简单的一门编程语言,但是没有基础的同学还是要进行系统的学习,那么Python培训入门基础知识学什么呢?来看看下面小编 ...

  2. NLP汉语自然语言处理入门基础知识介绍

    NLP汉语自然语言处理入门基础知识介绍 自然语言处理定义: 自然语言处理是一门计算机科学.人工智能以及语言学的交叉学科.虽然语言只是人工智能的一部分(人工智能还包括计算机视觉等),但它是非常独特的一部 ...

  3. 负荷计算的时候assert失败_负荷计算的入门基础知识,小白入门必备!

    负荷计算是电气设计人员必须掌握的一必修课,选导体.设备还有保护开关的选择,电网系统分析,都离不开负荷计算的内容,为此小编特意总结9个负荷计算的入门基础知识,分享给大家,希望能在工作和学习中作为一份参考 ...

  4. python笔记基础-Python入门基础知识学习笔记之一

    为什么要写这篇文章? 本人做过Objective-C开发,现在在用C#做WinForm开发.近段时间在学习Python入门基础知识时,发现有很多知识点和Objective-C的不一样.故想通过本文记录 ...

  5. 电脑的基础知识_电脑入门基础知识

    电脑入门基础知识 学习电脑应该先了解电脑的基本的组件,然后学习操作,包括键盘.鼠标的使用,能基本使用操作系统,再学习打字. 作为一个电脑小白,想要学习电脑,首先要知道如何操作,学习打字,接着就是熟练使 ...

  6. ***入门基础知识(超全)

    ***入门基础知识(超全) [sell=2]  DOS 常用命令: dir 列文件名 deltree 删除目录树 cls 清屏 cd 改变当前目录 copy 拷贝文件 diskcopy 复制磁盘 de ...

  7. Python入门基础知识学什么?

    Python基础知识主要是针对一些零基础的同学安排的,虽说Python是相对比较简单的一门编程语言,但是没有基础的同学还是要进行系统的学习,那么Python入门基础知识学什么呢?来看看下面小编的详细介 ...

  8. 半小时入门MATLAB编程入门基础知识:

    https://learnxinyminutes.com/docs/zh-cn/matlab-cn/ 半小时入门MATLAB编程入门基础知识: % 以百分号作为注释符 %{ 多行注释 可以 这样 表示 ...

  9. C语言入门基础知识有哪些?

    众所周知C语言经久不衰,并且很多人都想要成为C语言工程师,为了能够做好C语言技术学习,需要知晓C语言入门基础知识有哪些. 用一个简单的C程序例子,介绍C语言的基本构成.格式.以及良好的书写风格,使小伙 ...

最新文章

  1. android 发送http请求
  2. STM32开发 -- 烧写/启动模式
  3. CSS连载-控制背景与CSS精灵
  4. iPhone系统常用文件夹位置
  5. Linux命令:iptables网络防火墙
  6. mysql 中文乱码解决方法
  7. js 获取鼠标在画布的位置_云凤蝶如何打造媲美 sketch 的自由画布
  8. Spring Security(四) —— 核心过滤器源码分析
  9. mysql-8.0.14图文安装_mysql8.0.14安装配置方法图文教程(通用)
  10. cocos2dx阴影层的实现
  11. 1. webpack 复制文件
  12. 苹果服务器系统状态查询网址
  13. Linux系统vscode断点单步运行调试C++程序
  14. C语言-打卡机(sqlite数据库、多线程)
  15. C++进制转换程序(二进制转换为十进制,十进制转换为二进制)
  16. Tita 绩效管理:一对一正式面谈
  17. docker安装sharding-proxy
  18. ESP32的蓝牙架构你真的了解吗?来,蓝牙博主给你安排~
  19. 点击---显示悬浮页面窗口
  20. 网易闪电邮显示正在联系服务器,网易闪电邮如何正确添加outlook邮箱

热门文章

  1. Matlab软件绘制图像线颜色(RGB)参数设置
  2. 谷歌逐梦穿戴圈:Wear OS的失败能够靠Pixel Watch挽回吗?
  3. Pandas数据分析及可视化应用实践
  4. 程序人生路上的新阶段
  5. 第二章 74181中的先行进位问题
  6. 1. 用户行为采集平台概述
  7. Proteus + μVision Keil单片机仿真教程(一)点亮一个LED
  8. 贴一点代码(用VC实现在WINXP下的宽带拨号)
  9. JavaWeb(总+完结)
  10. 随时随地访问家里搭建的私有存储(tfcenter)