linux opengl效率,Ubuntu下使用GLUT编写OpenGL程序

在Linux下以及Windows操作系统下编写OpenGL程序已经变得非常便捷了,我们只需安装freeglut工具包即可。老旧的GLUT已经废弃了,现在如果我们要在一些类Unix系统上编写OpenGL程序的话需要安装FreeGLUT。如果是在Ubuntu上,则输入以下命令即可:

sudo apt-get install freeglut3-dev

现在FreeGLUT最新的稳定版本为3.0.0,因此我们用上述命令即可安装好最新版本的FreeGLUT工具。

接着,我们为了方便编译,可以写一个shell程序,命名为build.sh,如下所示:

clang main.c -std=gnu11 -lglut -lGL -o glutDemo

这里假定我们要编译的C源文件名为main.c。如果各位想用GCC编译的话,只需将上述的clang改写为gcc即可,其他不动。这里我们只需连接libGL与libglut这两个库即可。我们在安装freeglut时,这两个库都会被下载。

下面我们就来看一下main.c源文件内容:

#include

#include

#include

#ifndef var

#define var __auto_type

#endif

static const GLfloat sRectVertices[] = {

// top left

-0.4f, 0.4f,

// bottom left

-0.4f, -0.4f,

// top right

0.4f, 0.4f,

// bottom right

0.4f, -0.4f

};

static const GLfloat sTriangleVertices[] = {

// top center

0.0f, 0.4f,

// bottom left

-0.4f, -0.4f,

// bottom right

0.4f, -0.4f

};

static const GLfloat sColors[] = {

// red

1.0f, 0.0f, 0.0f, 1.0f,

// green

0.0f, 1.0f, 0.0f, 1.0f,

// blue

0.0f, 0.0f, 1.0f, 1.0f,

// white

1.0f, 1.0f, 1.0f, 1.0f

};

static void RenderHandler(void)

{

glClear(GL_COLOR_BUFFER_BIT);

// Draw rectangle

glVertexPointer(2, GL_FLOAT, 0, sRectVertices);

glColorPointer(4, GL_FLOAT, 0, sColors);

glLoadIdentity();

glTranslatef(-0.5f, 0.0f, -2.0f);

glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

// Draw triangle

glVertexPointer(2, GL_FLOAT, 0, sTriangleVertices);

glColorPointer(4, GL_FLOAT, 0, sColors);

glLoadIdentity();

glTranslatef(0.5f, 0.0f, -2.1f);

glDrawArrays(GL_TRIANGLES, 0, 3);

glFlush();

}

int main(int argc, char* argv[])

{

glutInit(&argc, argv);

glutInitDisplayMode(GLUT_SINGLE);

glutInitWindowSize(480, 480);

glutInitWindowPosition(200, 100);

glutCreateWindow("OpenGL GLUT Demo");

glutDisplayFunc(RenderHandler);

var vendor = (const char*)glGetString(GL_VENDOR);

var renderer = (const char*)glGetString(GL_RENDERER);

var version = (const char*)glGetString(GL_VERSION);

printf("The vendor is: %s\n", vendor);

printf("The renderer is: %s\n", renderer);

printf("The GL version is: %s\n", version);

glViewport(0, 0, 480, 480);

glClearColor(0.0f, 0.0f, 0.0f, 1.0f);

glShadeModel(GL_SMOOTH);

glFrontFace(GL_CCW);

glCullFace(GL_BACK);

glEnable(GL_CULL_FACE);

glEnableClientState(GL_VERTEX_ARRAY);

glEnableClientState(GL_COLOR_ARRAY);

glMatrixMode(GL_PROJECTION);

glLoadIdentity();

glOrtho(-1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 3.0f);

glMatrixMode(GL_MODELVIEW);

glutMainLoop();

}

完成之后,我们直接用终端进入main.c与build.sh所在的目录。然后直接执行bash build.sh进行编译,最后生成glutDemo这一可执行文件。我们如果是在命令行直接执行它,那么还能看到当前系统环境中的OpenGL驱动商以及所使用的渲染器名称。

下面再介绍一下如何在GLUT环境下刷新OpenGL渲染,从而可以使得它以一定的帧率进行绘制物体。

