2014-04-08  16:18:30

一、配置Glut

学习来源: http://blog.sina.com.cn/s/blog_5f0cf7bd0100c9oa.html

亲测可行。

Glut的一般框架:

int main(int argc, char *argv[])
{
   
glutInit(&argc, argv);
   
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
   
glutInitWindowPosition(100, 100);
   
glutInitWindowSize(400, 400);
   
glutCreateWindow("第一个OpenGL程序");
   
glutDisplayFunc(&myDisplay);
   
glutMainLoop();
    return
0;
}

1、glutInit,对GLUT进行初始化,这个函数必须在其它的GLUT使用之前调用一次。其格式比较死板,一般照抄这句glutInit(&argc, argv)就可以了。
2、glutInitDisplayMode,设置显示方式,其中GLUT_RGB表示使用RGB颜色,与之对应的还有GLUT_INDEX(表示使用索引颜色)。GLUT_SINGLE表示使用单缓冲,与之对应的还有GLUT_DOUBLE(使用双缓冲)。更多信息,请自己Google。当然以后的教程也会有一些讲解。
3、glutInitWindowPosition,这个简单,设置窗口在屏幕中的位置。
4、glutInitWindowSize,这个也简单,设置窗口的大小。
5、glutCreateWindow,根据前面设置的信息创建窗口。参数将被作为窗口的标题。注意:窗口被创建后,并不立即显示到屏幕上。需要调用glutMainLoop才能看到窗口。
6、glutDisplayFunc,设置一个函数,当需要进行画图时,这个函数就会被调用。(这个说法不够准确,但准确的说法可能初学者不太好理解,暂时这样说吧)。
7、glutMainLoop,进行一个消息循环。(这个可能初学者也不太明白,现在只需要知道这个函数可以显示窗口,并且等待窗口关闭后才会返回,这就足够了。)

二、关于Glut

学习来源:http://blog.renren.com/share/230411342/5994614012

 glut这是一套opengl的辅助库, 他使我们能十分简单的设置各种消息处理函数,而且与平台无关,也就是说如果使用glut在windows下编译通过程序无需更改便可在linux,和 mac os下的编译运行,这一点是十分有用的,要知道win32api繁琐的代码走出了windows的窗户可什么也干不了。给glut作了这么多广 告,让我们看看他是怎么用的.

GLUT的基本功能

包括窗口初始化功能、事件处理、窗口和菜单管理、回调函数注册和几何建模功能。

窗口初始化功能,它有4个函数。主要用于处理初始化并以及命令行参数,初始化显示模式,指定窗口左上角在屏幕上的位置和窗口大小,以像素为单位。

事件处理只有一个函数,它用于显示创建的窗口、处理输入的事件、触发回调函数、进入循环直到程序退出。

窗口管理包含18个函数,用于建立、销毁窗口及可能的子窗口,管理和设置窗口的属性。

在 GLUT中有20个回调函数,用于响应用户事件。最重要的回调函数是glutDisplayFunc,当GLUT认为需要重新显示窗口内容时,都将执行这 一函数注册的回调函数。另外一些重要的回调函数注册函数有:函数glutRe-shapeFunc用于注册窗口大小改变这一事件发生时GLUT将调用的函 数。glutKeyboardFunc和glutMouseFunc用于注册键盘和鼠标事件发生时的回调函数。函数glutMotionFunc注册鼠标 移动事件的回调函数。这3个函数用于人机交互处理。在没有其他事件处理时,GLUT将调用函数glutldleFunc注册的函数,而函数 glutTimerFunc则注册处理定时器事件的函数。

OpenGL绘图函数只能生成点、直线、多边形等简单的几何图元,GLUT提供了18个创建三维物体的函数。利用它们可以创建9种三维物体,如圆锥体、立方体、球体等,每一物体有线框和实体2种方式。

我们看到的以glut开头的函数都是 glut库的一部分,如处理参数的,和设置窗口的,我们在这里主要讨论glut支持的各种消息处理

窗口更新的处理函数

① 我们知道各种窗口的操作都会引发窗口更新消息,在glut中我们通过

void glutDisplayFunc(void (*func)(void))

来设置窗口刷新的消息处理函数,其唯一的参数指定了屏幕刷新时会调用的函数

② 如果要处理窗口变化的消息我们可以通过设置下面函数来实现

void glutReshapeFunc(void (*func)(int w, int h))

这里的func为回调函数,w,h分别为改变后窗口的宽和高

二:对于键盘和鼠标的输入我们可以通过下面两个函数来设置

void glutKeyboardFunc(void (*func)(unsigned char key, int x, int y))

void glutMouseFunc(void (*func)(int button, int state, int x, int y))

