立体图形3D动画和绘制

做了一个关于立体图形3D动画和绘制图形的例子,效果如下:

这个是参照苹果官方文档和例子来写的,其中茶壶是根据点、颜色渲染、网格结构和灯光效果来绘制出来的。

再说实现步骤前我们需要了解一下概念:

GLKView:作为OpenGLES内容的呈现目标

GLKViewController: 内容呈现的控制和动画,视图管理和维护一个framebuffer,应用只需在framebuffer进行绘画即可

GLKView 和GLKViewController类提供一个标准的OpenGLES视图和相关联的呈现循环

EAGLContext:实现和提供一个呈现环境

GLuint、GLfloat:其实就是typedef int和float的别名,当我们编写代码时不要被这些苹果的别名给吓到。

GLKTextureLoader:提供从iOS支持的各种图像格式的源自动加载纹理图像到OpenGLES 图像环境的方式,并能够进行适当的转换,并支持同步和异步加载方式

GLKMatrix4:一个unit共用体,是一个4*4的矩阵。

GLKBaseEffect:OpenGL ES 1.1规范中的关键的灯光和材料模式

好了,还有其他的概念性的东西可以下方留言,我将进行回答,也可以自己谷歌。

1.将所需系统库导入工程


2.创建一个GLKViewController类。

重写一个继承类,然后将view改为GLKView。

@interface PDTeapotViewController : GLKViewController
{
    EAGLContext *context;    // 实现和提供一个呈现环境
    GLuint mode;
    // 茶壶
    GLfloat rot;
    // 正方体
    GLfloat cubePos[3];
    GLfloat cubeRot;
    GLuint cubeTexture;
}

@property (nonatomic, strong) PDTeapotBaseEffect *innerCircle;
@property (nonatomic, strong) PDTeapotBaseEffect *outerCircle;
@property (nonatomic, strong) PDTeapotBaseEffect *teapot;
@property (nonatomic, strong) NSMutableArray *cubeEffectArr;
@property (nonatomic, strong) PDMusicCube *musicCube;

@end
并且分别在类中创建效果路径、茶壶、正方体、和控制背景音乐。

- (void)viewDidLoad {
    [super viewDidLoad];
    
    context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
    // 创建环境失败,或者将当前线程环境设置失败
    if (!context || ![EAGLContext setCurrentContext:context]) {
        return;
    }
    GLKView *glView = (GLKView *)self.view;
    glView.context = context;
    glView.drawableDepthFormat = GLKViewDrawableDepthFormat16;
    
    mode = 1;
    glEnable(GL_DEPTH_TEST);
    
    // 创建效果路径
    self.innerCircle = [PDTeapotBaseEffect makeCircleWithNumOfSegments:circleSegments radius:pathCircleRadius];
    self.outerCircle = [PDTeapotBaseEffect makeCircleWithNumOfSegments:circleSegments radius:pathOutCircleRadius];
    
    // 创建茶壶
    self.teapot = [PDTeapotBaseEffect makeTeapot];
    
    // 创建正方体
    self.cubeEffectArr = [PDTeapotBaseEffect makeCube];
    
    [self setUpCubeEffect];
    
    [self setUpMusicCube];
}
3.创建一个材料和效果类

#import "PDTeapotBaseEffect.h"

用来创建图形

<span style="font-size:12px;">#define kTeapotScale		1.8
#define kCubeScale			0.12
#define kButtonScale		0.1

#define kButtonLeftSpace	1.1

#define	DegreesToRadians(x) ((x) * M_PI / 180.0)

#define BUFFER_OFFSET(i) ((char *)NULL + (i))

static const CGFloat pathCircleRadius = 1.0;  // 运动路径内环
static const CGFloat pathOutCircleRadius = 1.1;  // 运动路径外环
static const GLuint circleSegments = 36;

// 效果类
@interface PDTeapotBaseEffect : NSObject

@property (nonatomic, strong) GLKBaseEffect *effect; // 效果类,灯光和材料模式效果
@property (nonatomic, assign) GLuint vertexArray;    // GLuint基础类型
@property (nonatomic, assign) GLuint vertexBuffer;
@property (nonatomic, assign) GLuint normalBuffer;


/**
 *  创建运动轨迹
 */
