Lighthouse3d.com >> GLUT Tutorial >> Basics >> Initialization

这一节开始从main函数入手.第一步是线初始化GLUT库和创建窗体.

GLUT进入事件处理循环之后会获得程序的控制权.GLUT会等待事件(event)发生,然后检查有没有绑定的函数来处理它.

所以在GLUT进入它的事件处理循环之前,我们要先告诉GLUT事件发生时需要调用哪个函数来处理.

你是不是想问什么是事件(event).事件就是诸如键盘的键被按下,鼠标被移动,窗体需要绘制(到显示器屏幕),还有窗体被改变大小,还有很多.. 我们先从处理绘制事件开始.

告诉GLUT一个事件对应哪个函数的方法是注册回调函数(callback function).每一个事件类型GLUT都提供一个指定的函数来注册回调函数.

main函数的框架如下:

int main(int argc, char **argv)
{ // init GLUT and create window // register callbacks // enter GLUT event processing cycle }

初始化GLUT和创建窗体

所有GLUT函数都以glut开头(作为名字前缀),而GLUT的初始化函数都以glutInit开头.第一步是调用glutInit函数,原型如下:

void glutInit(int *argc, char **argv);

argc和argv都是只读的main函数传入变量的指针

初始化GLUT之后,要定义窗体的属性.先定义位置,例如左上角在屏幕的位置.用glutInitWindowPosition函数实现,原型如下:

void glutInitWindowPosition(int x, int y);

x - 屏幕左边的像素值. -1表示使用默认值,意味着它交由window管理器来决定窗体出现在何处,不想这样的话就给正值,

y - 屏幕顶部的像素值. 同上.

接下来要定义窗体的大小,用glutInitWindowSize函数实现,原型如下:

void glutInitWindowSize(int width, int height);

width - 窗体的宽

height - 窗体的高

然后你要用glutInitDisplayMode函数定义显示模式,原型如下:

void glutInitDisplayMode(unsigned int mode)

mode - 指定显示模式

参数mode是由GLUT库预定义的可选值组成的一个布尔组合(OR位模式),用来指定颜色模型和缓冲的数量和类型.

预定义常量如下:

GLUT_RGBA / GLUT_RGB - 选择RGBA窗体.这是默认选项.

GLUT_INDEX - 选择颜色索引模式

显示模式允许选择单缓冲或双缓冲的窗体,预定义常量如下:

GLUT_SINGLE - 单缓存窗体

GLUT_DOUBLE - 双缓冲窗体,需要支持平滑运动

另外,你可以指定专用的缓冲集合

GLUT_ACCUM - 堆缓冲

GLUT_STENCIL - 模版缓冲

GLUT_DEPTH - 深度缓冲

假定你要创建一个RGB的双缓冲和深度缓冲的窗体.你要做的是用"或"合并这些常量.

glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT DEPTH);

完成了以上步骤之后,只需要调用glutCreateWindow来创建窗体,原型如下:

int glutCreateWindow(char *title);

title - 设置窗体标题

返回值是窗体ID,该ID后面几章会用到.

以下是上面零散初始化代码的整合:

#ifdef __APPLE__
#include <GLUT/glut.h>
#else
#include <GL/glut.h>
#endif int main(int argc, char **argv) { // init GLUT and create Window
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowPosition(,);
glutInitWindowSize(,);
glutCreateWindow("Lighthouse3D- GLUT Tutorial"); return ; }

注意到代码开头的include语法.包含的头文件是GLUT发行包,该发行包的位置在不同的操作系统都不同,所以跨平台检查是必须的.

渲染函数和回调注册

如果你运行这段代码,你会看到一个空的黑色命令行窗体,而不是OpenGL窗体.因为在渲染前还有两件事要做. 一是告诉GLUT库渲染的响应函数,该函数在每次窗体绘制或重绘的时候被GLUT调用.

我们来创建一个渲染的例子函数.下面这函数将会清空颜色缓冲,然后画一个三角形.

void renderScene(void) {

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glBegin(GL_TRIANGLES);
glVertex3f(-0.5,-0.5,0.0);
glVertex3f(0.5,0.0,0.0);
glVertex3f(0.0,0.5,0.0);
glEnd(); glutSwapBuffers();
}

该函数的名字随你喜欢.现在你要做的是把它绑定到GLUT中.该绑定操作叫作注册一个回调.GLUT会在需要渲染的时候调用该函数.

现在就告诉GLUT库renderScene函数需要在窗体绘制的时候调用.GLUT有一个专门函数来做绑定回调函数的操作,需要在窗体创建的时候调用,原型如下:

void glutDisplayFunc(void (*funcName)(void));

GLUT事件处理队列

现在就剩下最后一步,就是告知GLUT可以开始获取事件处理队列.GLUT提供一个函数以死循环的方式持续等待下一个要处理的事件.原型如下:

void glutMainLoop(void)

所有步骤都给出了

到目前的完整代码在下面.当你运行以下代码,会得到一个命令行窗体和一个简单的实例--白色三角形,应该是以指定的大小出现在指定的位置.

