glutmainloopevent会无限次调用必要的任何已经注册的函数,一般具体都是哪些函数?我产生了一组随

资讯通告 :
您的位置: >
> 教程内容
Linux下的OpenGL编程
注册窗口大小改变时的响应函数 */
glutReshapeFunc ( reshape );
/* 注册键盘响应函数 */
glutKeyboardFunc ( keyboard );
/* 进入GLUT消息循环,开始执行程序 */
glutMainLoop( );
   从上面的例子中我们可以看出,GLUT采用一种函数注册的机制来实现OpenGL绘图。它的一般流程正如我们上面的注释所写,先是初始化函数,定义窗口,然后执行OpenGL初始化程序,这主要是一些需要全局设置的环境变量。接下来是注册相应事件的函数,包括完成实际绘图工作的绘制程序、改变OpenGL窗口大小时的响应函数、键盘事件的响应函数和鼠标时间的响应函数。最后调用glutMainLoop()函数,执行在glutReshapeFunc和glutDisplayFunc中注册的函数,进入消息循环。当用户通过键盘和鼠标进行交互操作时,它即调用相应的函数。
   我们编译上面的名为light.c的源文件。假定头文件(目录GL)放在目录/usr/local/include下,库文件(动态库libGL.so.*、libGLU.so.*和libglut.so.*)在目录/usr/local/lib目录下,并已经运行了ldconfig,则编译命令为:
   gcc -I/usr/local/include -L/usr/local/lib -L/usr/X11R6/lib -lglut -lGLU -lGL
   -lX11 -lXext -lXmu -lXi -lm light.c -o light
   其中的-lX11 -lXert -lXi -lm 是绘制窗口需要的X的库,它们默认在 /usr/X11R6/lib目录下。下面的图一即是运行light的结果,当按下ESC键时,程序会退出。调整窗口大小时,图形自动重绘。注意在上面reshape函数中,比较w和h的值给出的取景变换,这是一个常用的技巧。
          图一
2.3 GLUT简介
   GLUT常用的函数主要包括以下几类:
   ? 初始化函数。主要就是上面例子中的几个函数。
   ? 消息循环函数。即glutMainLoop函数。
   ? 窗口管理函数。包括窗口的创建、修改、删除等。GLUT支持多个OpenGL窗口。
   ? Overlay管理函数。当用户显卡支持Overlay方式时,可以用这些函数来创建、管理、删除GLUT窗口的Overlay。
   ? 菜单管理函数。定制菜单以及定义菜单相应事件。
   ? 事件注册函数。除了上面例子中提及的外,还有鼠标、空间球(提供三维操作的装备)、特殊键(Ctrl、Shift、F系列键、方向键)等设备的事件注册函数。
   ? 字体绘制函数。用多种字体、字号供选择。
   ? 简单几何体的绘制程序。包括球、立方体、锥体、圆环体、十二面体、八面体、四面体、二十面体和茶壶。每种几何体都有实体和虚线两个选项。
   ? 取状态函数。类似OpenGL的glGet系列函数,取得GLUT的各种状态值。
   ? 颜色索引表函数。
这些函数极大的方便了用户的OpenGL编程。下面我们简略介绍一下几个常用的函数。
   ? glutPostRedisplay()。发送消息给函数glutMainLoop,请求重绘本窗口。利用此函数可以实现。例如在上面的例子中,我们添加一个全局变量:float move=0.0。并定义函数MoveSphere如下:
