89
3D Graphics on iPhone Douglass Turner [email protected] @dugla #iphonemeetup3dtalkacton

3D Graphics on iPhone

Embed Size (px)

Citation preview

Page 1: 3D Graphics on iPhone

3D Graphics on iPhone

Douglass Turner

[email protected]@dugla #iphonemeetup3dtalkacton

Page 2: 3D Graphics on iPhone

A talk in three acts ...

Page 3: 3D Graphics on iPhone

• Intro to Computer Graphics

• Computer Graphics in OpenGL

• OpenGL and CocoaTouch Playing Nice Together

Page 4: 3D Graphics on iPhone

Intro to Computer Graphics

(a trip down the graphics pipeline)

Page 5: 3D Graphics on iPhone

Build and Tesselate Model

Copyright Steve Jubinville

Page 6: 3D Graphics on iPhone

Pose Model

Copyright Steve Jubinville

Page 7: 3D Graphics on iPhone

Aim Camera

Page 8: 3D Graphics on iPhone

Design Appearance. Light Scene.

Copyright © 2006 Holger Schömann

Page 9: 3D Graphics on iPhone

Copyright © 2006 Florian Wild

Design Appearance. Light Scene.

Page 10: 3D Graphics on iPhone

Copyright © 2006 Jack Qiao

Design Appearance. Light Scene.

Page 11: 3D Graphics on iPhone

Render Scene

Page 12: 3D Graphics on iPhone

Cull & clip model triangles to viewing frustrum.

Page 13: 3D Graphics on iPhone

From models to pixels. Scanline interpolation.

• Depth Comparison

• Apply Appearance - Vertex level. Pixel level.

• Composite Elements

Rasterize

Page 14: 3D Graphics on iPhone

Present Image

Page 15: 3D Graphics on iPhone

Update Model State

Page 16: 3D Graphics on iPhone

Rinse, repeat.

Page 17: 3D Graphics on iPhone

Computer Graphics in OpenGL

Page 18: 3D Graphics on iPhone

OpenGL Cocoa

Page 19: 3D Graphics on iPhone

OpenGL is old school

Page 20: 3D Graphics on iPhone

You are flipping levers on a state machine.

Page 21: 3D Graphics on iPhone

float foo[]

Data Structures are for wimps.

glPushMatrix() and glPopMatrix()

Page 22: 3D Graphics on iPhone

OpenGL is a dragster. Not a Prius. Just buckle up ...

Page 23: 3D Graphics on iPhone

... and enjoy the ride, baby!

Page 24: 3D Graphics on iPhone

iPhone 3GS by the Numbers(via AnandTech http://bit.ly/1pQaJO)

~7M triangles / second

~230,000 realtime triangles (30fps)

iPhone display: 320 * 480 = 153,600 pixels

230,000 / 153,600 = ~1.5 realtime-triangles / pixel

;-)

Page 25: 3D Graphics on iPhone

OpenGL websites are a bit differentthan Cocoa websites ...

Page 26: 3D Graphics on iPhone

Isn’t that sweet ...

Page 27: 3D Graphics on iPhone

Um... WTF?

Page 28: 3D Graphics on iPhone

Can’t you just feel the love?

Page 29: 3D Graphics on iPhone

Dude. I think my eyes are bleeding.

Page 30: 3D Graphics on iPhone

No worries. safari.oreilly.com is your friend

Page 31: 3D Graphics on iPhone

Pose Model

Hierarchical Modeling. Transformation Stacks. Coordinate Frames.

Page 32: 3D Graphics on iPhone

Pose Model

Page 33: 3D Graphics on iPhone

You are already familiar with hierarchical modeling and coordinate frames.

Page 34: 3D Graphics on iPhone

[self.parentView addSubview:childView];

for (UIView *v in self.containerView.subviews) { CGRect bounds = [v convertRect:v.bounds toView:scrollView]; if (CGRectIntersectsRect(bounds, scrollView.bounds)) { NSLog(@"View %d is visible", v.tag); } else { NSLog(@"View %d is hidden", v.tag); } } // for (self.containerView.subviews)

