返回

立方体旋转、纹理绘制实现3D动画基础指南

IOS

OpenGL-ES图形编程教程系列:立方体旋转、纹理绘制实现3D动画基础指南

总览

本教程以OpenGL-ES和GLKit为工具,着重于创建一个纹理立方体模型,让它能够根据指定轴进行旋转,并对旋转效果增加光照,最终实现一个完整的3D动画场景。在这个过程中,我们将探讨GLKit的应用、纹理贴图、光照设置等细节,帮助你对3D图形编程的原理有更深入的理解。

准备工作

在开始之前,我们需要先完成一些准备工作,包括导入必要的库和创建相关属性。

导入库

#import <GLKit/GLKit.h>

创建属性

// 创建上下文
EAGLContext *context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];

// 创建视图
GLKView *view = [[GLKView alloc] initWithFrame:self.bounds context:context];

GLKit配置

接下来,我们需要配置GLKit,使其支持3D图形渲染。

view.enableSetNeedsDisplay = NO;

纹理贴图

为了让立方体拥有更逼真的外观,我们将使用纹理贴图。首先,我们加载纹理图片:

UIImage *image = [UIImage imageNamed:@"texture.png"];

然后,将其转换为纹理对象:

GLKTextureInfo *textureInfo = [GLKTextureLoader textureWithCGImage:image.CGImage options:nil error:nil];

光照设置

为了让立方体在3D空间中更真实地呈现,我们需要设置光照。这里我们使用一个简单的光源,如下:

glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);

GLfloat ambientLight[] = { 0.2f, 0.2f, 0.2f, 1.0f };
glLightfv(GL_LIGHT0, GL_AMBIENT, ambientLight);

GLfloat diffuseLight[] = { 0.8f, 0.8f, 0.8f, 1.0f };
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseLight);

GLfloat lightPosition[] = { 0.0f, 1.0f, 2.0f, 1.0f };
glLightfv(GL_LIGHT0, GL_POSITION, lightPosition);

绘制立方体

现在,我们可以开始绘制立方体了。首先,我们定义顶点数据:

GLfloat vertices[] = {
    -0.5f, -0.5f, -0.5f,
    0.5f, -0.5f, -0.5f,
    0.5f,  0.5f, -0.5f,
    -0.5f,  0.5f, -0.5f,
    -0.5f, -0.5f,  0.5f,
    0.5f, -0.5f,  0.5f,
    0.5f,  0.5f,  0.5f,
    -0.5f,  0.5f,  0.5f
};

接着,定义纹理坐标:

GLfloat textureCoords[] = {
    0.0f, 0.0f,
    1.0f, 0.0f,
    1.0f, 1.0f,
    0.0f, 1.0f
};

最后,定义索引数据:

GLuint indices[] = {
    0, 1, 2,
    0, 2, 3,
    4, 5, 6,
    4, 6, 7,
    0, 4, 5,
    0, 3, 7,
    1, 2, 6,
    1, 5, 6,
    0, 1, 4,
    3, 2, 6,
    7, 6, 5,
    7, 5, 4
};

有了这些数据,我们就可以在GLKit中绘制立方体了:

glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 0, vertices);
glEnableVertexAttribArray(GLKVertexAttribPosition);

glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, 0, textureCoords);
glEnableVertexAttribArray(GLKVertexAttribTexCoord0);

glDrawElements(GL_TRIANGLES, sizeof(indices) / sizeof(GLuint), GL_UNSIGNED_INT, indices);

旋转动画

为了让立方体旋转起来,我们需要在每次渲染循环中更新模型视图矩阵。这里我们使用了一个简单的旋转矩阵:

float angle = (float)CFAbsoluteTimeGetCurrent() / 10.0f;

GLKMatrix4 modelViewMatrix = GLKMatrix4MakeRotation(angle, 0.0f, 1.0f, 0.0f);

然后,将其应用到渲染过程中:

glUniformMatrix4fv(uniforms.modelViewMatrix, 1, 0, modelViewMatrix.m);

效果预览

现在,你应该可以看到一个带有纹理贴图、光照效果并能够旋转的立方体了。