#ifdef __APPLE__
#include <GLUT/glut.h>
#else
#include <GL/glut.h>
#endif void renderScene(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glBegin(GL_TRIANGLES);
glVertex3f(-0.5,-0.5,0.0);
glVertex3f(0.5,0.0,0.0);
glVertex3f(0.0,0.5,0.0);
glEnd(); glutSwapBuffers();
} int main(int argc, char **argv) { // init GLUT and create Window
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowPosition(,);
glutInitWindowSize(,);
glutCreateWindow("Lighthouse3D - GLUT Tutorial"); // register callbacks
glutDisplayFunc(renderScene); // enter GLUT event processing cycle
glutMainLoop(); return ;
}

[译]GLUT教程 - 初始化的更多相关文章

  1. [译]GLUT教程(目录)

    http://www.lighthouse3d.com/tutorials/glut-tutorial/ GLUT是OpenGL Utility Toolkit的意思.作者Mark J. Kilgar ...

  2. [译]GLUT教程 - 游戏模式

    Lighthouse3d.com >> GLUT Tutorial >> Extras >> Game Mode 根据GLUT官网的说明,GLUT的游戏模式是为开启 ...

  3. [译]GLUT教程 - 创建和关闭子窗体

    Lighthouse3d.com >> GLUT Tutorial >> Subwindows >> Creating and Destroying Subwind ...

  4. [译]GLUT教程 - 每秒帧数

    Lighthouse3d.com >> GLUT Tutorial >> Extras >> Frames per Second 你的程序实际上跑得多快? 有时我们 ...

  5. [译]GLUT教程 - 鼠标

    Lighthouse3d.com >> GLUT Tutorial >> Input >> The Mouse 上一节我们讨论了怎么用GLUT的键盘函数跟OpenG ...

  6. [译]GLUT教程 - 改变窗体大小

    Lighthouse3d.com >> GLUT Tutorial >> Basics >> Resizing the Window 上一章的例子创建了两个窗体,命 ...

  7. [译]GLUT教程 - glutPostRedisplay函数

    Lighthouse3d.com >> GLUT Tutorial >> Avoiding the Idle Func >> glutPostRedisplay 直 ...

  8. [译]GLUT教程 - 安装

    Lighthouse3d.com >> GLUT Tutorial >> Basics >> Setup 你需要什么 要用GLUT库开发程序,你可以下载最新版本3. ...

  9. [译]GLUT教程 - 整合代码8

    Lighthouse3d.com >> GLUT Tutorial >> Avoiding the Idle Func >> The Code So Far VII ...

随机推荐

  1. UAF学习之Adobe reader CVE-2013-3346

    学习了UAF,分析了几个漏洞,同时,也熟悉了windbg的用法,收获挺大. 基本的UAF分析流程如下: i:找有漏洞的函数 ii:找到被释放对象的类型,以及被释放对象在内存中的位置 iii:理解对象的 ...

  2. objective-c 强弱引用、properties的学习

    一.强弱引用 强引用:strong reference 弱引用:weak reference 引用可以理解为指针A指向的对象B.换句话说,拥有指针A的对象是对象B的所有者(ownership). 区别 ...

  3. AOJ 0531:Paint Color(二维离散+imos)

    [题目链接] http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=0531 [题目大意] 给出一张图,和一些矩形障碍物,求该图没被障碍物覆 ...

  4. ife2015-task2-4-5

    task2-4.html<!DOCTYPE html><html><head lang="en"> <meta charset=" ...

  5. 为什么代理属性设置成assign为了防止生成保留环来

    循环引用 全部的引用计数系统, 都存在循环应用的问题, 比如以下的引用关系: 1. 对象a创建并引用到了对象b 2. 对象b创建并引用到了对象c 3. 对象c创建并引用到了对象b 这时候b和c的引用计 ...

  6. iOS:自定义模态动画 --UIPresentationController

    UIPresentationController :展示控制器,是iOS8的一个新特性,用来展示模态窗口的.它是所有模态控制器的管理者. 即: 1> 管理所有Modal出来的控制器 2>  ...

  7. EJB vs Spring

    转载: Spring 自从2003年发布以来,一直是Java开源框架的奇迹之一.从2000年开始,伴随着B/S架构逐渐引入企业应用软件开发的领域,Java就逐渐成为企业应用开发的主流技术,一直到200 ...

  8. 使用老版本的java api提交hadoop作业

    还是使用之前的单词计数的例子 自定义Mapper类 import java.io.IOException; import org.apache.hadoop.io.LongWritable; impo ...

  9. mysql 修改字符集为utf8mb4

    一般情况下,我们会设置MySQL默认的字符编码为utf8,但是近些年来,emoji表情的火爆使用,给数据库带来了意外的错误,就是emoji的字符集已经超出了utf8的编码范畴

  10. Java Applet 基础

    Java Applet 基础 Applet 是一种 Java 程序.它一般运行在支持 Java 的 Web 浏览器内.因为它有完整的 Java API支持,所以Applet 是一个全功能的 Java ...