or ...

You are already familiar with hierarchical modeling and coordinate frames.

Page 35: 3D Graphics on iPhone

You are already already familiar with transformations.

- (void)setTransform:(CGAffineTransform)newValue { // Scale along x-axis only CGAffineTransform constrainedTransform = CGAffineTransformScale(CGAffineTransformIdentity, newValue.a, 1.0);

newValue.a = constrainedTransform.a; newValue.b = constrainedTransform.b; newValue.c = constrainedTransform.c; newValue.d = constrainedTransform.d; [super setTransform:newValue]; }

Page 36: 3D Graphics on iPhone

HelloTeapot Demo

Source: http://github.com/turner/HelloTeapot

Page 37: 3D Graphics on iPhone

HelloTeapot Code Walkthrough

Page 39: 3D Graphics on iPhone

// Position Camera glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glLoadMatrixf(_openGLCameraInverseTransform);

// Position Light glPushMatrix(); glMultMatrixf(_cameraTransform); glEnable(GL_LIGHT3); glLightfv(GL_LIGHT3, GL_DIFFUSE, spotLight);

glPopMatrix();

// Position Model glPushMatrix();

JLMMatrix3DSetZRotationUsingDegrees(rotation, -45.0f); JLMMatrix3DSetScaling(scale, sx, sy, sz); JLMMatrix3DMultiply(rotation, scale, concatenation); glMultMatrixf(concatenation);

// Render for(int i = 0; i < num_teapot_indices; i += new_teapot_indicies[i] + 1) {

glDrawElements(GL_TRIANGLE_STRIP, indices[i], GL_UNSIGNED_SHORT, &indices[i+1]);

} // for (num_teapot_indices)

glPopMatrix();

http://github.com/turner/HelloTeapot/blob/master/Classes/GLViewController.[hm]

Page 40: 3D Graphics on iPhone

// Position Camera glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glLoadMatrixf(_openGLCameraInverseTransform);

// Position Light glPushMatrix(); glMultMatrixf(_cameraTransform); glEnable(GL_LIGHT3); glLightfv(GL_LIGHT3, GL_DIFFUSE, spotLight);

glPopMatrix();

// Position Model glPushMatrix();

JLMMatrix3DSetZRotationUsingDegrees(rotation, -45.0f); JLMMatrix3DSetScaling(scale, sx, sy, sz); JLMMatrix3DMultiply(rotation, scale, concatenation); glMultMatrixf(concatenation);

// Render for(int i = 0; i < num_teapot_indices; i += new_teapot_indicies[i] + 1) {

glDrawElements(GL_TRIANGLE_STRIP, indices[i], GL_UNSIGNED_SHORT, &indices[i+1]);

} // for (num_teapot_indices)

glPopMatrix();

http://github.com/turner/HelloTeapot/blob/master/Classes/GLViewController.[hm]

Pose Model

Page 41: 3D Graphics on iPhone

// Position Camera glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glLoadMatrixf(_openGLCameraInverseTransform);

// Position Light glPushMatrix(); glMultMatrixf(_cameraTransform); glEnable(GL_LIGHT3); glLightfv(GL_LIGHT3, GL_DIFFUSE, spotLight);

glPopMatrix();

// Position Model glPushMatrix();

JLMMatrix3DSetZRotationUsingDegrees(rotation, -45.0f); JLMMatrix3DSetScaling(scale, sx, sy, sz); JLMMatrix3DMultiply(rotation, scale, concatenation); glMultMatrixf(concatenation);

// Render for(int i = 0; i < num_teapot_indices; i += new_teapot_indicies[i] + 1) {

glDrawElements(GL_TRIANGLE_STRIP, indices[i], GL_UNSIGNED_SHORT, &indices[i+1]);

} // for (num_teapot_indices)

glPopMatrix();

http://github.com/turner/HelloTeapot/blob/master/Classes/GLViewController.[hm]

Light Scene

Page 42: 3D Graphics on iPhone