+ (instancetype)makeCircleWithNumOfSegments:(GLuint)segments radius:(GLfloat)radius;

/**
 *  创建茶壶
 */
+ (instancetype)makeTeapot;

/**
 *  创建正方体
 */
+ (NSMutableArray *)makeCube;

/**
 *  背景音乐的播放
 */
+ (void)musicBack;</span>


例如创建一个茶壶代码:

PDTeapotBaseEffect *teapot = [[PDTeapotBaseEffect alloc] init];
    GLKBaseEffect *effect = [[GLKBaseEffect alloc] init];
    // 材料
    effect.material.ambientColor = GLKVector4Make(0.4, 0.8, 0.4, 1.0);
    effect.material.diffuseColor = GLKVector4Make(1.0, 1.0, 1.0, 1.0);
    effect.material.specularColor = GLKVector4Make(1.0, 1.0, 1.0, 1.0);
    effect.material.shininess = 100.0;
    // 光
    effect.light0.enabled = GL_TRUE;
    effect.light0.ambientColor = GLKVector4Make(0.2, 0.2, 0.2, 1.0);
    effect.light0.diffuseColor = GLKVector4Make(0.2, 0.7, 0.2, 1.0);
    effect.light0.position = GLKVector4Make(0.0, 0.0, 1.0, 0.0);
    
    GLuint vertexArray, vertexBuffer, normalBuffer;
    
    glGenVertexArraysOES(1, &vertexArray);
    glBindVertexArrayOES(vertexArray);
    
    // 位置
    glGenBuffers(1, &vertexBuffer);
    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(teapot_vertices), teapot_vertices, GL_STATIC_DRAW);
    
    glEnableVertexAttribArray(GLKVertexAttribPosition);
    glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
    
    glGenBuffers(1, &normalBuffer);
    glBindBuffer(GL_ARRAY_BUFFER, normalBuffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(teapot_normals), teapot_normals, GL_STATIC_DRAW);
    
    glEnableVertexAttribArray(GLKVertexAttribNormal);
    glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
    
    glBindVertexArrayOES(0);
    
    teapot.effect = effect;
    teapot.vertexArray = vertexArray;
    teapot.vertexBuffer = vertexBuffer;
    teapot.normalBuffer = normalBuffer;
    return teapot;

4.利用glkView:drawInRect:函数做绘制和重绘

关于glkView:drawInRect:我要解释一下:

使用GLKit视图绘制OpenGL内容需要三个子步骤:准备OpenGLES基础;发布绘制命令;呈现显示内容到Core Animation。       GLKit类本身已经实现了第一个和第三个步骤,用户只需实现第二个步骤,在视图的方法drawRect或视图的代理对象的glkView:drawInRect:中调用适当的OpenGLES绘制命令进行内容绘制。

代码如下(由于代码比较多,我将部分粘贴,其余部分参照我的github例子 ps:下载时给颗星最好了。。。。):

