Professional Documents
Culture Documents
Douglass Turner
douglass.turner@gmail.com
@dugla #iphonemeetup3dtalkacton
A talk in three acts ...
• Intro to Computer Graphics
• Depth Comparison
• Apply Appearance - Vertex level. Pixel level.
• Composite Elements
Present Image
Update Model State
Rinse, repeat.
Computer Graphics in OpenGL
OpenGL Cocoa
OpenGL is old school
You are flipping levers on a state machine.
float foo[]
;-)
OpenGL websites are a bit different
than Cocoa websites ...
Isn’t that sweet ...
Um... WTF?
Can’t you just feel the love?
Dude. I think my eyes are bleeding.
No worries. safari.oreilly.com is your friend
Hierarchical Modeling. Transformation Stacks. Coordinate Frames.
Pose Model
Pose Model
You are already familiar with hierarchical modeling and coordinate frames.
[self.parentView addSubview:childView];
or ...
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)
You are already familiar with hierarchical modeling and coordinate frames.
- (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];
}
Source: http://github.com/turner/HelloTeapot
HelloTeapot Code Walkthrough
http://github.com/turner/HelloTeapot/blob/master/Classes/GLViewController.[hm]
// 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) {
} // for (num_teapot_indices)
glPopMatrix();
http://github.com/turner/HelloTeapot/blob/master/Classes/GLViewController.[hm]
Pose Model
// 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) {
} // for (num_teapot_indices)
glPopMatrix();
http://github.com/turner/HelloTeapot/blob/master/Classes/GLViewController.[hm]
Light Scene
// 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) {
} // for (num_teapot_indices)
glPopMatrix();
http://github.com/turner/HelloTeapot/blob/master/Classes/GLViewController.[hm]
// Position Camera
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glLoadMatrixf(_openGLCameraInverseTransform);
// Position Light
glPushMatrix();
glMultMatrixf(_cameraTransform);
glEnable(GL_LIGHT3);
glLightfv(GL_LIGHT3, GL_DIFFUSE, spotLight);
// Render
for(int i = 0; i < num_teapot_indices; i += new_teapot_indicies[i] + 1) {
} // for (num_teapot_indices)
glPopMatrix();
http://github.com/turner/HelloTeapot/blob/master/Classes/GLViewController.[hm]
camera teapot
wTc wTt
world
cT t
camera teapot
glMatrixMode(GL_MODELVIEW);
glLoadMatrixf(_openGLCameraInverseTransform);
cT t
camera teapot
-1
(wTc) wTt
world
cT t = cT w * wTt
cT t = cT w * wTt
// Position Camera
glMatrixMode(GL_MODELVIEW);
cT t = cT w * wTt
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) {
} // for (num_teapot_indices)
glPopMatrix();
http://github.com/turner/HelloTeapot/blob/master/Classes/GLViewController.[hm]
- (void)placeCameraAtLocation:(M3DVector3f)location
target:(M3DVector3f)target
up:(M3DVector3f)up;
http://github.com/turner/HelloTeapot/blob/master/Classes/GLViewController.[hm]
Render
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 strip
26,
// vertex strip indices
1122, 1243, 1272, 1242, ... ,1283, 1199,
...
};
http://github.com/turner/HelloTeapot/blob/master/teapot.h
Render
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
// 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) {
} // for (num_teapot_indices)
glPopMatrix();
http://github.com/turner/HelloTeapot/blob/master/Classes/GLViewController.[hm]
http://github.com/turner/HelloTeapot/blob/master/Classes/GLViewController.[hm]
invert( camera_transform )
red_light
green_light
blue_light
push()
camera_transform
white_spotlight
pop()
push()
teapot_transform
draw()
pop()
You’ll want to understand this stuff if you intend
to do AR* apps like all the cool kids.
Method
initWithTextureFile:mipmap:
Class
github.com/turner/HelloTexture/blob/master/Classes/TEITexture.[h,m]
HelloTexture Demo
Source: http://github.com/turner/HelloTexture
Two Words
Texture. Atlas.
t
Texture Space
t
Texture Space
HelloParticleSystem Demo
• GLGravity | http://bit.ly/2dS8YI
• Jeff LaMarche OpenGL ES Template | http://bit.ly/2IvZtV
Touch Sequence & Accelerometer
HelloParticleSystem Demo
touchesCancelled:withEvent:
Accelerometer
- (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
+ (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);
}
OpenGL:
- (void)startAnimation {
animationTimer = [NSTimer scheduledTimerWithTimeInterval:animationInterval
target:self
selector:@selector(drawView)
userInfo:nil
repeats:YES];
}
iPhone is an Expression Platform
• Touch
• Sound
• Proximity
• Cloud
• Camera
• INU (almost)
• Geography
iPhone encourages plausible, hyper-real,
extensions of human experience.
Be interesting. Be brilliant.
Resources
• @dugla - search on #iphonemeetup3dtalkacton
• http://theelasticimage.posterous.com
• This presentation on SlideShare: http://bit.ly/4wC4Mu
Douglass Turner
@dugla #iphonemeetup3dtalkacton
douglass.turner@gmail.com