// Position Camera glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glLoadMatrixf(_openGLCameraInverseTransform);

// Position Light glPushMatrix(); glMultMatrixf(_cameraTransform); glEnable(GL_LIGHT3); glLightfv(GL_LIGHT3, GL_DIFFUSE, spotLight);

glPopMatrix();

// Position Model glPushMatrix();

JLMMatrix3DSetZRotationUsingDegrees(rotation, -45.0f); JLMMatrix3DSetScaling(scale, sx, sy, sz); JLMMatrix3DMultiply(rotation, scale, concatenation); glMultMatrixf(concatenation);

// Render for(int i = 0; i < num_teapot_indices; i += new_teapot_indicies[i] + 1) {

glDrawElements(GL_TRIANGLE_STRIP, indices[i], GL_UNSIGNED_SHORT, &indices[i+1]);

} // for (num_teapot_indices)

glPopMatrix();

http://github.com/turner/HelloTeapot/blob/master/Classes/GLViewController.[hm]

Aim Camera ...

Dude, where is the camera ...?

Page 43: 3D Graphics on iPhone

camera teapot

world

wTtwTc

Page 44: 3D Graphics on iPhone

camera teapot

glMatrixMode(GL_MODELVIEW);glLoadMatrixf(_openGLCameraInverseTransform);

?

cTt

Page 45: 3D Graphics on iPhone

camera teapot

world

wTt(wTc)

cTt

cTt wTtcTw *=

-1

Page 46: 3D Graphics on iPhone

cTt wTtcTw *=

Page 47: 3D Graphics on iPhone

// Position Camera glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glLoadMatrixf(_openGLCameraInverseTransform);

// Position Light glPushMatrix(); glMultMatrixf(_cameraTransform); glEnable(GL_LIGHT3); glLightfv(GL_LIGHT3, GL_DIFFUSE, spotLight);

glPopMatrix();

// Position Model glPushMatrix();

JLMMatrix3DSetZRotationUsingDegrees(rotation, -45.0f); JLMMatrix3DSetScaling(scale, sx, sy, sz); JLMMatrix3DMultiply(rotation, scale, concatenation); glMultMatrixf(concatenation);

// Render for(int i = 0; i < num_teapot_indices; i += new_teapot_indicies[i] + 1) {

glDrawElements(GL_TRIANGLE_STRIP, indices[i], GL_UNSIGNED_SHORT, &indices[i+1]);

} // for (num_teapot_indices)

glPopMatrix();

http://github.com/turner/HelloTeapot/blob/master/Classes/GLViewController.[hm]

cTt wTtcTw *=

Page 48: 3D Graphics on iPhone

- (void)placeCameraAtLocation:(M3DVector3f)location target:(M3DVector3f)target up:(M3DVector3f)up;

http://github.com/turner/HelloTeapot/blob/master/Classes/GLViewController.[hm]

Page 49: 3D Graphics on iPhone

float teapot_vertices [] = { 0.0663, 0.1178, 0.0, 0.0672, 0.1152, 0.0, 0.0639, 0.1178, 0.0178043,

... };

float teapot_normals[] = { -0.987635, -0.156768, 0, -0.902861, -0.429933, 0, -0.953562, -0.156989, -0.257047,

... };

short indicies[] = {// howmany vertices in vertex strip26,// vertex strip indices1122, 1243, 1272, 1242, ... ,1283, 1199, ... };

http://github.com/turner/HelloTeapot/blob/master/teapot.h

Render

Page 50: 3D Graphics on iPhone

glEnableClientState(GL_VERTEX_ARRAY);glVertexPointer(3 ,GL_FLOAT, 0, teapot_vertices);

glEnableClientState(GL_NORMAL_ARRAY);glNormalPointer(GL_FLOAT, 0, teapot_normals);glEnable(GL_NORMALIZE);

http://github.com/turner/HelloTeapot/blob/master/Classes/GLViewController.[hm]

Render

Page 51: 3D Graphics on iPhone

// Position Camera glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glLoadMatrixf(_openGLCameraInverseTransform);

// Position Light glPushMatrix(); glMultMatrixf(_cameraTransform); glEnable(GL_LIGHT3); glLightfv(GL_LIGHT3, GL_DIFFUSE, spotLight);

glPopMatrix();

// Position Model glPushMatrix();

JLMMatrix3DSetZRotationUsingDegrees(rotation, -45.0f); JLMMatrix3DSetScaling(scale, sx, sy, sz); JLMMatrix3DMultiply(rotation, scale, concatenation); glMultMatrixf(concatenation);

// Render for(int i = 0; i < num_teapot_indices; i += indicies[i] + 1) {

glDrawElements(GL_TRIANGLE_STRIP, indices[i], GL_UNSIGNED_SHORT, &indices[i+1]);

} // for (num_teapot_indices)