key为键盘按键的ASCII吗

x y都表示鼠标的位置,

而button则为GLUT_LEFT_BUTTON或GLUT_RIGHT_BUTTON

分别表示左右按键。

state为按键的状态,若为按下则为GLUT_DOWN

当鼠标移动式我们还可以通过下面的函数来设置鼠标移动消息的处理函数

void glutMotionFunc(void (*func)(int x, int y))

X,Y仍然为鼠标的位置

   特殊函数用于完成循环画图(或者说是动画)

这里还有一个函数比较特殊

                                               void glutIdleFunc(void (*func)(void)).

这里设置的是系统空闲时将会调用的函数

下面我们将看到一个完整的例子,通过输入来控制三维物体的旋转

#include <math.h>

#include <gl/glut.h>

#include <gl/gl.h>

#define pi 3.1415926

bool mouseisdown=false;

bool loopr=false;

int mx,my;

int ry=30;

int rx=30;

void timer(int p)

{

ry-=5;

glutPostRedisplay();                 //marks the current window as needing to be redisplayed.

if (loopr)

glutTimerFunc(200,timer,0);

}

void mouse(int button, int state, int x, int y)

{

if(button == GLUT_LEFT_BUTTON)

{

if(state == GLUT_DOWN)

{    mouseisdown=true; loopr=false;}

else

mouseisdown=false;

}

if (button== GLUT_RIGHT_BUTTON)

if(state == GLUT_DOWN)

{loopr=true; glutTimerFunc(200,timer,0);}

}

void motion(int x, int y)

{

if(mouseisdown==true)

{

ry+=x-mx;

rx+=y-my;

mx=x;

my=y;

glutPostRedisplay();

}

}

void special(int key, int x, int y)

{

switch(key)

{

case GLUT_KEY_LEFT:

ry-=5;

glutPostRedisplay();

break;

case GLUT_KEY_RIGHT:

ry+=5;

glutPostRedisplay();

break;

case GLUT_KEY_UP:

rx+=5;

glutPostRedisplay();

break;

case GLUT_KEY_DOWN:

rx-=5;

glutPostRedisplay();

break;

}

}

void display()

{

float red[3]={1,0,0};

float blue[3]={0,1,0};

float green[3]={0,0,1};

float yellow[3]={1,1,0};

glClearColor(1,1,1,1);

glClear(GL_COLOR_BUFFER_BIT);

glLoadIdentity();

glRotatef(ry,0,1,0);

glRotatef(rx,1,0,0);

glColor3fv(green);

glutWireTeapot(0.5);

glFlush();

}

int main(int argc, char** argv)

{

glutInit(&argc, argv);

glutInitDisplayMode (GLUT_SINGLE| GLUT_RGBA);

glutInitWindowSize (400, 400);

glutInitWindowPosition(100,100);

glutCreateWindow ("A TEAPOT");

glutDisplayFunc (display);

glutMouseFunc(mouse);

glutMotionFunc(motion);

glutSpecialFunc(special);

glutMainLoop();

return 0;

}

运行这个程序我们会发现一个茶壶,我们可以通过鼠标和键盘的方向键来控制它的旋转,而按下鼠标右键则可以让这个茶壶自动旋转,这里还有几个函数我们要注意一下

void glutWireTeapot(GLdouble size)在当前的OCS坐标中心画一个以size为大小的茶壶

void glutSpecialFunc(void (*func)( int key, int x, int y))

这个函数与glutKeyboardFunc的区别在于前者是用来响应键盘上的特殊按键,如方向键和控制键等。而后者则是用来响应键盘上的字符按键