#include

#include

#include

#ifndef var

#define var __auto_type

#endif

static const GLfloat sRectVertices[] = {

// top left

-0.4f, 0.4f,

// bottom left

-0.4f, -0.4f,

// top right

0.4f, 0.4f,

// bottom right

0.4f, -0.4f

};

static const GLfloat sTriangleVertices[] = {

// top center

0.0f, 0.4f,

// bottom left

-0.4f, -0.4f,

// bottom right

0.4f, -0.4f

};

static const GLfloat sColors[] = {

// red

1.0f, 0.0f, 0.0f, 1.0f,

// green

0.0f, 1.0f, 0.0f, 1.0f,

// blue

0.0f, 0.0f, 1.0f, 1.0f,

// white

1.0f, 1.0f, 1.0f, 1.0f

};

static int sRotAngle = 0;

static void TimerHandler(int value);

static void RenderHandler(void)

{

// 以50FPS的帧率进行刷新

glutTimerFunc(20, TimerHandler, 0);

glClear(GL_COLOR_BUFFER_BIT);

// Draw rectangle

glVertexPointer(2, GL_FLOAT, 0, sRectVertices);

glColorPointer(4, GL_FLOAT, 0, sColors);

glLoadIdentity();

glTranslatef(-0.5f, 0.0f, -2.0f);

glRotatef(sRotAngle, 0.0f, 0.0f, 1.0f);

glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

// Draw triangle

glVertexPointer(2, GL_FLOAT, 0, sTriangleVertices);

glColorPointer(4, GL_FLOAT, 0, sColors);

glLoadIdentity();

glTranslatef(0.5f, 0.0f, -2.1f);

glRotatef(-sRotAngle, 0.0f, 0.0f, 1.0f);

glDrawArrays(GL_TRIANGLES, 0, 3);

glFlush();

if(++sRotAngle == 360)

sRotAngle = 0;

}

static void TimerHandler(int value)

{

RenderHandler();

}

int main(int argc, char* argv[])

{

glutInit(&argc, argv);

glutInitDisplayMode(GLUT_SINGLE);

glutInitWindowSize(480, 480);

glutInitWindowPosition(200, 100);

glutCreateWindow("OpenGL GLUT Demo");

glutDisplayFunc(RenderHandler);

var vendor = (const char*)glGetString(GL_VENDOR);

var renderer = (const char*)glGetString(GL_RENDERER);

var version = (const char*)glGetString(GL_VERSION);

printf("The vendor is: %s\n", vendor);

printf("The renderer is: %s\n", renderer);

printf("The GL version is: %s\n", version);

glViewport(0, 0, 480, 480);

glClearColor(0.0f, 0.0f, 0.0f, 1.0f);

glShadeModel(GL_SMOOTH);

glFrontFace(GL_CCW);

glCullFace(GL_BACK);

glEnable(GL_CULL_FACE);

glEnableClientState(GL_VERTEX_ARRAY);

glEnableClientState(GL_COLOR_ARRAY);

glMatrixMode(GL_PROJECTION);

glLoadIdentity();

glOrtho(-1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 3.0f);

glMatrixMode(GL_MODELVIEW);

glutMainLoop();

}

GLUT有一个glutTimerFunc函数,用于提供定时器任务。其原型为:

void glutTimerFunc(unsigned int msecs, void (*func)(int value), int value);

这里,msecs用于指定定时器触发的时间间隔,单位为毫秒。参数func则是指向我们自己定义的定时器处理函数。参数value是我们传递给回调函数func的参数值,这个值可以用来标识当前定时器回调函数的状态,可自定义其语义。这里各位要注意的是,glutTimerFunc函数在调用之后只会触发一次定时器,如果我们要不断触发定时器,那么就得将它放在渲染处理函数之中重复调用。

我们运行上述代码之后就能看到一个不断转动的正方形和一个三角形了。不过各位注意到,三角形和正方形在旋转时边缘会出现锯齿。GLUT提供了一种非常便捷的方式来开启OpenGL所实现的多重采样抗锯齿(MSAA)效果。我们只需要在glutInitDisplayMode函数参数中添加上GLUT_MULTISAMPLE标志,然后调用glutSetOption函数来设置样本个数,一般来说用4个样本就足够了。最后使用glEnable(GL_MULTISAMPLE_ARB)来开启多重采样效果即可。