glPopMatrix();

http://github.com/turner/HelloTeapot/blob/master/Classes/GLViewController.[hm]

Render

Page 53: 3D Graphics on iPhone

red_lightgreen_light

blue_light

push()

pop()

invert( camera_transform )

camera_transformwhite_spotlight

push()

pop()

teapot_transformdraw()

Page 54: 3D Graphics on iPhone

You’ll want to understand this stuff if you intend to do AR* apps like all the cool kids.

*Augmented Reality - See http://layar.com

Page 55: 3D Graphics on iPhone

Design Appearance

Page 56: 3D Graphics on iPhone

Mipmapped textures are your friend.

They will become your workhorse for visual complexity.

Page 57: 3D Graphics on iPhone

Texture Everything

Copyright © Douglass Turner

Page 58: 3D Graphics on iPhone

glGenTextures(1, &_name); glBindTexture(GL_TEXTURE_2D, _name); glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, glColor, _w, _h, 0, glColor, glFormat, data); glGenerateMipmapOES(GL_TEXTURE_2D);

MethodinitWithTextureFile:mipmap:

Classgithub.com/turner/HelloTexture/blob/master/Classes/TEITexture.[h,m]

Page 59: 3D Graphics on iPhone

HelloTexture Demo

Source: http://github.com/turner/HelloTexture

Page 60: 3D Graphics on iPhone

Two Words

Texture. Atlas.

Page 61: 3D Graphics on iPhone

s

t

Texture Space

Page 62: 3D Graphics on iPhone

s

t

Texture Space

Page 63: 3D Graphics on iPhone

HelloParticleSystem Demo

texture atlas hacks

Page 64: 3D Graphics on iPhone

OpenGL ES 2.0 == GLSL

Page 65: 3D Graphics on iPhone

Shaders Take it to Another Level Copyright © Douglass Turner

Page 66: 3D Graphics on iPhone

Shaders Take it to Another Level Copyright © Douglass Turner

Page 67: 3D Graphics on iPhone

Shaders Take it to Another Level ZBrush Modeling Daniel Lieske

Page 68: 3D Graphics on iPhone

Shaders Take it to Another LevelZBrush Modeling Daniel LieskeMaterial Design Ralf Stumpf

Page 69: 3D Graphics on iPhone

Shaders Take it to Another LevelZBrush Modeling Daniel LieskeMaterial Design Ralf Stumpf

Page 70: 3D Graphics on iPhone

Shaders Take it to Another Level Copyright: Stephen Molyneaux

Page 71: 3D Graphics on iPhone

GLSL is cool.

Sadly, OpenGL ES 2.0 (iPhone 3Gs) does not support hardware anti-aliasing.

Stick with mipmapped textures until you really know what you are doing.

Or don’t care about aliasing artifacts ...

Page 72: 3D Graphics on iPhone

1 sample per pixel 4 jittered/filtered samples per pixel

Page 73: 3D Graphics on iPhone

Remember the iPhone Imperitive

Your app will be beautiful.

Page 74: 3D Graphics on iPhone

OpenGL and Cocoa Touch Playing Nice Together

Page 75: 3D Graphics on iPhone

MVC

OpenGL is M. Keep V dumb. Lots of chatter between M and V.

