http://www.helmsmansoft.com/index.php/archives/1483
在前两节教程中介绍的是在3D环境中绘制2D图形,只是简单的绘制,所有图形都是静态绘制的,并且只进行了一次绘制,如果当图形或者物体是运行的时候,显然这样是不行的。那该怎么办呢?这就是本节课程所要涉及的内容。
在这里涉及倒游戏循环和定时器的概念,下面先来说说关于机器本身的属性:
在iPhone的硬件上,屏幕的刷新频率为60Hz.OpenGL渲染引擎每秒只能交换屏幕缓冲区60次。更重要的是,缓冲区交换代码会等待屏幕完全刷新之后才能切换到下一帧图像,也就是说在iPhone上能获得的最高帧率为60fps. 如果代码能在1/60秒的时间内处理完一帧,那么动画会很流畅,否则就会造成问题。
在代码中会存在两种不同的帧率:一个是游戏代码执行的速率;另一个是用户实际看到的帧率。为了处理游戏执行速率和用户时间看到的帧率之间的问题,Apple在IOS中引入了显示链接(display link),显示链接是硬件触发的一个回调函数,每次屏幕刷新时会调用对象上的一个指定方法。这个对象命名为CADisplayLink.不过它只适用于ios 3.1,所以本教程并不适用这个方法。
这里使用定时器来动态的刷新
由于本教程是连续的,所以教程使用的模板都是一样的,如果您还没有下载模板,可以在本教程的前2课寻找并下载。
好了,在RenderView.h中添加属性
NSTimer * _animationTimer;
NSTimeInterval timeInterval;
//--------------------------------
@property (nonatomic, retain) NSTimer * animationTimer;
@property (nonatomic, assign) NSTimeInterval timeInterval;
在RenderView.m中添加如下代码:
@synthesize animationTimer = _animationTimer;
@synthesize timeInterval;
//------------------------------------
//添加以下方法
//动画循环
- (void)startAnimation
{
_animationTimer = [NSTimer scheduledTimerWithTimeInterval:timeInterval target:self selector:@selector(gameRunLoop) userInfo:nil repeats:YES];
}
//设置时间间隔并启动动画
- (void)setTimeIntervalAndStartScene
{
timeInterval = 1.0 / 60.0; //设置动画帧时间的间隔
[self startAnimation]; //调用定时器启动循环
}
//调用render方法循环渲染
- (void)gameRunLoop
{
[self render];
}
//render方法为修改,大部分没有变化,修改如下:
//渲染方法
- (void)render
{
static GLfloat rotation = 0.0; //初始化旋转角度
static CGFloat spinnySquareVertices[8] = {
-0.5f, -0.5f,
0.5f, -0.5f,
-0.5f, 0.5f,
0.5f, 0.5f,
};
static CGFloat spinnSquareColor[] = {
255,255,0,255,
0,255,255,255,
0,0,0,0,
255,0,255,255,
};
glClearColor(0.1f, 0.8f, 1.0f, 1.0f); //设置清屏颜色
glClear(GL_COLOR_BUFFER_BIT); //清屏
glViewport(0, 0, backingWidth, backingHeight); //设置视口
// glMatrixMode(GL_PROJECTION);
glLoadIdentity(); //清空当前矩阵,还原默认矩阵 //new
glOrthof(-1.0f, 1.0f, -1.5f, 1.5f, -1.0f, 1.0f); //正交模式下可视区域 //new
glColor4f(1.0, 1.0, 0.0, 1.0); //绘制的颜色
glVertexPointer(2, GL_FLOAT, 0, spinnySquareVertices); //确定使用的顶点坐标数列的位置和尺寸
glEnableClientState(GL_VERTEX_ARRAY); //启动独立的客户端功能,告诉OpenGL将会使用一个由glVertexPointer定义的定点数组
glColorPointer(4, GL_FLOAT, 0, spinnSquareColor);
glEnableClientState(GL_COLOR_ARRAY);
glRotatef(rotation, 0.0, 0.0, 1.0); //旋转 //new
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); //进行连续不间断的渲染,在渲染缓冲区有了一个准备好的要渲染的图像
rotation += 0.5;
[_context presentRenderbuffer:GL_RENDERBUFFER_OES]; //将渲染缓冲区的内容呈现到屏幕上
}
上面的NSTimer方法相信大家都已经很熟悉了,就不多说了,作用就是每1/60秒循环调用方法。在render方法里,使用static静态标示定义了一个角度变量。
glOrthof(-1.0f, 1.0f, -1.5f, 1.5f, -1.0f, 1.0f); 4个参数依次为:最左边的值,最右边的值,上界,下界,近界,远界。
glRotatef(rotation, 0.0, 0.0, 1.0) 实现围绕z轴进行旋转.
运行以上代码,如下图:一个围绕z轴进行旋转的正方形
www.helmsmansoft.com
除了以上的旋转方法还有以下方法:
glTranslatef(x,y,z); //平移到指定位置
glScalef(xScale,yScale,zScale); //缩放