另外,为了使得渲染效率提升,我们也可以使用双缓存机制。我们在glutInitDisplayMode函数参数中添加上GLUT_DOUBLE即可开启双缓存模式。当我们开始渲染一个帧缓存时,调用glutSwapBuffers();函数,切换到另一个帧缓存,使得下一次渲染直接在另一个帧缓存上进行,这样即便当前渲染的速度稍慢也不会对帧率产生太大影响。当然,使用双缓存的话,OpenGL所要花费的存储空间肯定要增大,这就是所谓的用空间来换时间。下面请看代码:

#include

#include

#include

#ifndef var

#define var __auto_type

#endif

static const GLfloat sRectVertices[] = {

// top left

-0.4f, 0.4f,

// bottom left

-0.4f, -0.4f,

// top right

0.4f, 0.4f,

// bottom right

0.4f, -0.4f

};

static const GLfloat sTriangleVertices[] = {

// top center

0.0f, 0.4f,

// bottom left

-0.4f, -0.4f,

// bottom right

0.4f, -0.4f

};

static const GLfloat sColors[] = {

// red

1.0f, 0.0f, 0.0f, 1.0f,

// green

0.0f, 1.0f, 0.0f, 1.0f,

// blue

0.0f, 0.0f, 1.0f, 1.0f,

// white

1.0f, 1.0f, 1.0f, 1.0f

};

static int sRotAngle = 0;

static void TimerHandler(int value);

static void RenderHandler(void)

{

// 以50FPS的帧率进行刷新

glutTimerFunc(20, TimerHandler, 0);

glClear(GL_COLOR_BUFFER_BIT);

// Draw rectangle

glVertexPointer(2, GL_FLOAT, 0, sRectVertices);

glColorPointer(4, GL_FLOAT, 0, sColors);

glLoadIdentity();

glTranslatef(-0.5f, 0.0f, -2.0f);

glRotatef(sRotAngle, 0.0f, 0.0f, 1.0f);

glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

// Draw triangle

glVertexPointer(2, GL_FLOAT, 0, sTriangleVertices);

glColorPointer(4, GL_FLOAT, 0, sColors);

glLoadIdentity();

glTranslatef(0.5f, 0.0f, -2.1f);

glRotatef(-sRotAngle, 0.0f, 0.0f, 1.0f);

glDrawArrays(GL_TRIANGLES, 0, 3);

glFlush();

glutSwapBuffers();

if(++sRotAngle == 360)

sRotAngle = 0;

}

static void TimerHandler(int value)

{

RenderHandler();

}

int main(int argc, char* argv[])

{

glutInit(&argc, argv);

glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_MULTISAMPLE);

glutInitWindowSize(480, 480);

glutInitWindowPosition(200, 100);

glutCreateWindow("OpenGL GLUT Demo");

glutSetOption(GLUT_MULTISAMPLE, 4);

glutDisplayFunc(RenderHandler);

var vendor = (const char*)glGetString(GL_VENDOR);

var renderer = (const char*)glGetString(GL_RENDERER);

var version = (const char*)glGetString(GL_VERSION);

printf("The vendor is: %s\n", vendor);

printf("The renderer is: %s\n", renderer);

printf("The GL version is: %s\n", version);

glViewport(0, 0, 480, 480);

glClearColor(0.0f, 0.0f, 0.0f, 1.0f);

glShadeModel(GL_SMOOTH);

glFrontFace(GL_CCW);

glCullFace(GL_BACK);

glEnable(GL_CULL_FACE);

glEnable(GL_MULTISAMPLE_ARB);

glEnableClientState(GL_VERTEX_ARRAY);

glEnableClientState(GL_COLOR_ARRAY);

glMatrixMode(GL_PROJECTION);

glLoadIdentity();

glOrtho(-1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 3.0f);

glMatrixMode(GL_MODELVIEW);

glutMainLoop();

}

这样一来,我们就能看到既流畅,又光滑的正方形与三角形了~ ^o^

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了小程序应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值