• GLGravity | http://bit.ly/2dS8YI• Jeff LaMarche OpenGL ES Template | http://bit.ly/2IvZtV

Page 76: 3D Graphics on iPhone

Touch Sequence & Accelerometer

Page 77: 3D Graphics on iPhone

HelloParticleSystem Demo

Particle system. Touch. Acceleration

Page 78: 3D Graphics on iPhone

Touch Sequence

Page 79: 3D Graphics on iPhone

touchesBegan:withEvent:

touchesMoved:withEvent:

touchesEnded:withEvent:

touchesCancelled:withEvent:

Initialize model state

Evolve model state

Clean up model state

Page 80: 3D Graphics on iPhone

Accelerometer

Page 81: 3D Graphics on iPhone

- (void)accelerometer:(UIAccelerometer*)accelerometer didAccelerate:(UIAcceleration*)acceleration { // Compute "G". Use low-pass filter to attenuate instantaneous acceleration. self.accelerationValueX = acceleration.x * kFilteringFactor + self.accelerationValueX * (1.0 - kFilteringFactor); self.accelerationValueY = acceleration.y * kFilteringFactor + self.accelerationValueY * (1.0 - kFilteringFactor); self.accelerationValueZ = acceleration.z * kFilteringFactor + self.accelerationValueZ * (1.0 - kFilteringFactor); // ParticleSystem particles live in flatland. Use x and y compoments of "G". [ParticleSystem setGravity:CGPointMake(self.accelerationValueX, self.accelerationValueY)];}

UIAccelerometerDelegate

Page 82: 3D Graphics on iPhone

+ (void)setGravity:(CGPoint)gravityVector { // Normalize 2D “G” vector. Only care about direction. float length = sqrtf(gravityVector.x * gravityVector.x + gravityVector.y * gravityVector.y); ParticleSystemGravity.x = gravityVector.x / length; ParticleSystemGravity.y = gravityVector.y / length; // Flip y-component of gravity vector to be consistent with screen space coordinate // system used in ParticleSystem. ParticleSystemGravity.y = -(ParticleSystemGravity.y);}

ParticleSystem - Class State

Page 83: 3D Graphics on iPhone

// dv = dv/dt * dt float dv_x = (ParticleSystemGravity.x * gravityScaleFactor * dt); float dv_y = (ParticleSystemGravity.y * gravityScaleFactor * dt); particle.velocity = CGPointMake(particle.velocity.x + dv_x, particle.velocity.y + dv_y); // dx = dx/dt * dt float dx = particle.velocity.x * dt; float dy = particle.velocity.y * dt; // x = x_old * dx particle.location = CGPointMake(particle.location.x + dx, particle.location.y + dy);

ParticleSystem - Instance State

Page 84: 3D Graphics on iPhone

CoreAnimation:

[myView setNeedsDisplay] & [myView drawRect]

OpenGL:

- (void)startAnimation { animationTimer = [NSTimer scheduledTimerWithTimeInterval:animationInterval target:self selector:@selector(drawView) userInfo:nil repeats:YES];}

Page 85: 3D Graphics on iPhone

iPhone is an Expression Platform

You Must See:Stanford cs 193p Lecture 17 Video | On iTunes: http://bit.ly/PUrGjCreating New Expressive Social Mediums on the iPhone Ge Wang | CCO & CTO | Smule

Page 86: 3D Graphics on iPhone

• Touch• Sound• Proximity• Cloud• Camera• INU (almost)• Geography

iPhone is a general purpose sensing platform

Page 87: 3D Graphics on iPhone

iPhone encourages plausible, hyper-real, extensions of human experience.

Be interesting. Be brilliant.

Page 88: 3D Graphics on iPhone

Resources

• @dugla - search on #iphonemeetup3dtalkacton

• http://theelasticimage.posterous.com

• This presentation on SlideShare: http://bit.ly/4wC4Mu

Page 89: 3D Graphics on iPhone

Douglass Turner

@dugla #iphonemeetup3dtalkacton [email protected]

Copyright © Douglass Turner