How to change the perspective on a 3D cube in OpenGL ES? - iphone

I draw a cube with OpenGL ES and I want to have an above perspective on it.But I don't know what should I modify...Maybe you can help.
- (void)render:(CADisplayLink*)displayLink {
//-(void) render{
glClearColor(255.0, 255.0/255.0, 255.0/255.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
//projection
CC3GLMatrix *projection = [CC3GLMatrix matrix];
float h = 4.0f * self.frame.size.height / self.frame.size.width;
[projection populateFromFrustumLeft:-2 andRight:2 andBottom:-h/2 andTop:h/2 andNear:4 andFar:8];
glUniformMatrix4fv(_projectionUniform, 1, 0, projection.glMatrix);
CC3GLMatrix *modelView = [CC3GLMatrix matrix];
// _currentScaling += displayLink.duration * 1.0;
[modelView populateFromTranslation:CC3VectorMake(sin(30), _currentScaling , -7)];
[modelView rotateBy:CC3VectorMake(0, -15, 0)];
// [modelView scaleByY:_currentScaling];
if(_currentScaling > 2 ){
[displayLink invalidate];
_running = 1;
// scale = 0;
}
glUniformMatrix4fv(_modelViewUniform, 1, 0, modelView.glMatrix);
// 1
glViewport(0, 0, self.frame.size.width, self.frame.size.height);
// 2
glVertexAttribPointer(_positionSlot, 3, GL_FLOAT, GL_FALSE,
sizeof(Vertex), 0);
glVertexAttribPointer(_colorSlot, 4, GL_FLOAT, GL_FALSE,
sizeof(Vertex), (GLvoid*) (sizeof(float) * 3));
// 3
glDrawElements(GL_TRIANGLES, sizeof(Indices)/sizeof(Indices[0]),
GL_UNSIGNED_BYTE, 0);
[_context presentRenderbuffer:GL_RENDERBUFFER];
}

I recently started looking into OpenGL myself and found this same example. I believe what you are looking for is to change this line to change the perspective:
[modelView rotateBy:CC3VectorMake(0, -15, 0)];
and specify the degrees of rotation you want for the x,y,z axes.

Related

Simple gradient issue with OpenGL on iphone simulator

i was following the tutorial from raywenderlich website, the gradient seems not to work perfectly, is it only because of the iphone simulator, or is it something else? I can't try myself with an iphone. Here is the image :
And the code :
-(CCSprite *)spriteWithColor:(ccColor4F)bgColor textureSize:(float)textureSize {
// 1: Create new CCRenderTexture
CCRenderTexture *rt = [CCRenderTexture renderTextureWithWidth:textureSize height:screenSize.height];
// 2: Call CCRenderTexture:begin
[rt beginWithClear:bgColor.r g:bgColor.g b:bgColor.b a:bgColor.a];
// 3: Draw into the texture
glDisable(GL_TEXTURE_2D);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
float gradientAlpha = 0.5;
CGPoint vertices[4];
ccColor4F colors[4];
int nVertices = 0;
vertices[nVertices] = CGPointMake(0, 0);
colors[nVertices++] = (ccColor4F){0, 0, 0, 0};
vertices[nVertices] = CGPointMake(textureSize, 0);
colors[nVertices++] = (ccColor4F){0, 0, 0, gradientAlpha};
vertices[nVertices] = CGPointMake(0, screenSize.height);
colors[nVertices++] = (ccColor4F){0, 0, 0, 0};
vertices[nVertices] = CGPointMake(textureSize, screenSize.height);
colors[nVertices++] = (ccColor4F){0, 0, 0, gradientAlpha};
glVertexPointer(2, GL_FLOAT, 0, vertices);
glColorPointer(4, GL_FLOAT, 0, colors);
glDrawArrays(GL_TRIANGLE_STRIP, 0, (GLsizei)nVertices);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnable(GL_TEXTURE_2D);
// 4: Call CCRenderTexture:end
[rt end];
// 5: Create a new Sprite from the texture
return [CCSprite spriteWithTexture:rt.sprite.texture];
}
Thanks

Texture Mapping - Cocos2d/OpenGL ES 1.0

This lightning is really affecting my game's performance because I am constantly adding and removing the lightning, but also each lighting strike is composed of 3 anti aliased lines using:
void ccDrawSmoothLine(CGPoint pos1, CGPoint pos2, float width)
{
GLfloat lineVertices[12], curc[4];
GLint ir, ig, ib, ia;
CGPoint dir, tan;
// Default GL states: GL_TEXTURE_2D, GL_VERTEX_ARRAY, GL_COLOR_ARRAY, GL_TEXTURE_COORD_ARRAY
// Needed states: GL_VERTEX_ARRAY,
// Unneeded states: GL_TEXTURE_2D, GL_TEXTURE_COORD_ARRAY, GL_COLOR_ARRAY
glDisable(GL_TEXTURE_2D);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
//glEnable(GL_LINE_SMOOTH);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
pos1.x *= CC_CONTENT_SCALE_FACTOR();
pos1.y *= CC_CONTENT_SCALE_FACTOR();
pos2.x *= CC_CONTENT_SCALE_FACTOR();
pos2.y *= CC_CONTENT_SCALE_FACTOR();
width *= CC_CONTENT_SCALE_FACTOR();
width = width*2;
dir.x = pos2.x - pos1.x;
dir.y = pos2.y - pos1.y;
float len = sqrtf(dir.x*dir.x+dir.y*dir.y);
if(len<0.00001)
return;
dir.x = dir.x/len;
dir.y = dir.y/len;
tan.x = -width*dir.y;
tan.y = width*dir.x;
lineVertices[0] = pos1.x + tan.x;
lineVertices[1] = pos1.y + tan.y;
lineVertices[2] = pos2.x + tan.x;
lineVertices[3] = pos2.y + tan.y;
lineVertices[4] = pos1.x;
lineVertices[5] = pos1.y;
lineVertices[6] = pos2.x;
lineVertices[7] = pos2.y;
lineVertices[8] = pos1.x - tan.x;
lineVertices[9] = pos1.y - tan.y;
lineVertices[10] = pos2.x - tan.x;
lineVertices[11] = pos2.y - tan.y;
glGetFloatv(GL_CURRENT_COLOR,curc);
ir = 255.0*curc[0];
ig = 255.0*curc[1];
ib = 255.0*curc[2];
ia = 255.0*curc[3];
const GLubyte lineColors[] = {
ir, ig, ib, 0,
ir, ig, ib, 0,
ir, ig, ib, ia,
ir, ig, ib, ia,
ir, ig, ib, 0,
ir, ig, ib, 0,
};
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glVertexPointer(2, GL_FLOAT, 0, lineVertices);
glColorPointer(4, GL_UNSIGNED_BYTE, 0, lineColors);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 6);
glDisableClientState(GL_COLOR_ARRAY);
// restore default state
glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnable(GL_TEXTURE_2D);
}
My FPS will drop to about 40, then shoot back up to 60. I've read that texture mapping the line could improve my game's performance.
I have been trying to figure this out for several weeks now, with no luck. Can someone PLEASE help me with this?
This is my current ccDrawLines and draw method
-(void) draw
{
numPoints_ = 0;
glColor4ub(_color.r, _color.g, _color.b, _opacity);
if (_opacity != 255)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
drawLightning(_strikePoint2, _strikePoint, _displacement, _minDisplacement, _seed, lightningPoints_, &numPoints_);
ccDrawLines(lightningPoints_, numPoints_, texture);
if (_opacity != 255)
glBlendFunc(CC_BLEND_SRC, CC_BLEND_DST);
glColor4f(1.0, 1.0, 1.0, 1.0);
}
void ccDrawLines( CGPoint* points, uint numberOfPoints, CCTexture2D* texture )
{
//layout of points [0] = origin, [1] = destination and so on
ccVertex2F vertices[numberOfPoints];
if (CC_CONTENT_SCALE_FACTOR() != 1 )
{
for (int i = 0; i < numberOfPoints; i++)
{
vertices[i].x = points[i].x * CC_CONTENT_SCALE_FACTOR();
vertices[i].y= points[i].y * CC_CONTENT_SCALE_FACTOR();
}
glVertexPointer(2, GL_FLOAT, 0, vertices);
}
else glVertexPointer(2, GL_FLOAT, 0, points);
ccTex2F texCoords[numberOfPoints];
float width = texture.pixelsWide;
float height = texture.pixelsHigh;
if (CC_CONTENT_SCALE_FACTOR() != 1 )
{
for (int i = 0; i < numberOfPoints; i++)
{
texCoords[i].u = (vertices[i].x * CC_CONTENT_SCALE_FACTOR()) / width;
texCoords[i].v = (vertices[i].y * CC_CONTENT_SCALE_FACTOR()) / height;
}
glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
}
else glTexCoordPointer(2, GL_FLOAT, 0, points);
// Default GL states: GL_TEXTURE_2D, GL_VERTEX_ARRAY, GL_COLOR_ARRAY, GL_TEXTURE_COORD_ARRAY
// Needed states: GL_VERTEX_ARRAY,
// Unneeded states: GL_TEXTURE_2D, GL_TEXTURE_COORD_ARRAY, GL_COLOR_ARRAY
glPushMatrix();
glBindTexture(GL_TEXTURE_2D, [texture name]);
glDisableClientState(GL_COLOR_ARRAY);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glDrawArrays(GL_TRIANGLE_STRIP, 0, numberOfPoints);
// restore default state
glEnableClientState(GL_COLOR_ARRAY);
glPopMatrix();
}
The texture is just a 32x32 .png file with a small blue dot.
If you look at ccDrawLines I have added the code to texture map the line. The problem with it is, gaps in the line, multiple lines being drawn, and it looks horrible.
EDIT:
I decided not to texture map the line and use ccDrawSmoothLine.
All I did was allocate the lightning in my gamelayer's init
lightningStrike_ = [Lightning lightningWithStrikePoint:ccp(-100, -100) strikePoint2:ccp(-100, -100)];
[self addChild:lightningStrike_ z:1];
Then, I created an instance method to set the _strikePoint and _strikePoint2 properties and call the strikeRandom method.
-(Lightning *)lightningStrike:(CGPoint)p end:(CGPoint)p2
{
lightningStrike_.strikePoint = ccp(p.x, p.y);
lightningStrike_.strikePoint2 = ccp(p2.x, p2.y);
[lightningStrike_ strikeRandom];
return lightningStrike_;
}
Usage:
[self lightningStrike:ccp(100, 100) end:ccp(100, 100)];
This fixed the FPS drop. After 24 hours I will answer and accept my own answer.
EDIT: I decided not to texture map the line and use ccDrawSmoothLine.
All I did was allocate the lightning in my gamelayer's init
lightningStrike_ = [Lightning lightningWithStrikePoint:ccp(-100, -100) strikePoint2:ccp(-100, -100)];
[self addChild:lightningStrike_ z:1];
Then, I created an instance method to set the _strikePoint and _strikePoint2 properties and call the strikeRandom method.
-(Lightning *)lightningStrike:(CGPoint)p end:(CGPoint)p2
{
    lightningStrike_.strikePoint = ccp(p.x, p.y);
    lightningStrike_.strikePoint2 = ccp(p2.x, p2.y);
    [lightningStrike_ strikeRandom];
    return lightningStrike_;
}
Usage:
[self lightningStrike:ccp(100, 100) end:ccp(100, 100)];
This fixed the FPS drop. After 24 hours I will answer and accept my own answer.