<span style="font-size:12px;">#pragma mark - 重绘
- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
{
    glClearColor(0.0, 0, 0, 1.0);
    glClearDepthf(1.0);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
    GLfloat aspectRatio = (GLfloat)(view.drawableWidth) / (GLfloat)(view.drawableHeight);
    GLKMatrix4 projectionMatrix = GLKMatrix4MakeOrtho(-1.0f, 1.0f, -1.0f/aspectRatio, 1.0f/aspectRatio, -10.0f, 10.0f);
    projectionMatrix = GLKMatrix4Rotate(projectionMatrix, DegreesToRadians(-30.0f), 0.0f, 1.0f, 0.0f);
    
    // set the projection matrix
    self.innerCircle.effect.transform.projectionMatrix = projectionMatrix;
    self.outerCircle.effect.transform.projectionMatrix = projectionMatrix;
    self.teapot.effect.transform.projectionMatrix = projectionMatrix;
    for (int f=0; f<6; f++)
        ((PDTeapotBaseEffect *)self.cubeEffectArr[f]).effect.transform.projectionMatrix = projectionMatrix;
    
    glBindVertexArrayOES(self.innerCircle.vertexArray);
    [self.innerCircle.effect prepareToDraw];
    glDrawArrays (GL_LINE_LOOP, 0, circleSegments);
    
    glBindVertexArrayOES(self.outerCircle.vertexArray);
    [self.outerCircle.effect prepareToDraw];
    glDrawArrays (GL_LINE_LOOP, 0, circleSegments);
    
    [self drawTeapotAndUpdatePlayback];
    
    [self drawCube];
}</span>
好了,关于整个项目其他不动的地方可以参照, 图像编程总结
下面是大家最想要的   github源码



  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 3D动画是一个使用计算机软件制作三维立体图像的动态效果的过程。它通过创建三维模型,并在其中进行各种操作(如移动、旋转、缩放等),将一帧帧的图像组合在一起以创建一个流畅的动画效果。 在制作3D动画的过程中,制作人员需要使用专业的3D软件,如Maya、3ds Max、Cinema 4D等,来模拟真实世界中的物理效果,如重力、光照和阴影等。他们还需要考虑角色的运动和表情,以及动画的背景和音效,以创建一个逼真的动画效果。 总的来说,3D动画是一个复杂而又有趣的制作过程,需要许多专业技能和技巧,以及对动画原理和视觉效果的精确掌握。 ### 回答2: 3D动画是一种使用计算机生成的动画形式。它的制作过程包括以下几个步骤: 首先,我们需要有一个初始的想法或概念。这个概念可以是一个角色、一个场景、一个物体或一个故事情节。 接下来,我们使用专业的3D建模软件来构建和绘制这些场景、角色或物体的模型。建模可以通过多边形网格的形式来进行,或者通过雕刻等其他方式来实现。 完成建模后,我们需要给模型添加材质和纹理。材质和纹理可以使模型看起来更真实,并且给予其表面的颜色、反射率、光泽等特性。 一旦模型有了外观和表面特性,我们就要为其添加骨骼或关节系统。这是为了使模型能够进行骨骼动画,也就是给予模型一定的运动和动作。 完成骨骼系统后,我们可以为模型设置关键帧和路径。通过这些设置,我们可以控制模型在动画中的移动、旋转和其他变化。同时,我们还可以添加其他特效,如粒子效果、烟雾效果等。 最后,我们需要将模型渲染和呈现出来。通过渲染,我们可以对模型进行光照、阴影、运动模糊等效果的处理。渲染后的动画输出可以是视频文件或图像序列,可以进行后期处理和编辑。 总的来说,3D动画制作过程涉及到构建模型、创建材质和纹理、设定骨骼和动画路径、添加特效,最后通过渲染和呈现来完成制作。这个过程需要综合运用建模、纹理、动画、渲染等多种技术,并需要一定的创意和艺术修养。 ### 回答3: 3D动画是利用计算机图形技术创建并模拟三维场景的过程。下面将介绍3D动画的基本过程。 首先,3D动画制作的第一步是概念设计和规划。动画师首先需要确定他们想要创造的场景和角色的外观,并制定一个详细的计划,包括故事情节和动画的时间轴。 接下来是建模阶段。在这一阶段中,动画师使用专业的3D建模软件,根据概念设计,创造出动画中的角色、道具和场景等三维模型。建模是一个艺术和技术结合的过程,需要有良好的空间感和创造力。 完成建模后,就是材质和纹理的添加。动画师需要为每一个3D模型赋予逼真的纹理和光线效果,以提高逼真度和质感。这包括在模型上添加颜色、纹理以及调整光线和阴影等效果。 接下来就是骨骼绑定和动画制作了。在这一阶段中,动画师为角色模型添加骨骼系统,用于控制角色的动作和姿态。然后,动画师会根据动画的要求,使用关键帧动画或运动捕捉等技术来制作角色的动作。 动画完成后,就是渲染和后期制作阶段。在这一阶段中,将3D场景中的模型和角色与环境和光源相结合,通过渲染引擎将其转化为视觉图像。后期制作包括颜色校正、特效添加和音效设计等,以提升动画的视觉效果和感受。 最后是输出和呈现。动画制作完成后,可以选择将其输出为视频文件或动画渲染序列,以供观众观看。 综上所述,3D动画制作是一个复杂而精细的过程,涉及到概念设计、建模、材质纹理添加、动画制作、渲染和后期制作等多个步骤,需要艺术和技术能力的综合运用。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值