I posting this as the complete source of the class, I sure its something to do with the project matrix not working
#import "GLViewController.h"
#import "ConstantsAndMacros.h"
#import "OpenGLCommon.h"
#import "WorldAppDelegate.h"
#import "Tools.h"
#import "glu.h"
#define SPEED_MOVE 0.025
#define SPEED_TURN 0.05
#define MapSizeX 20
#define MapSizeZ 20
typedef struct
{
float x;
float y;
float z;
} IMPoint3D;
@interface GLViewController ()
- (void)updateData;
- (BOOL)checkCollisionWithX:(float)x andWithZ:(float)z;
- (void)loadTextures:(NSString *)textureName andWithIndex:(int)index;
- (void)handleTouches;
- (void)updateCoords;
- (void)setupPlayer;
- (void)addScene;
- (void)loadTextureList;
- (void)loadController;
- (Boolean) checkCollission:(CGPoint)winPos object:(IMPoint3D) _object;
- (CGPoint)getScreenCoorOfPoint:(IMPoint3D)_point3D;
@end
@implementation GLViewController
@synthesize deviceID, players, label,collisionArray, baseURL;
-(void)setupView:(GLView*)view {
const GLfloat zNear = 0.1, zFar = 1000.0, fieldOfView = 120.0;
GLfloat size = zNear * tanf(DEGREES_TO_RADIANS(fieldOfView) / 8.0);
glEnable(GL_DEPTH_TEST);
glMatrixMode(GL_PROJECTION);
//Rotate the view
glRotatef(-90,0,0,1);
CGRect rect = self.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);
// Starting position
eye[0] = -0;
eye[1] = 3;
eye[2] = -10;
center[0] = 0;
center[1] = 1.5;
center[2] = 0;
[self loadTextureList];
[self loadController];
[self loadTextureList ];
[self addScene];
[self setupPlayer];
[self updateCoords];
}
// ...
- (void)drawView:(UIView *)theView {
// floor
const GLfloat floorVertices[] = {
-1, 0.0f, 1,
1, 0.0f, 1,
1, 0.0f, -1,
-1, 0.0f, -1
};
const GLshort floorTextureCoords[] = {
0, 1, // top left
0, 0, // bottom left
1, 0, //bottom right
1, 1 //top right
};
// Colour cube
static const GLubyte cubeNumberOfIndices = 36;
const GLubyte colourCubeFaceColors[] = {
0,255,0,255,
255,125,0,255,
255,0,0,255,
255,255,0,255,
0,0,255,255,
255,0,255,255
};
static const Vertex3D texturedVertices[]= {
{-1.0, 1.0, 1.0}, // vertices[0]
{1.0, 1.0, 1.0}, // vertices[1]
{-1.0, -1.0, 1.0}, // vertices[2]
{-1.0, -1.0, 1.0}, // vertices[3]
{1.0, 1.0, 1.0}, // vertices[4]
{1.0, -1.0, 1.0}, // vertices[5]
{-1.0, 1.0, 1.0}, // vertices[6]
{-1.0, 1.0, -1.0}, // vertices[7]
{-1.0, -1.0, 1.0}, // vertices[8]
{-1.0, -1.0, 1.0}, // vertices[9]
{-1.0, 1.0, -1.0}, // vertices[10]
{-1.0, -1.0, -1.0}, // vertices[11]
{-1.0, 1.0, -1.0}, // vertices[12]
{1.0, 1.0, -1.0}, // vertices[13]
{-1.0, -1.0, -1.0}, // vertices[14]
{-1.0, -1.0, -1.0}, // vertices[15]
{1.0, 1.0, -1.0}, // vertices[16]
{1.0, -1.0, -1.0},
{1.0, 1.0, 1.0},
{1.0, 1.0, -1.0},
{1.0, -1.0, 1.0},
{1.0, -1.0, 1.0},
{1.0, 1.0, -1.0},
{1.0, -1.0, -1.0},
{-1.0, 1.0, 1.0},
{-1.0, 1.0, -1.0},
{1.0, 1.0, 1.0},
{1.0, 1.0, 1.0},
{-1.0, 1.0, -1.0},
{1.0, 1.0, -1.0},
{-1.0, -1.0, 1.0},
{-1.0, -1.0, -1.0},
{1.0, -1.0, 1.0},
{1.0, -1.0, 1.0},
{-1.0, -1.0, -1.0},
{1.0, -1.0, -1.0},
};
static const GLubyte texturedCube[] = {
0, 1, 2,
3, 4, 5,
6, 7, 8,
9, 10, 11,
12, 13, 14,
15, 16, 17,
18, 19, 20,
21, 22, 23,
24, 25, 26,
27, 28, 29,
30, 31, 32,
33, 34, 35,
};
static const GLfloat texturedCubeCoord[] = {
0.0, 1.0,
1.0, 1.0,
0.0, 0.0,
0.0, 0.0,
1.0, 1.0,
1.0, 0.0,
1.0, 1.0,
0.0, 1.0,
1.0, 0.0,
1.0, 0.0,
0.0, 1.0,
0.0, 0.0,
1.0, 1.0,
0.0, 1.0,
1.0, 0.0,
1.0, 0.0,
0.0, 1.0,
0.0, 0.0,
0.0, 1.0,
1.0, 1.0,
0.0, 0.0,
0.0, 0.0,
1.0, 1.0,
1.0, 0.0,
0.0, 1.0,
1.0, 1.0,
0.0, 0.0,
0.0, 0.0,
1.0, 1.0,
1.0, 0.0,
0.0, 1.0,
1.0, 1.0,
0.0, 0.0,
0.0, 0.0,
1.0, 1.0,
1.0, 0.0,
};
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glColor4f(1.0, 1.0, 1.0, 1.0);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
[self handleTouches];
//view : prebaked in to OPenGL Template
gluLookAt(eye[0], eye[1], eye[2],center[0], center[1], center[2], 0.0, 1, 0.0);
// draw the floor
glPushMatrix();
//tell GL about our texture
glMatrixMode(GL_TEXTURE);
glScalef(20,20,1);
glBindTexture(GL_TEXTURE_2D, 3);
glMatrixMode(GL_MODELVIEW);
glScalef(20,1,20);
glTexCoordPointer(2, GL_SHORT, 0, floorTextureCoords);
glVertexPointer(3, GL_FLOAT, 0, floorVertices);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
glPopMatrix();
for (NSString *coords in self.collisionArray) {
NSArray *coordsArray = [coords componentsSeparatedByString:@","];
float x = [[coordsArray objectAtIndex:0] floatValue] ;
float z = [[coordsArray objectAtIndex:1] floatValue] ;
float width = ([[coordsArray objectAtIndex:2] floatValue] /2) ;
float length = ([[coordsArray objectAtIndex:3] floatValue] /2) ;
glPushMatrix();
//tell GL about our texture
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
if (width > length) {
glScalef(width, 3, length);
} else {
glScalef(length, 3, width);
}
glBindTexture(GL_TEXTURE_2D, ([[coordsArray objectAtIndex:4] floatValue]));
glMatrixMode(GL_MODELVIEW);
glTranslatef(x, 3, z);
glScalef(width, 3, length);
glVertexPointer(3, GL_FLOAT, 0, texturedVertices);
glTexCoordPointer(2, GL_FLOAT, 0, texturedCubeCoord);
glDrawElements(GL_TRIANGLES,cubeNumberOfIndices , GL_UNSIGNED_BYTE, texturedCube);
glPopMatrix();
}
float x;
float z;
float playerRotation;
for (NSDictionary *item in self.players) {
x = [[item objectForKey:@"posX"] floatValue];
z = [[item objectForKey:@"posZ"] floatValue];
playerRotation = [[item objectForKey:@"rotation"] floatValue];
glPushMatrix();
glTranslatef(x, 1 , z);
glRotatef(playerRotation, 0, 1, 0);
//Reset textures
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glVertexPointer(3, GL_FLOAT, 0, texturedVertices);
glTexCoordPointer(2, GL_FLOAT, 0, texturedCubeCoord);
glBindTexture(GL_TEXTURE_2D, 1);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, &texturedCube[0]);
glBindTexture(GL_TEXTURE_2D, 4);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, &texturedCube[6]);
int colorIndex = 0;
glBindTexture(GL_TEXTURE_2D, 0);
glColor4ub(colourCubeFaceColors[colorIndex], colourCubeFaceColors[colorIndex+1], colourCubeFaceColors[colorIndex+2], colourCubeFaceColors[colorIndex+3]);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, &texturedCube[12]);
glPopMatrix();
}
// GL teardown
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
CGPoint pos = [[touches anyObject] locationInView:self.view];
int i = 0;
for (NSDictionary *item in self.players) {
IMPoint3D playerPos;
playerPos.x = [[item objectForKey:@"posX"] floatValue];
playerPos.z = [[item objectForKey:@"posZ"] floatValue];
playerPos.y = 1.0f;
if([self checkCollission:pos object:playerPos])
{
NSLog(@"FIRE I LOVE YOU MAN %i", i);
}
}
//left
if ( pos.x >= 35 && pos.x <= 80 && pos.y >= 0 && pos.y <= 40) {
action = ActionTurnLeft;
//right
} else if ( pos.x >= 35 && pos.x <= 80 && pos.y >= 80 && pos.y <= 120) {
action = ActionTurnRight;
//forward
} else if ( pos.x >= 80 && pos.x <= 120 && pos.y >= 32 && pos.y <= 82) {
action = ActionMoveForward;
//back
} else if ( pos.x >= 0 && pos.x <= 40 && pos.y >= 32 && pos.y <= 82) {
action = ActionMoveBackward;
}
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
action = ActionNone;
}
#define RAY_ITERATIONS 1000
#define COLLISION_RADIUS 0.1f
-(Boolean) checkCollission:(CGPoint)winPos object:(IMPoint3D) _object {
glGetFloatv( GL_PROJECTION_MATRIX, __projection );
glGetFloatv( GL_MODELVIEW_MATRIX, __modelview );
glGetIntegerv( GL_VIEWPORT, __viewport );
winPos.y = (float)__viewport[3] - winPos.y;
Point3D nearPoint;
Point3D farPoint;
Point3D rayVector;
//Retreiving position projected on near plan
gluUnProject( winPos.x, winPos.y , 0, __modelview, __projection, __viewport, &nearPoint.x, &nearPoint.y, &nearPoint.z);
//Retreiving position projected on far plan
gluUnProject( winPos.x, winPos.y, 1, __modelview, __projection, __viewport, &farPoint.x, &farPoint.y, &farPoint.z);
//Processing ray vector
rayVector.x = farPoint.x - nearPoint.x;
rayVector.y = farPoint.y - nearPoint.y;
rayVector.z = farPoint.z - nearPoint.z;
float rayLength = sqrtf(POW2(rayVector.x) + POW2(rayVector.y) + POW2(rayVector.z));
//normalizing ray vector
rayVector.x /= rayLength;
rayVector.y /= rayLength;
rayVector.z /= rayLength;
Point3D collisionPoint;
Point3D objectCenter = {_object.x, _object.y, _object.z};
//Iterating over ray vector to check collisions
for(int i = 0; i < RAY_ITERATIONS; i++)
{
collisionPoint.x = rayVector.x * rayLength/RAY_ITERATIONS*i;
collisionPoint.y = rayVector.y * rayLength/RAY_ITERATIONS*i;
collisionPoint.z = rayVector.z * rayLength/RAY_ITERATIONS*i;
//Checking collision
if([Tools poinSphereCollision:collisionPoint center:objectCenter radius:COLLISION_RADIUS])
{
return TRUE;
}
}
return FALSE;
}
/* does not work
-(CGPoint)getScreenCoorOfPoint:(IMPoint3D)_point3D
{
GLfloat p[16]; // Where The 16 Doubles Of The Projection Matrix Are To Be Stored
glGetFloatv(GL_PROJECTION_MATRIX, p); // Retrieve The Projection Matrix
/*
Multiply M * point
*/
//GLfloat _p[] = {p[0]*_point3D.x +p[4]*_point3D.y +p[8]*_point3D.z + p[12],
// p[1]*_point3D.x +p[5]*_point3D.y +p[9]*_point3D.z + p[13],
// p[2]*_point3D.x +p[6]*_point3D.y +p[10]*_point3D.z+ p[14],
// p[3]*_point3D.x +p[7]*_point3D.y +p[11]*_point3D.z+ p[15]};
/*
divide by scale factor
*/
// CGPoint _p2D = {_p[0]/_p[3], _p[1]/_p[3]};
/*
get result in screen coordinates. In this case I'm in landscape mode
*/
//return (CGPoint) {_p2D.x*240.0f + 240.0f, (1.0f - _p2D.y) *160.0f};
}
*/
- (void)handleTouches {
if (action != ActionNone) {
GLfloat v[] = {center[0] - eye[0], center[1] - eye[1], center[2] - eye[2]};
switch (action) {
case ActionMoveForward:
eye[0] += v[0] * SPEED_MOVE;
eye[2] += v[2] * SPEED_MOVE;
center[0] += v[0] * SPEED_MOVE;
center[2] += v[2] * SPEED_MOVE;
if ((eye[2] > MapSizeZ || eye[0] > MapSizeX || eye[2] < -MapSizeZ || eye[0] < -MapSizeX) || [self checkCollisionWithX:eye[0] andWithZ:eye[2]]){
eye[0] -= v[0] * SPEED_MOVE;
eye[2] -= v[2] * SPEED_MOVE;
center[0] -= v[0] * SPEED_MOVE;
center[2] -= v[2] * SPEED_MOVE;
}
break;
case ActionMoveBackward:
eye[0] -= v[0] * SPEED_MOVE;
eye[2] -= v[2] * SPEED_MOVE;
center[0] -= v[0] * SPEED_MOVE;
center[2] -= v[2] * SPEED_MOVE;
if ((eye[2] > MapSizeZ || eye[0] > MapSizeX || eye[2] < -MapSizeZ || eye[0] < -MapSizeX) || [self checkCollisionWithX:eye[0] andWithZ:eye[2]] ){
eye[0] += v[0] * SPEED_MOVE;
eye[2] += v[2] * SPEED_MOVE;
center[0] += v[0] * SPEED_MOVE;
center[2] += v[2] * SPEED_MOVE;
}
break;
case ActionTurnLeft:
center[0] = eye[0] + cos(-SPEED_TURN)*v[0] - sin(-SPEED_TURN)*v[2];
center[2] = eye[2] + sin(-SPEED_TURN)*v[0] + cos(-SPEED_TURN)*v[2];
rotation -=2.865;
break;
case ActionTurnRight:
center[0] = eye[0] + cos(SPEED_TURN)*v[0] - sin(SPEED_TURN)*v[2];
center[2] = eye[2] + sin(SPEED_TURN)*v[0] + cos(SPEED_TURN)*v[2];
rotation +=2.865;
break;
}
}
}
- (void)loadTextures:(NSString *)textureName andWithIndex:(int)index {
// load image as a CG ref
CGImageRef textureImage = [UIImage imageNamed:textureName].CGImage;
// if failed, bail
if (!textureImage) {
NSLog(@"Error: failed to load texture");
return;
}
// figure out the width and height
int texWidth = CGImageGetWidth(textureImage);
int texHeight = CGImageGetHeight(textureImage);
// alloc space for the texture
GLubyte *textureData = (GLubyte *)malloc(texWidth * texHeight * 4);
// create a CA context ref
CGContextRef textureContext = CGBitmapContextCreate(
textureData, texWidth, texHeight, 8, texWidth * 4,
CGImageGetColorSpace(textureImage),
kCGImageAlphaPremultipliedLast
);
// draw the image to in-memory buffer
CGContextDrawImage(textureContext, CGRectMake(0,0,texWidth,texHeight), textureImage);
// done with context - release it
CGContextRelease(textureContext);
// have GL create handle for our texture
glGenTextures(1, &textures[index]);
// tell GL that the image is 2D
glBindTexture(GL_TEXTURE_2D, textures[index]);
// send our data down to GL, copy into graphics hardware
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texWidth, texHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureData);
// free our in-memory copy of the data
free(textureData);
// specify min/max filters
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// tell GL to turn on textures
glEnable(GL_TEXTURE_2D);
}
- (void)updateCoords {
self.players = [[NSMutableArray alloc] initWithContentsOfURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@UpdatePlayer.aspx?playerIndex=%@&posX=%f&posZ=%f&rotation=%f", baseURL, self.deviceID, eye[0], eye[2], rotation]]];
[self updateData];
}
- (void)updateData {
NSInvocationOperation *op = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(updateCoords) object:nil];
[[(WorldAppDelegate *)[[UIApplication sharedApplication] delegate] sharedOperationQueue] addOperation:op];
[op release];
}
- (void)setupPlayer {
// Device id
UIDevice *device = [UIDevice currentDevice];
self.deviceID = [device uniqueIdentifier];
NSDictionary *tempDict = [[[NSDictionary alloc] initWithContentsOfURL:[NSURL URLWithString:[NSString stringWithFormat: @"%@GetPlayerPosition.aspx?playerIndex=%@", baseURL, self.deviceID]]] autorelease];
eye[0] = [[tempDict objectForKey:@"posX"] floatValue];
eye[2] = [[tempDict objectForKey:@"posZ"] floatValue] ;
rotation = [[tempDict objectForKey:@"rotation"] floatValue];
}
- (void)addScene {
self.collisionArray = [[NSMutableArray alloc] init];
[self.collisionArray addObject:@"5,-4,4,4,1"];
[self.collisionArray addObject:@"5, 4,4,4,1"];
[self.collisionArray addObject:@"20,0,1,40,4"];
[self.collisionArray addObject:@"-20,0,1,40,4"];
[self.collisionArray addObject:@"0,-20,40,1,4"];
[self.collisionArray addObject:@"0,20,40,1,4"];
}
- (void)loadTextureList {
[self loadTextures:@"crate.png" andWithIndex:0];
[self loadTextures:@"brick.jpg" andWithIndex:1];
[self loadTextures:@"GrassTexture.png" andWithIndex:2];
[self loadTextures:@"swtexnew.png" andWithIndex:3];
}
- (void)loadController {
self.baseURL = @"http://burf2000.dyndns.org:90/Cubes/";
//Controler
UIImageView *joypadView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"StoneCompass.png"]];
joypadView.frame = CGRectMake(0, 0, 120, 120);
[self.view addSubview:joypadView];
[joypadView release];
}
- (BOOL)checkCollisionWithX:(float)x andWithZ:(float)z {
for (NSString *coords in self.collisionArray) {
NSArray *coordsArray = [coords componentsSeparatedByString:@","];
float x1 = [[coordsArray objectAtIndex:0] floatValue] - ([[coordsArray objectAtIndex:2] floatValue] /2) ;
float z1 = [[coordsArray objectAtIndex:1] floatValue] - ([[coordsArray objectAtIndex:3] floatValue] /2) ;
float x2 = [[coordsArray objectAtIndex:0] floatValue] + ([[coordsArray objectAtIndex:2] floatValue] /2) ;
float z2 = [[coordsArray objectAtIndex:1] floatValue] + ([[coordsArray objectAtIndex:3] floatValue] /2) ;
if ( x > x1 && x < x2 && z > z1 && z < z2 ) {
return YES;
}
}
return NO;
}
- (void)dealloc {
[deviceID release];
[players release];
[collisionArray release];
[label release];
[baseURL release];
[super dealloc];
}
@end
GLKMathUnproject
function so there is no need to port other solutions. It is part ofGLKit Math Utilities
. – Martin Berger