making an iphone cube class

I followed this tutorial and I'm currently trying to create a class to draw cubes. The class populates the buffers in a function called setup and draws them in a function called draw.
There are no errors however nothing is displayed on the screen.
My question is basicly how do I go about making a class from which I can render cubes.
Using Xcode 4.2, Opengl and Objective-C.
[edit]
-(void)SetShader:(GLuint)InShader
{
glUseProgram(InShader);
_positionSlot = glGetAttribLocation(InShader, "Position");
_colorSlot = glGetAttribLocation(InShader, "SourceColor");
glEnableVertexAttribArray(_positionSlot);
glEnableVertexAttribArray(_colorSlot);
_projectionUniform = glGetUniformLocation(InShader, "Projection");
_modelViewUniform = glGetUniformLocation(InShader, "Modelview");
_texCoordSlot = glGetAttribLocation(InShader, "TexCoordIn");
glEnableVertexAttribArray(_texCoordSlot);
_textureUniform = glGetUniformLocation(InShader, "Texture");
}
-(void)SetupVBO
{
GLuint vertexBuffer;
glGenBuffers(1, &vertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(CubeVertices), CubeVertices, GL_STATIC_DRAW);
GLuint indexBuffer;
glGenBuffers(1, &indexBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(CubeIndices), CubeIndices, GL_STATIC_DRAW);
}
-(void)draw
{
glVertexAttribPointer(_positionSlot, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), 0);
glVertexAttribPointer(_colorSlot, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*) (sizeof(float) * 3));
glVertexAttribPointer(_texCoordSlot, 2, GL_FLOAT, GL_FALSE,
sizeof(Vertex), (GLvoid*) (sizeof(float) * 7));
glDrawElements(GL_TRIANGLES, sizeof(CubeIndices)/sizeof(CubeIndices[0]), GL_UNSIGNED_BYTE, 0);
}
-(void)render:(CADisplayLink*)displayLink
{
glClearColor(0, 0, 0.2, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
CC3GLMatrix *projection = [CC3GLMatrix matrix];
float h = 4.0f * self.frame.size.height / self.frame.size.width;
[projection populateFromFrustumLeft:-2 andRight:2 andBottom:-h/2 andTop:h/2 andNear:4 andFar:10];
glUniformMatrix4fv(_projectionUniform, 1, 0, projection.glMatrix);
CC3GLMatrix *modelView = [CC3GLMatrix matrix];
[modelView populateFromTranslation:CC3VectorMake(0, 0, -7)];
[modelView translateBy:CC3VectorMake(0,5,0)];
glUniformMatrix4fv(_modelViewUniform, 1, 0, modelView.glMatrix);
glViewport(0, 0, self.frame.size.width, self.frame.size.height);
[m_cube draw];
[_context presentRenderbuffer:GL_RENDERBUFFER];
}
It was as mentioned a problem with the arrangement of my viewport and perspective setups.

How to set background image using OpenGL ES 1.1 for iPhone

Please help me to set a background image in EaglView. Here my source code with the image:
glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
brushImage = [UIImage imageNamed:#"Particle.png"].CGImage;
width = CGImageGetWidth(brushImage);
height = CGImageGetHeight(brushImage);
if(brushImage) {
brushData = (GLubyte *) calloc(width * height * 4, sizeof(GLubyte));
brushContext = CGBitmapContextCreate(brushData, width, height, 8, width * 4, CGImageGetColorSpace(brushImage), kCGImageAlphaPremultipliedLast);
CGContextDrawImage(brushContext, CGRectMake(0.0, 0.0, (CGFloat)width, (CGFloat)height), brushImage);
CGContextRelease(brushContext);
glGenTextures(1, &brushTexture);
glBindTexture(GL_TEXTURE_2D, brushTexture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, brushData);
free(brushData);
}
self.contentScaleFactor = 1.0;
glLoadIdentity();
glMatrixMode(GL_PROJECTION);
CGRect frame = self.bounds;
CGFloat scale = self.contentScaleFactor;
glOrthof(0, frame.size.width * scale, 0, frame.size.height * scale, -1, 1);
glViewport(0, 0, frame.size.width * scale, frame.size.height * scale);
glMatrixMode(GL_MODELVIEW);
glDisable(GL_DITHER);
glEnable(GL_TEXTURE_2D);
glEnableClientState(GL_VERTEX_ARRAY);
glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_POINT_SPRITE_OES);
glTexEnvf(GL_POINT_SPRITE_OES, GL_COORD_REPLACE_OES, GL_TRUE);
glPointSize(width / kBrushScale);`
Instead of using a point sprite should simply draw a textured quad.
GLfloat vert_tex[] = {
0., 0.,
1., 0.,
1., 1.,
0., 1.
};
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glVertexPointer(2, GL_FLOAT, 0, vert_tex);
glTexCoordPointer(2, GL_FLOAT, 0, vert_tex);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, 1, 0, 1, -1, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture_name);
glDrawArrays(GL_QUADS, 0, 4);
EDIT2:
// Erases the screen
- (void) erase
{
[EAGLContext setCurrentContext:context];
CGRect frame = self.bounds;
CGFloat scale = self.contentScaleFactor;
GLfloat vert_tex[] = {
0., 0.,
frame.size.width * scale, 0.,
frame.size.width * scale, frame.size.height * scale,
0., frame.size.height * scale
};
glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glVertexPointer(2, GL_FLOAT, 0, vert_tex);
glTexCoordPointer(2, GL_FLOAT, 0, vert_tex);
// Setup the view port in Pixels
glMatrixMode(GL_PROJECTION);
glOrthof(0, frame.size.width * scale, 0, frame.size.height * scale, -1, 1);
glViewport(0, 0, frame.size.width * scale, frame.size.height * scale);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glDisable(GL_DITHER);
glEnable(GL_TEXTURE_2D);
// background_image texture must be initialized with the desired
// content; see initWithCoder of original GLPaint example for
// example code how to load textures.
glBindTexture(GL_TEXTURE_2D, background_image);
// Clear the buffer with background image
glDrawArrays(GL_QUADS, 0, 4);
// Display the buffer
glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
[context presentRenderbuffer:GL_RENDERBUFFER_OES];
}
In renderLineFromPoint you must add a line to bind the brush texture before drawing:
// Drawings a line onscreen based on where the user touches
- (void) renderLineFromPoint:(CGPoint)start toPoint:(CGPoint)end
{
/* ... */
// add this line here v v v v v v v v v v v
glBindTexture(GL_TEXURE_2D, brushTexture);
// ^ ^ ^ ^^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^
// Render the vertex array
glVertexPointer(2, GL_FLOAT, 0, vertexBuffer);
glDrawArrays(GL_POINTS, 0, vertexCount);
// Display the buffer
glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
[context presentRenderbuffer:GL_RENDERBUFFER_OES];

How do I implement AABB ray cast hit checking on the iPhone

Basically, I draw a 3D cube, I can spin it around but I want to be able to touch it and know where on my cube's surface the user touched.
I'm using for setting up, generating and spinning. Its based on the Molecules code and NeHe tutorial #5.
Any help, links, tutorials and code would be greatly appreciated. I have lots of development experience but nothing much in the way of openGL and 3d.
//
// GLViewController.h
// NeHe Lesson 05
//
// Created by Jeff LaMarche on 12/12/08.
// Copyright Jeff LaMarche Consulting 2008. All rights reserved.
//
#import "GLViewController.h"
#import "GLView.h"
#implementation GLViewController
- (void)drawBox
{
static const GLfloat cubeVertices[] = {
-1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f,
1.0f,-1.0f, 1.0f,
-1.0f,-1.0f, 1.0f,
-1.0f, 1.0f,-1.0f,
1.0f, 1.0f,-1.0f,
1.0f,-1.0f,-1.0f,
-1.0f,-1.0f,-1.0f
};
static const GLubyte cubeNumberOfIndices = 36;
const GLubyte cubeVertexFaces[] = {
0, 1, 5, // Half of top face
0, 5, 4, // Other half of top face
4, 6, 5, // Half of front face
4, 6, 7, // Other half of front face
0, 1, 2, // Half of back face
0, 3, 2, // Other half of back face
1, 2, 5, // Half of right face
2, 5, 6, // Other half of right face
0, 3, 4, // Half of left face
7, 4, 3, // Other half of left face
3, 6, 2, // Half of bottom face
6, 7, 3, // Other half of bottom face
};
const GLubyte cubeFaceColors[] = {
0, 255, 0, 255,
255, 125, 0, 255,
255, 0, 0, 255,
255, 255, 0, 255,
0, 0, 255, 255,
255, 0, 255, 255
};
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, cubeVertices);
int colorIndex = 0;
for(int i = 0; i < cubeNumberOfIndices; i += 3)
{
glColor4ub(cubeFaceColors[colorIndex], cubeFaceColors[colorIndex+1], cubeFaceColors[colorIndex+2], cubeFaceColors[colorIndex+3]);
int face = (i / 3.0);
if (face%2 != 0.0)
colorIndex+=4;
glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_BYTE, &cubeVertexFaces[i]);
}
glDisableClientState(GL_VERTEX_ARRAY);
}
//move this to a data model later!
- (GLfixed)floatToFixed:(GLfloat)aValue;
{
return (GLfixed) (aValue * 65536.0f);
}
- (void)drawViewByRotatingAroundX:(float)xRotation rotatingAroundY:(float)yRotation scaling:(float)scaleFactor translationInX:(float)xTranslation translationInY:(float)yTranslation view:(GLView*)view;
{
glMatrixMode(GL_MODELVIEW);
GLfixed currentModelViewMatrix[16] = { 45146, 47441, 2485, 0,
-25149, 26775,-54274, 0,
-40303, 36435, 36650, 0,
0, 0, 0, 65536 };
/*
GLfixed currentModelViewMatrix[16] = { 0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 65536 };
*/
//glLoadIdentity();
//glOrthof(-1.0f, 1.0f, -1.5f, 1.5f, -10.0f, 4.0f);
// Reset rotation system
if (isFirstDrawing)
{
//glLoadIdentity();
glMultMatrixx(currentModelViewMatrix);
[self configureLighting];
isFirstDrawing = NO;
}
// Scale the view to fit current multitouch scaling
GLfixed fixedPointScaleFactor = [self floatToFixed:scaleFactor];
glScalex(fixedPointScaleFactor, fixedPointScaleFactor, fixedPointScaleFactor);
// Perform incremental rotation based on current angles in X and Y
glGetFixedv(GL_MODELVIEW_MATRIX, currentModelViewMatrix);
GLfloat totalRotation = sqrt(xRotation*xRotation + yRotation*yRotation);
glRotatex([self floatToFixed:totalRotation],
(GLfixed)((xRotation/totalRotation) * (GLfloat)currentModelViewMatrix[1] + (yRotation/totalRotation) * (GLfloat)currentModelViewMatrix[0]),
(GLfixed)((xRotation/totalRotation) * (GLfloat)currentModelViewMatrix[5] + (yRotation/totalRotation) * (GLfloat)currentModelViewMatrix[4]),
(GLfixed)((xRotation/totalRotation) * (GLfloat)currentModelViewMatrix[9] + (yRotation/totalRotation) * (GLfloat)currentModelViewMatrix[8])
);
// Translate the model by the accumulated amount
glGetFixedv(GL_MODELVIEW_MATRIX, currentModelViewMatrix);
float currentScaleFactor = sqrt(pow((GLfloat)currentModelViewMatrix[0] / 65536.0f, 2.0f) + pow((GLfloat)currentModelViewMatrix[1] / 65536.0f, 2.0f) + pow((GLfloat)currentModelViewMatrix[2] / 65536.0f, 2.0f));
xTranslation = xTranslation / (currentScaleFactor * currentScaleFactor);
yTranslation = yTranslation / (currentScaleFactor * currentScaleFactor);
// Grab the current model matrix, and use the (0,4,8) components to figure the eye's X axis in the model coordinate system, translate along that
glTranslatef(xTranslation * (GLfloat)currentModelViewMatrix[0] / 65536.0f, xTranslation * (GLfloat)currentModelViewMatrix[4] / 65536.0f, xTranslation * (GLfloat)currentModelViewMatrix[8] / 65536.0f);
// Grab the current model matrix, and use the (1,5,9) components to figure the eye's Y axis in the model coordinate system, translate along that
glTranslatef(yTranslation * (GLfloat)currentModelViewMatrix[1] / 65536.0f, yTranslation * (GLfloat)currentModelViewMatrix[5] / 65536.0f, yTranslation * (GLfloat)currentModelViewMatrix[9] / 65536.0f);
// Black background, with depth buffer enabled
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
[self drawBox];
}
- (void)configureLighting;
{
const GLfixed lightAmbient[] = {13107, 13107, 13107, 65535};
const GLfixed lightDiffuse[] = {65535, 65535, 65535, 65535};
const GLfixed matAmbient[] = {65535, 65535, 65535, 65535};
const GLfixed matDiffuse[] = {65535, 65535, 65535, 65535};
const GLfixed lightPosition[] = {30535, -30535, 0, 0};
const GLfixed lightShininess = 20;
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_COLOR_MATERIAL);
glMaterialxv(GL_FRONT_AND_BACK, GL_AMBIENT, matAmbient);
glMaterialxv(GL_FRONT_AND_BACK, GL_DIFFUSE, matDiffuse);
glMaterialx(GL_FRONT_AND_BACK, GL_SHININESS, lightShininess);
glLightxv(GL_LIGHT0, GL_AMBIENT, lightAmbient);
glLightxv(GL_LIGHT0, GL_DIFFUSE, lightDiffuse);
glLightxv(GL_LIGHT0, GL_POSITION, lightPosition);
glEnable(GL_DEPTH_TEST);
glShadeModel(GL_SMOOTH);
glEnable(GL_NORMALIZE);
}
-(void)setupView:(GLView*)view
{
const GLfloat zNear = 0.1,
zFar = 1000.0,
fieldOfView = 60.0;
GLfloat size;
glMatrixMode(GL_PROJECTION);
glEnable(GL_DEPTH_TEST);
size = zNear * tanf(DEGREES_TO_RADIANS(fieldOfView) / 2.0);
CGRect rect = view.bounds;
glFrustumf(-size, size, -size / (rect.size.width / rect.size.height), size /
(rect.size.width / rect.size.height), zNear, zFar);
glViewport(0, 0, rect.size.width, rect.size.height);
glScissor(0, 0, rect.size.width, rect.size.height);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glTranslatef(0.0f, 0.0f, -6.0f);
isFirstDrawing = YES;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
- (void)dealloc
{
[super dealloc];
}
#end
In order to implement Ray cast hit checking, you should check these sources:
http://www.mvps.org/directx/articles/rayproj.htm
http://bookofhook.com/mousepick.pdf
http://eigenclass.blogspot.com/2008/10/opengl-es-picking-using-ray-boundingbox.html
Basically, first, create a 3D ray from a 2D touch. Then use that ray to check for intersection with objects in your world. You should create the matrix inverse of your current matrix, and from the inverse matrix you can create start and end position using your near and far clip plane. and then when calculating the near and far points you should apply the projection settings.
BTW: In my project, my point recognition is based on color unique pixel comparison rather than ray cast hit check. It is much easier to implement hit check with just finding unique colors. Only a suggestion, hope it helps :)
cheers,
Guvener