ubuntu+opengl程序设计(4) 使用双缓
--lihn1987(转载请注明作者,谢谢)
哈哈,今天想把上传的代码加上语法高亮,可是怎么做呢?
因为我用来编辑上传到博客的编辑器是 openoffice,而我所使用的代码编辑工具是 VIM
VIM中我是设置了语法高亮的,于是我在 VIM中使用了一条命令 Tohtml
于是就转化出来了 html版本的源代码,代语法高亮的
然后由于 openoffice这种办公软件是支持 html格式复制的,于是遍将代语法高亮的 html复制出来拉!!!哇咔咔~~~~~~
这次要做的是一个代双缓存的,会移动的, 2D的, opengl其中红色的小方块会不停的移动
上图:
show代码:
#include <GL/glut.h>
#include <stdlib.h>
#include <stdio.h>
// Initial square position and size
GLfloat x = 0.0f ;
GLfloat y = 0.0f ;
GLfloat rsize = 25 ;
// Step size in x and y directions
// (number of pixels to move each time)
GLfloat xstep = 1.0f ;
GLfloat ystep = 1.0f ;
// Keep track of windows changing width and height
GLfloat windowWidth;
GLfloat windowHeight;
///
// Called to draw scene
void RenderScene(void )
{
// Clear the window with current clearing color
glClear(GL_COLOR_BUFFER_BIT);
// Set current drawing color to red
// R G B
glColor3f(1.0f , 0.0f , 0.0f );
// Draw a filled rectangle with current color
glRectf(x, y, x + rsize, y - rsize);
// Flush drawing commands and swap
glutSwapBuffers();
}
///
// Called by GLUT library when idle (window not being
// resized or moved)
void TimerFunction(int value)
{
// Reverse direction when you reach left or right edge
if (x > windowWidth-rsize || x < -windowWidth)
xstep = -xstep;
// Reverse direction when you reach top or bottom edge
if (y > windowHeight || y < -windowHeight + rsize)
ystep = -ystep;
// Actually move the square
x += xstep;
y += ystep;
// Check bounds. This is in case the window is made
// smaller while the rectangle is bouncing and the
// rectangle suddenly finds itself outside the new
// clipping volume
if (x > (windowWidth-rsize + xstep))
x = windowWidth-rsize-1 ;
else if (x < -(windowWidth + xstep))
x = -windowWidth -1 ;
if (y > (windowHeight + ystep))
y = windowHeight-1 ;
else if (y < -(windowHeight - rsize + ystep))
y = -windowHeight + rsize - 1 ;
// Redraw the scene with new coordinates
glutPostRedisplay();
glutTimerFunc(33 ,TimerFunction, 1 );
}
///
// Setup the rendering state
void SetupRC(void )
{
// Set clear color to blue
glClearColor(0.0f , 0.0f , 1.0f , 1.0f );
}
///
// Called by GLUT library when the window has chanaged size
void ChangeSize(int w, int h)
{
GLfloat aspectRatio;
// Prevent a divide by zero
if (h == 0 )
h = 1 ;
// Set Viewport to window dimensions
glViewport(0 , 0 , w, h);
// Reset coordinate system
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
// Establish clipping volume (left, right, bottom, top, near, far)
aspectRatio = (GLfloat)w / (GLfloat)h;
if (w <= h)
{
windowWidth = 100 ;
windowHeight = 100 / aspectRatio;
glOrtho (-100.0 , 100.0 , -windowHeight, windowHeight, 1.0 , -1.0 );
}
else
{
windowWidth = 100 * aspectRatio;
windowHeight = 100 ;
glOrtho (-windowWidth, windowWidth, -100.0 , 100.0 , 1.0 , -1.0 );
}
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
///
// Main program entry point
int main(int argc, char * argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowSize(800 ,600 );
glutCreateWindow("Bounce" );
glutDisplayFunc(RenderScene);
glutReshapeFunc(ChangeSize);
glutTimerFunc(33 , TimerFunction, 1 );
SetupRC();
glutMainLoop();
return 0 ;
}
这次的代码和上次的比起来大部分都 是相同的,比如 ChangeSize 函数阿, RenderScene 函数阿,相同的地方都很多,但是呢,我们首先介绍下这些大部分相同的部分有那些变化
首先是
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
这句话
从前我们使用的是
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB );
根据我们的了解,这个变化的参数 GLUT_DOUBLE 意思是使用双缓冲,而非从 前的单缓冲。
至于这些函数到底的意义是什么呢? 我觉得有必要告诉大家如何去查 opengl官方对其的描述。
这里 http://www.opengl.org/sdk/docs/man/就是 OpenGL 2.1 Reference Pages
另外一个函数
RenderScene
该函数是我们用来初始化当前界面 场景的,当我们使用双缓存的时候,里面的绘图函数也有了一些区别
曾经使用的 glFlush() ; 变成了 glutSwapBuffers()
以下是官网对其的解释
glutSwapBuffers swaps the buffers of the current window if double buffered.
Usage
void glutSwapBuffers(void);
Description
Performs a buffer swap on the layer in use for the current window . Specifically, glutSwapBuffers promotes the contents of the back buffer of the layer in use of the current window to become the contents of the front buffer. The contents of the back buffer then become undefined. The update typically takes place during the vertical retrace of the monitor, rather than immediately after glutSwapBuffers is called.
An implicit glFlush is done by glutSwapBuffers before it returns. Subsequent OpenGL commands can be issued immediately after calling glutSwapBuffers, but are not executed until the buffer exchange is completed.
If the layer in use is not double buffered, glutSwapBuffers has no effect
具体意思大概是说
只有当我们使用双缓冲的时候,该函 数才会有作用,而作用是使当前缓冲区背面的内容显示出来,其实也是调用了 glFlash 进行刷新,不过是在函数返回前就进行了隐式的调用。
另外我们还要看一个第一次见到的回 调函数
void glutTimerFunc(unsigned int msecs, void (*Func)(int value), int value);
光凭我们程序员的直觉,我们应该能够想到,该函数是一个定时器,
其函数的意思也就是在 msecs 毫秒后调用 Func 函数,并为 Func 函数传入的参数值 value
我们在看看这个定时器的回调函数
TimerFunction
该函数的作用也就是随着时间移动我们的红色矩形块
其中调用到了一个没有见过的函数
glutPostRedisplay 其实是告诉操作系统,该区域需要重绘