void glutTimerFunc(int delay, (void (*func)( int parameter),int parameter)

这 个函数相当于win32 api中的timer定时器,也是在delay毫秒后放出一个定时器消息,而这里的func则为这个消息的处理函数,patameter为附加参数。这里 有一点要注意这个函数是一次性的,如果要重复使用可以在func中继续调用glutTimerFunc,而且这个功能是可以叠加的,在opengl内部将 他们看成许多个不同的定时器,这也就是为什么我们在上面的例子中连续按下鼠标右键会加快旋转的速度

键盘和鼠标是图形绘制过程中最主要的两种输入工具。如何通过键盘的按键或鼠标的点击来完成用户想达到的图形显示事件呢?在GLUT库中专门有两个函数来用于接收和响应这两类动作,分别为:
glutKeyboardFunc(void(*func)(unsigned char key, int x, int y))
glutMouseFunc(void(*func)(int button, int state, int x, int y))
这两个函数存在于消息循环中,不断地检查当前是否有键盘敲击或鼠标点击的事件发生,如果有这样的事件发生,则触发func函数,执行一系列的动作。

glutKeyboardFunc(void(*func)(unsigned char key, int x, int y))

函数用于接收并响应键盘动作,它需要一个函数的指针作为参数,这个函数func称为回调函数(callback)。通俗点说就是,回调函数并不会主动执
行,而是通过另一个函数来通知它是否执行(比如glutKeyboardFunc函数用来通知func()函数是否执行)。键盘回调函数的定义格式如下:
void func(unsigned char key, int x, int y)
为了让程序更易于理解,常将其函数名命名为myKeyboard:
   void myKeyboard(unsigned char key, int x, int y)   
glutKeyboardFunc(myKeyboard)函数检测到键盘事件后,它先将用户按键盘那一时刻的鼠标位置(xyx表示鼠标相对于窗口的左边框的偏移量;y表示鼠标相对于窗口上边框的偏移量,都以像素为单位,即相当于原点在窗口左上角)和键盘按键时的键值(key,即键盘字母对应的ASCII码值)作为实际参数传送给myKeyboard,然后通知myKeyboard函数立即执行。

glutMouseFunc(void(*func)(int button, int state, int x, int y))
此函数用于接收并响应鼠标动作,同样需要一个回调函数指针作为参数。鼠标回调函数的定义格式如下:
void func(int button, int state, int x, int y)
为了让程序更易于理解,常将其函数名命名为myMouse:
   void myMouse(int button, int state, int x, int y)   
同样,在消息循环过程中,当glutMouseFunc(myMouse)函数检测到有鼠标事件发生后,它先将事件发生那一时刻的鼠标按键(button,说明是左键还是右键),鼠标动作(state,说明是鼠标按下去那一刻,还是按下去后弹上来那一刻),以及按键时鼠标的位置(xyx表示鼠标相对于窗口的左边框的偏移量;y表示鼠标相对于窗口上边框的偏移量,都以像素为单位,即相当于原点在窗口左上角)作为实际参数传递给myMouse,然后通知myMouse执行。
其中button对应的值有:
左键:GLUT_LFET_BUTTON  [0]
中建:GLUT_MIDDLE_BUTTON  [1]
右键:GLUT_RIGHT_BUTTON  [2]
state对应的值有:
按下去:GLUT_DOWN  [0]
弹上来:GLUT_UP  [1]
注:中括号中表示常量所对应的实际数值。

下面讨论回调函数参数中x和y的具体意义,即myKeyboard和myMouse的参数中x和y的值如何映对到窗口的实际坐标位置上。

看下图,假设鼠标或键盘动作产生时,鼠标位置在图中的红色点的位置,它相对于上边框的距离为200像素,相对于左边框的像素为300像素,这样我用x,y
的值表示坐标(300,200)就是现在红色点这个位置吗?显然不是,而我把y替换为z,即窗口高度减去y的值得到(300,400)是否可以映射到实际
坐标位置呢?显然也不是,因为当前的窗口坐标范围是:左下角坐标为(-300,-300);右上角坐标为(300,300),所以(300,200)应处
在窗口的右上方,而(300,400)则跑出了坐标表示的范围,显然这两个坐标都不能与红色点的位置重合。

再考虑,(300,400)是红色点相对于窗口左下角的位置,即可以看做它所对应的原点(0,0)在左下角,而实际坐标中,左下角坐标为
(-300,-300)实际的原点在窗口的中心位置,所以,这个时候,你只需对(x,z)向左和向下进行平移300个单位即可。这样(x-300,z-
300)就得到了(0,100)正好与红色点重合。
我们从上面的分析过程可以得到将x,y转换为实际坐标的值的方法:
   横坐标值:x + 左下角横坐标值   
   纵坐标值:窗口高度 - y + 左下角纵坐标值   

OpenGl学习资料:

http://www.videotutorialsrock.com/

http://bbs.pfan.cn/post-275228.html

vc++ 6.0下Glut的配置 及 Glut 框架介绍的更多相关文章

  1. VC++6.0 下配置 pthread库2010年12月12日 星期日 13:14VC下的pthread多线程编程 转载

    VC++6.0 下配置 pthread库2010年12月12日 星期日 13:14VC下的pthread多线程编程     转载 #include <stdio.h>#include &l ...

  2. Windows平台VC++ 6.0 下的网络编程学习 - 简单的测试winsock.h头文件

    最近学习数据结构和算法学得有点累了(貌似也没那么累...)...找了本网络编程翻了翻当做打一个小基础吧,打算一边继续学习数据结构一边也看看网络编程相关的... 简单的第一次尝试,就大致梳理一下看书+自 ...

  3. 03、NetCore2.0下Web应用之搭建最小框架

    03.NetCore2.0下Web应用之搭建最小框架 这里我们不使用VS2017或者CLI命令的方式创建Asp.Net Core 2.0网页应用程序,而是完全手工的一点点搭建一个Web框架,以便更好的 ...

  4. VC++ 6.0下OpengGL配置以及glut配置

    转自:http://blog.sina.com.cn/s/blog_5f0cf7bd0100c9oa.html OpenGL官方网站(英文) http://www.opengl.org 下面我将对Wi ...

  5. OpenCV1.0在VC ++6.0下的配置

    1.本人使用win7操作系统,首先要预装VC++6.0,安装方法不再赘述. 2.在OpenCV官方网站下载OpenCV的安装文件"OpenCV_1.0.EXE"(参考链接:http ...

  6. 解决libcurl7.50.3在windows XP SP3 VC++ 6.0下编译报错 unresolved external symbol __imp__IdnToAscii@20 unresolved external symbol __imp__IdnToUnicode@20

    错误重现: --------------------Configuration: curl - Win32 LIB Debug DLL Windows SSPI DLL WinIDN--------- ...

  7. Intelligencia.UrlRewriter在IIS 7.0下的完全配置攻略

    在项目中,之前公司是使用IIS 7.0官方的URL重写模块,官方的使用说明请参见官方URLRewrite  ,添加伪静态支持,后来经理问我有没有涉及伪静态,我说之前项目中我一直是用Intelligen ...

  8. Kali 2.0 下 Metasploit 初始化配置

    在kali 2.0中,命令行中直接输入msfconsole 提示不能连接到数据库 ,是由于postgresql 未启动.因此,需要开启postgresql,并且进行postgresql 的初始化配置. ...

  9. VC++6.0下通过opencv读入图像并反色

    第一个opencv测试程序: 不多说,直接上代码,代码注释很详尽: ////////////////////////////////////////////////////////////////// ...

随机推荐

  1. JayProxy的设置

    1. mac http://pac.jayproxy.com/jayproxy/jayproxy.pac 2. wifi http://pac.jayproxy.com/jayproxy/m.pac ...

  2. android volley get请求使用

    调用百度api微博热门精选接口,使用了volley,简单说说volley get的请求方式的使用 header的设置和请求参数的设置,见代码如下: private void getWeixinNews ...

  3. CHAP认证原理

    整个过程就是PPP协商过程,分三步:LCP.认证.NCP. 一 协议概述 PPP包含以下两个层次的协议: ·链路控制协议(LCP):负责建立.配置和测试数据链路连接 ·网络控制协议(NCP):负责建立 ...

  4. C语言 百炼成钢8

    //题目22:两个乒乓球队进行比赛,各出三人.甲队为a,b,c三人,乙队为x,y,z三人.已抽签决定 //比赛名单.有人向队员打听比赛的名单.a说他不和x比,c说他不和x, z比,请编程序找出 //三 ...

  5. C# winform 上传文件到服务器

    1.首先要在服务器端新建一个网站axpx页 然后再网站的后台写代码获取winform传过来的文件名. 声明:这个方法虽然最简单最省事,但是上传大文件可能会报错,我的机器是10M, 超过10M就会提示报 ...

  6. 基于Flot可放缩的折线图

    Flot初步 Flot是一个免费开源的图标插件,可以用它开发出功能强大的图表系统.下面着重讲解在Asp.net中如何使用这个插件做出功能强大的图表应用. 关于Flot,可以在这里查看现有的例子(或者是 ...

  7. Caffe学习系列(21):caffe图形化操作工具digits的安装与运行

    经过前面一系列的学习,我们基本上学会了如何在linux下运行caffe程序,也学会了如何用python接口进行数据及参数的可视化. 如果还没有学会的,请自行细细阅读: caffe学习系列:http:/ ...

  8. SQL 语句大全

    转载:http://www.cnblogs.com/yubinfeng/archive/2010/11/02/1867386.html 经典SQL语句大全 一.基础 1.说明:创建数据库 CREATE ...

  9. Xamarin.Form 实例: Discuz BBS 客户端 源码分享

    感谢台风, 这个十一长假让我好好的休息了一回, 睡觉到腰酸背疼, 看电影看到眼发红. 今天最后一天, 不敢出去逛, 不知道哪会还会下暴雨... 嗯嗯..这个项目其实在十一之前就开始了, 工作无聊,没有 ...

  10. C#进阶系列——WebApi接口传参不再困惑:传参详解(转载)

    原文地址: http://www.cnblogs.com/landeanfen/p/5337072.html 前言:还记得刚使用WebApi那会儿,被它的传参机制折腾了好久,查阅了半天资料.如今,使用 ...