void MoveSphere ( void )
for(int i=0;i&100;i++){
if ( move&1.0) move+=0.1;
else move=0.0;
glutPostRedisplay ( );
同时修改函数display()为:
void display ( void )
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glTranslatef ( move, 0.0, 0.0);
glutSolidSphere (1.0, 40, 50);
glFlush ();
   这样,当我们执行函数MoveSphere时,就会看到上面的球从中间向右移动一段距离,然后又回到中心,继续移动。
   ? glutIdleFunc()函数。这个函数注册一个空闲程序一直在后台运行。我们将上面的MoveSphere函数加以修改,去掉循环,然后在light.c程序的glutMainLoop()函数调用前添加一行代码:glutIdleFunc (MoveSphere);这样我们不需要直接调用函数MoveSphere,程序一运行,它就被反复调用直到我们退出程序为止,这和我们前一版本中它只能循环特定的步数不一样。
   ? glutTimerFunc()函数。和前面的glutIdleFunc()函数类似,但不同的是它注册的函数每隔特定的事件发生。时间的单位是毫秒。
   ? glutBitmapCharacter()函数。用位图方式按指定的字体绘制一个字符串。
   ? glutSolidSphere()函数。这是绘制几何体类函数中的一个。此函数绘制一个球体。
2.4 一个更有代表性的例子
   下面我们来看一个稍稍复杂的例子。我们绘制一个平面,用户的左键点击被自动连接成一个多边形。当用户点击右键,会弹出菜单供用户选择。用户可以选择清除、镶嵌和退出。选择清除将回到初始状态;选择镶嵌程序自动对多边形进行三角剖分;选择退出则终止程序。(见图二、图三和图四)
       图二                图三               图四
/* tessdemo.c 多边形镶嵌的例子,使用函数gluTessCallback和函数gluTessVertex。*/
/* 定义允许的最大多边形数、多边形允许的最大顶点数和可镶嵌的最大三角形数*/
#define MAX_POINTS 256
#define MAX_CONTOURS 32
#define MAX_TRIANGLES 256
/* 用于菜单选项的枚举类型 */
typedef enum{ QUIT, TESSELATE, CLEAR } menu_
static mode_
/* 定义绘制模式的枚举类型 */
typedef enum{ DEFINE, TESSELATED } mode_
static GLsizei width, /* OpenGL窗口的大小 */
static GLuint contour_ /* 记录多边形数目 */
static GLuint triangle_ /* 记录三角形数目 */
static GLuint list_ /* 用于显示列表 */
/* 多边形结构 */
static struct {
GLfloat p[MAX_POINTS][2];
GLuint point_
} contours [ MAX_CONTOURS ] ;
/* 三角形结构 */
static struct {
GLfloat p [3] [2];
GLclampf color [3] [3];
} triangles [ MAX_TRIANGLES ];
/* 窗口大小改变时,设定width和height值,用于重新绘制网格 */
void set_screen_wh ( GLsizei w, GLsizei h )
{ width = height = }
void tesse ( void )
{ /* 镶嵌函数,调用&&&[2]&&&&&
相关文章列表
(评论内容只代表网友观点,与本站立场无关!)网友评论:
&&&&用户名: !
&&&&评&&&nbsp分:100分
&&&&内 容: !
&&&&&&&&&&&&&&&&
(注“!”为必填内容。) 验证码:
本类热门文章  glutMainLoop进入GLUT事件处理循环,让所有的与“事件”有关的
无限循环。
  glutMainLoop进入GLUT事件处理循环。在一个GLUT程序中,这个例程被调用一次 。一旦被调用,这个程序将永远不会返回 。它将调用必要的任何已注册的回调。
  例子:(opengl实例)
  #include
  void RenderScene()
  glClear(GL_COLOR_BUFFER_BIT);
  glFlush();
  void SetupRc()
  glClearColor(0.3f,0.0f,0.0f,0.1f);
  void main(void)
  int i=20;
  glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
  glutCreateWindow(&single&);
  glutDisplayFunc(RenderScene);
  SetupRc();
  glutMainLoop();//这里让整个绘图循环进行,相当于死循环
为本词条添加和相关影像
互动百科的词条(含所附图片)系由网友上传,如果涉嫌侵权,请与客服联系,我们将按照法律之相关规定及时进行处理。未经许可,禁止商业网站等复制、抓取本站内容;合理使用者,请注明来源于。
登录后使用互动百科的服务,将会得到个性化的提示和帮助,还有机会和专业认证智愿者沟通。
您也可以使用以下网站账号登录:
此词条还可添加&
编辑次数:3次
参与编辑人数:3位
最近更新时间: 11:38:12
贡献光荣榜
扫描二维码用手机浏览词条
保存二维码可印刷到宣传品
扫描二维码用手机浏览词条
保存二维码可印刷到宣传品当前访客身份:游客 [
擅长C++, 热爱STL,Boost,FSF; 正在学习C++11,永久邮箱,欢迎交流 http://blog.csdn.net/xusiwei1236
:引用来自“notmmao”的评论 main函数也可以封装起...
:main函数也可以封装起来,函数内部逻辑简化为:n...
:由此结果可以看到,Code Formatter对的OSchina博...
今日访问:0
昨日访问:1
本周访问:1
本月访问:1
所有访问:2108
GLUT的简洁OO封装
发表于1年前( 22:08)&&
阅读(427)&|&评论()
0人收藏此文章,
毕业设计用到了OpenGL,由于不会用MFC和Win32API做窗口程序;自然选用了GLUT。GLUT很好用,就是每次写一堆Init,注册callback,觉得有点恶心,于是对他做了简单的OO封装。记录在此,如有同学有兴趣可以下载。
GLUT应用程序
直接使用GLUT的程序是这样的:
#include &GL/glut.h&
#include &stdio.h&
void display()
// OpenGL commands
// 一般按键(所有可打印字符,ESC也在内)
void keyboardHander(unsigned char ch, int x, int y)
printf("key %d(%c) x: %d, y: %d\n", ch, ch, x, y);
fflush(stdout);
// 特殊按键
void specialKeyHandler(int key, int x, int y)
printf("special key");
switch(key) {
case GLUT_KEY_UP:
printf("%d(%s) ", key, "GLUT_KEY_UP");
case GLUT_KEY_DOWN:
printf("%d(%s) ", key, "GLUT_KEY_DOWN");
case GLUT_KEY_LEFT:
printf("%d(%s) ", key, "GLUT_KEY_LEFT");
case GLUT_KEY_RIGHT:
printf("%d(%s) ", key, "GLUT_KEY_RIGHT");
printf("%d(%s) ", key, "Other Special keys");
printf("x: %d, y: %d\n", x, y);
fflush(stdout);
// 鼠标按键
void mouseHandler(int button, int state, int x, int y)
printf("mouse pos: (%3d, %3d) button: %s(%d), state: %s(%d)\n", x, y,
GLUT_LEFT_BUTTON == button ? "GLUT_LEFT_BUTTON"
: GLUT_RIGHT_BUTTON == button ? "GLUT_RIGHT_BUTTON"
: GLUT_MIDDLE_BUTTON == button ? "GLUT_MIDDLE_BUTTON"
GLUT_UP == state ? "GLUT_UP"
: GLUT_DOWN == state ? "GLUT_DOWN"
: "UNKNOW"
fflush(stdout);
// 鼠标拖动
void motionHandler(int x, int y)
printf("motion to %d, %d\n", x, y);
fflush(stdout);
// 鼠标移动
void passiveMotionHandler(int x, int y)
printf("passive motion to %d, %d\n", x, y);
fflush(stdout);
void testTimer(int i)
printf("Alarm %d\n", i);
fflush(stdout);
if( i & 5 )
glutTimerFunc(1000, testTimer, i+1);
int main(int argc, char *argv[])
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
glutInitWindowSize(400, 300);
glutInitWindowPosition(100, 100);
glutCreateWindow("Getting started with OpenGL 4.3");
glutDisplayFunc(display);
glutKeyboardFunc(keyboardHander); // 键盘按键(一般)
glutSpecialFunc(specialKeyHandler); // 特殊按键
glutMouseFunc(mouseHandler); // 鼠标按键
glutMotionFunc(motionHandler);
// 鼠标拖动
glutPassiveMotionFunc(passiveMotionHandler); // 鼠标移动
glutTimerFunc(1000, testTimer, 1); // 定时器
glutMainLoop(); // start main loop.
}用起来还算简单,就是每次都写一堆Init和callback注册...
于是,我想到是否能够将它封装为一个基类,然后每次继承一下(有点像Java,C#的窗体程序)。
也就是每个成员函数对应一种事件的响应,比如onKey, onMouse等等。我们希望我们的程序像下面这样:
int main(int argc, char **argv)
GlutApp::initGlut(argc, argv);
GlutApp* app = new DemoApp();
app-&setTitle("a demo app");
app-&setWindowsSize(800, 600);
app-&run();
Member function 如何作为Callback?
这里其实是两个问题。
第一个问题,member function的函数签名上有this指针,不能直接传给glut*Func作为callback,怎么办?
member function不行,很自然的想到static function;因为static function的函数签名上没有this指针。
第二个问题,static function如何能够调用member function,且与之关联的对象(this指针)能够在运行时期(或者用户程序)决定?
其一,static function调用member function自然要用到 static member。
其二,可让member function修改这个static member。
有了上面的分析,GlutApp类就可以轻易的写出来了:
#ifndef GLUT_APP_H
#define GLUT_APP_H
class GlutApp
typedef void (*MenuFuncPtr)(void);
struct MenuEntry
const char*
// 当前 App 实例指针,指向子类实例
static GlutApp* s_pCurrentA
// 右键菜单 项数最大值
static const int MAX_MENU = 32;
GlutApp();
// getter and setters:
static void initGlut(int argc, char** argv) { s_argc = s_argv = }
void setDisplayMode(unsigned int mode) { m_displayMode = }
void setWindowsSize(int w, int h) { m_winWidth = m_winHeight = }
int getWindowWidth() { return m_winW }
int getWindowHeight() { return m_winH }
void setWindowsPos(int x, int y) { m_winPosX = m_winPosY = }
void setTitle(char *title) { m_title = }
void run();
void addRightMenu(const char *str, MenuFuncPtr fun);
virtual void onInit(){}
//////////////////////////////////////////////////////////////////////////
// GLUT delegate callbacks:
// 空闲函数
virtual void onIdle(){}
// 图形显示(OpenGL绘图指令)
virtual void onDisplay() = 0; // 子类必须重写;不能实例化该类
// 窗口大小改变
virtual void onResize(int w, int h){}
//////////////////////////////////////////////////////////////////////////
// 键盘事件响应 方法:
// 一般按键(可打印字符,ESC)
virtual void onKey(unsigned char key, int x, int y){}
// 一般按键 按下
virtual void onKeyDown(unsigned char key, int x, int y) {}
// 特殊按键(除一般按键外按键)
virtual void onSpecialKey(int key, int x, int y){}
// 特殊按键按下
virtual void onSpecialKeyDown(int key, int x, int y){}
//////////////////////////////////////////////////////////////////////////
// 鼠标事件响应 方法:
// 鼠标按键
//! @param button: The button parameter is one of GLUT LEFT BUTTON, GLUT MIDDLE BUTTON, or GLUT RIGHT BUTTON.
//! @param state: The state parameter is either GLUT UP or GLUT DOWN indicating
whether the callback was due to a release or press respectively.
virtual void onMousePress(int button, int state, int x, int y){}
// 鼠标移动
virtual void onMouseMove(int x, int y){}
// 鼠标拖动
virtual void onMousePressMove(int x,int y){}
//////////////////////////////////////////////////////////////////////////
// 定时器相关 方法:
virtual void onTimer() {}
void setTimer(int delay, int period = 0);
protected:
void registerMenus();
// actual GLUT callback functions:
static void KeyboardCallback(unsigned char key, int x, int y);
static void KeyboardUpCallback(unsigned char key, int x, int y);
static void SpecialKeyboardCallback(int key, int x, int y);
static void SpecialKeyboardUpCallback(int key, int x, int y);
static void ReshapeCallback(int w, int h);
static void IdleCallback();
static void MouseFuncCallback(int button, int state, int x, int y);
static void MotionFuncCallback(int x,int y);
static void MousePassiveCallback(int x, int y);
static void DisplayCallback();
static void MenuCallback(int menuId);
static void TimerCallback(int period);
unsigned int m_displayM
// for glutInit
static int s_
static char** s_
// for glutSetWindowSize
int m_winW
int m_winH
// for windows position
int m_winPosX;
int m_winPosY;
// for menus:
MenuEntry m_menuEntry[MAX_MENU];
// for timer:
#endif // GLUT_APP_H
GlutApp.cpp
#include &gl/glut.h&
#include &assert.h&
#include &stdio.h&
#include "GlutApp.h"
int GlutApp::s_argc = 0;
char** GlutApp::s_argv = 0;
GlutApp* GlutApp::s_pCurrentApp = 0;
int g_iLastWindow = 0;
void GlutApp::run()
GlutApp* lastApp = GlutApp::s_pCurrentA
GlutApp::s_pCurrentApp =
GlutApp* app = GlutApp::s_pCurrentA
assert(app);
int screenW = glutGet(GLUT_SCREEN_WIDTH);
int screenH = glutGet(GLUT_SCREEN_HEIGHT);
if (!app-&m_winWidth)
app-&m_winWidth = screenW / 2;
app-&m_winHeight = screenH / 2;
if (!app-&m_winPosX)
app-&m_winPosX = (screenW - app-&m_winWidth) / 2;
app-&m_winPosY = (screenH - app-&m_winHeight) / 2;
if (!lastApp) // first time calling Glut::run().
// glutInit that should only be called exactly once in a GLUT program.
glutInit(&this-&s_argc, this-&s_argv);
glutInitDisplayMode(this-&m_displayMode);
glutInitWindowPosition(app-&m_winPosX, app-&m_winPosY);
glutInitWindowSize(app-&m_winWidth, app-&m_winHeight);
glutCreateWindow(app-&m_title);
g_iLastWindow = glutGetWindow();
// printf("create window: %d\n", g_iLastWindow);
glutDestroyWindow(g_iLastWindow);
glutInitDisplayMode(this-&m_displayMode);
glutInitWindowPosition(app-&m_winPosX, app-&m_winPosY);
glutInitWindowSize(app-&m_winWidth, app-&m_winHeight);
glutCreateWindow(app-&m_title);
g_iLastWindow = glutGetWindow();
// printf("create window: %d\n", g_iLastWindow);
app-&onInit();
// register keyboard callbacks
glutKeyboardFunc(GlutApp::KeyboardCallback);
glutKeyboardUpFunc(GlutApp::KeyboardUpCallback);
glutSpecialFunc(GlutApp::SpecialKeyboardCallback);
glutSpecialUpFunc(GlutApp::SpecialKeyboardUpCallback);
// register mouse callbacks
glutMouseFunc(GlutApp::MouseFuncCallback);
glutMotionFunc(GlutApp::MotionFuncCallback);
glutPassiveMotionFunc(GlutApp::MousePassiveCallback);
// register menus:
registerMenus();
// regitser windows resize callback
glutReshapeFunc(GlutApp::ReshapeCallback);
// register render callback
glutDisplayFunc(GlutApp::DisplayCallback);
// register timer callbacks:
if (app-&m_delay)
glutTimerFunc(app-&m_delay, GlutApp::TimerCallback, app-&m_period);
// register idle callback
glutIdleFunc(GlutApp::IdleCallback);
GlutApp::IdleCallback();
glutMainLoop();
GlutApp::GlutApp()
m_displayMode = GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH | GLUT_STENCIL;
m_menuCount = 0;
m_delay = 0;
m_period = 0;
m_winPosX = 0;
m_winPosY = 0;
m_winWidth = 0;
m_winHeight = 0;
void GlutApp::KeyboardCallback( unsigned char key, int x, int y )
GlutApp::s_pCurrentApp-&onKey(key,x,y);
void GlutApp::KeyboardUpCallback( unsigned char key, int x, int y )
GlutApp::s_pCurrentApp-&onKeyDown(key,x,y);
void GlutApp::SpecialKeyboardCallback( int key, int x, int y )
GlutApp::s_pCurrentApp-&onSpecialKey(key,x,y);
void GlutApp::SpecialKeyboardUpCallback( int key, int x, int y )
GlutApp::s_pCurrentApp-&onSpecialKeyDown(key,x,y);
void GlutApp::ReshapeCallback( int w, int h )
GlutApp::s_pCurrentApp-&setWindowsSize(w, h);
GlutApp::s_pCurrentApp-&onResize(w,h);
void GlutApp::IdleCallback()
GlutApp::s_pCurrentApp-&onIdle();
void GlutApp::MouseFuncCallback( int button, int state, int x, int y )
GlutApp::s_pCurrentApp-&onMousePress(button,state,x,y);
void GlutApp::MotionFuncCallback( int x,int y )
GlutApp::s_pCurrentApp-&onMousePressMove(x,y);
void GlutApp::MousePassiveCallback( int x, int y )
GlutApp::s_pCurrentApp-&onMouseMove(x, y);
void GlutApp::DisplayCallback( void )
GlutApp::s_pCurrentApp-&onDisplay();
void GlutApp::addRightMenu( const char *str, MenuFuncPtr fun )
m_menuEntry[m_menuCount].id = m_menuC
m_menuEntry[m_menuCount].str =
m_menuEntry[m_menuCount].fun =
m_menuCount++;
void GlutApp::registerMenus()
if (m_menuCount & 0)
glutCreateMenu(GlutApp::MenuCallback);
for (int i=0; i&m_menuC ++i)
glutAddMenuEntry(m_menuEntry[i].str, m_menuEntry[i].id);
glutAttachMenu(GLUT_RIGHT_BUTTON);
void GlutApp::MenuCallback( int menuId )
for (int i=0; i&GlutApp::s_pCurrentApp-&m_menuC ++i)
if (menuId == GlutApp::s_pCurrentApp-&m_menuEntry[i].id)
GlutApp::s_pCurrentApp-&m_menuEntry[i].fun();
void GlutApp::setTimer( int delay, int period )
this-&m_delay =
this-&m_period =
void GlutApp::TimerCallback( int period )
// printf("Timer Alarm!\n");
GlutApp::s_pCurrentApp-&onTimer();
if (period)
glutTimerFunc(period, GlutApp::TimerCallback, period);
“伟大的三角形”,如同Hello world在编程语言教程里一样有名:
#include &windows.h& // 这里使用的是 Windows SDK 实现的OpenGL,必须写在&gl/gl.h&之前
#include &gl/gl.h&
#include &gl/glut.h&
#include &stdio.h&
#include "GlutApp.h"
class TestApp : public GlutApp
virtual void onSpecialKeyDown( int key, int x, int y )
printf("onKeyDown: %d(%c), &%d, %d&\n", key, key, x, y);
virtual void onSpecialKey( int key, int x, int y )
printf("onSpecialKey: %d(%c), &%d, %d&\n", key, key, x, y);
virtual void onKeyDown( unsigned char key, int x, int y )
printf("onKeyDown: %d(%c), &%d, %d&\n", key, key, x, y);
virtual void onKey( unsigned char key, int x, int y )
printf("onKey: %d(%c), &%d, %d&\n", key, key, x, y);
virtual void onMouseMove( int x, int y )
printf("onMouseMove: %d, %d\n", x, y);
virtual void onMousePress( int button, int state, int x, int y )
printf("onMousePress: %d, %d, %d, %d\n", button, state, x, y);
virtual void onMousePressMove( int x,int y )
printf("onMousePressMove: %d, %d\n", x, y);
virtual void onInit()
printf("OnInit\n");
glClearColor(0.0, 0.0, 0.0, 0.0);
glShadeModel(GL_FLAT);
virtual void onDisplay()
glClear(GL_COLOR_BUFFER_BIT);
// glPolygonMode(GL_FRONT, GL_LINE);
glBegin(GL_TRIANGLES);
glColor3f(1, 0, 0);
glVertex2f(-1, -1);
glVertex2f(1,
glVertex2f(0, 1);
glFlush();
glutSwapBuffers();
virtual void onResize( int w, int h )
printf("resize window: %d, %d\n", w, h);
virtual void onIdle()
void menu1() { printf("menu1 selected!\n"); }
void menu2() { printf("menu2 selected!\n"); }
void fullScreen() { glutFullScreen(); }
void exitApp() { exit(0); }
int main(int argc, char **argv)
test.initGlut(argc, argv);
test.setTitle("AppTest");
test.setWindowsSize(640, 480);
test.setDisplayMode(GLUT_RGBA | GLUT_SINGLE);
test.addRightMenu("menu1", menu1);
test.addRightMenu("menu2", menu2);
test.addRightMenu("full screen", fullScreen);
test.addRightMenu("exit", exitApp);
test.run();
更多开发者职位上
1)">1)">1" ng-class="{current:{{currentPage==page}}}" ng-repeat="page in pages"><li class='page' ng-if="(endIndex<li class='page next' ng-if="(currentPage
相关文章阅读第九讲 OpenGL编程_图文_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
评价文档:
第九讲 OpenGL编程
上传于||文档简介
&&计&#8203;算&#8203;机&#8203;图&#8203;形&#8203;学&#8203;课&#8203;件
大小:6.87MB
登录百度文库,专享文档复制特权,财富值每天免费拿!
你可能喜欢opengl重要函数
扫扫二维码,随身浏览文档
手机或平板扫扫即可继续访问
opengl重要函数
举报该文档为侵权文档。
举报该文档含有违规或不良信息。
反馈该文档无法正常浏览。
举报该文档为重复文档。
推荐理由:
将文档分享至:
分享完整地址
文档地址:
粘贴到BBS或博客
flash地址:
支持嵌入FLASH地址的网站使用
html代码:
&embed src='/DocinViewer-4.swf' width='100%' height='600' type=application/x-shockwave-flash ALLOWFULLSCREEN='true' ALLOWSCRIPTACCESS='always'&&/embed&
450px*300px480px*400px650px*490px
支持嵌入HTML代码的网站使用
您的内容已经提交成功
您所提交的内容需要审核后才能发布,请您等待!
3秒自动关闭窗口

我要回帖

更多关于 glutmainloop 的文章

 

随机推荐