Wednesday, December 17, 2008

gluLookAt()

Somebody asked me for an implementation of gluLookAt() for OpenGL ES. I didn't have one, but I knew where I could get one. The Mesa3D project is a non-licensed, open-source OpenGL-compatible library. Some changes were required to get this function to work under OpenGL ES, but this is, in no way, my work - I just tweaked it a little so that it would compile and run on OpenGL ES 1.1.

gluLookAt.h
/*
* gluLookAt.h
*
* This is a modified version of the function of the same name from
* the Mesa3D project ( http://mesa3d.org/ ), which is licensed
* under the MIT license, which allows use, modification, and
* redistribution
*
* In order to work under OpenGL ES, all instances of GLdouble
* had to be changed to GLfloat, and all "d" function calls had
* to be changed to the "f" versions.
*
* Original developer's comments have been left in place.
*
* Out of respect for the original authors, this is licensed under
* the Mesa (MIT) license. Original license follows:
*
* -----------------------------------------------------------------------
*
* Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.

* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/

#import <Foundation/Foundation.h>
#import <OpenGLES/EAGL.h>
#import <OpenGLES/ES1/gl.h>
#import <OpenGLES/ES1/glext.h>

void gluLookAt(GLfloat eyex, GLfloat eyey, GLfloat eyez,
GLfloat centerx, GLfloat centery, GLfloat centerz,
GLfloat upx, GLfloat upy, GLfloat upz);



gluLookAt.m
/*
* gluLookAt.c
*/


#include "gluLookAt.h"

void gluLookAt(GLfloat eyex, GLfloat eyey, GLfloat eyez,
GLfloat centerx, GLfloat centery, GLfloat centerz,
GLfloat upx, GLfloat upy, GLfloat upz)
{
GLfloat m[16];
GLfloat x[3], y[3], z[3];
GLfloat mag;

/* Make rotation matrix */

/* Z vector */
z[0] = eyex - centerx;
z[1] = eyey - centery;
z[2] = eyez - centerz;
mag = sqrt(z[0] * z[0] + z[1] * z[1] + z[2] * z[2]);
if (mag) { /* mpichler, 19950515 */
z[0] /= mag;
z[1] /= mag;
z[2] /= mag;
}

/* Y vector */
y[0] = upx;
y[1] = upy;
y[2] = upz;

/* X vector = Y cross Z */
x[0] = y[1] * z[2] - y[2] * z[1];
x[1] = -y[0] * z[2] + y[2] * z[0];
x[2] = y[0] * z[1] - y[1] * z[0];

/* Recompute Y = Z cross X */
y[0] = z[1] * x[2] - z[2] * x[1];
y[1] = -z[0] * x[2] + z[2] * x[0];
y[2] = z[0] * x[1] - z[1] * x[0];

/* mpichler, 19950515 */
/* cross product gives area of parallelogram, which is < 1.0 for
* non-perpendicular unit-length vectors; so normalize x, y here
*/


mag = sqrt(x[0] * x[0] + x[1] * x[1] + x[2] * x[2]);
if (mag) {
x[0] /= mag;
x[1] /= mag;
x[2] /= mag;
}

mag = sqrt(y[0] * y[0] + y[1] * y[1] + y[2] * y[2]);
if (mag) {
y[0] /= mag;
y[1] /= mag;
y[2] /= mag;
}

#define M(row,col) m[col*4+row]
M(0, 0) = x[0];
M(0, 1) = x[1];
M(0, 2) = x[2];
M(0, 3) = 0.0;
M(1, 0) = y[0];
M(1, 1) = y[1];
M(1, 2) = y[2];
M(1, 3) = 0.0;
M(2, 0) = z[0];
M(2, 1) = z[1];
M(2, 2) = z[2];
M(2, 3) = 0.0;
M(3, 0) = 0.0;
M(3, 1) = 0.0;
M(3, 2) = 0.0;
M(3, 3) = 1.0;
#undef M
glMultMatrixf(m);

/* Translate Eye to Origin */
glTranslatef(-eyex, -eyey, -eyez);

}




11 comments:

adam said...

Thanks a tonne this exactly what I was looking for. Now I know I can check mesa3d.org when I need something that's missing.

Cheers,
Adam

weaksauce said...

You might also need to include the license found here: http://mesa3d.org/license.html

I am not a lawyer though.

Memphis said...

Hi, I tried to compile your code with my existing code.
I'm newbie to the xcode and Object-C. When I add you files into my projects, xcode finds 2000 errors inside NSObjRuntime.h.

Am I missing some sort of configuration? I also changed the extension of all files from m to mm but it didn't work either.

I would really appreciated if you give me some hints.

Thanks
Memphis

Memphis said...

Hi again,
I fixed that, My problem was having gluLookAt.c instead of gluLookAt.m. silly me!

Memphis

Ken said...

It would be great to see this used in your examples for the OpenGL ES tutorial you did. Moving the 'camera' around the 10 rotating icosahedrons would be a great way to show how to move around a 3D environment.

Thanks for posting this.

Randy said...

Can you explain why you do eye-center, instead of center-eye, which it seems like analogous code from other libraries is doing?

Edwin said...

scrub m65 kamagra attorney lawyer body scrub field jacket lovegra marijuana attorney injury lawyer

JeansPilot said...

JeansPilot offers the chance to buy a large variety of men’s and women’s jeans clothing from the world famous Italian Brands.
Online jeans clothing store looks for original fashion clothing sales and clearances of worldwide known designers. We participate in fashion auctions to get the lowest possible price for Top quality Clothes, Shoes and Accessories.
Buy Jeans

h4ns said...

What youre saying is completely true. I know that everybody must say the same thing, but I just think that you put it in a way that everyone can understand. I also love the images you put in here. They fit so well with what youre trying to say. Im sure youll reach so many people with what youve got to say.

Arsenal vs Huddersfield Town live streaming
Arsenal vs Huddersfield Town live streaming
Wolverhampton Wanderers vs Stoke City Live Streaming
Wolverhampton Wanderers vs Stoke City Live Streaming
Notts County vs Manchester City Live Streaming
Notts County vs Manchester City Live Streaming
Bologna vs AS Roma Live Streaming
Bologna vs AS Roma Live Streaming
Juventus vs Udinese Live Streaming
Juventus vs Udinese Live Streaming
Napoli vs Sampdoria Live Streaming
Napoli vs Sampdoria Live Streaming
Fulham vs Tottenham Hotspur Live Streaming
Fulham vs Tottenham Hotspur Live Streaming
AS Monaco vs Marseille Live Streaming
AS Monaco vs Marseille Live Streaming
Alajuelense vs Perez Zeledon Live Streaming
Alajuelense vs Perez Zeledon Live Streaming
Technology News | News Today | Live Streaming TV Channels

J said...

I dont understand the section in the #define. Can you explain what the macro is doing exactly? How does it work? Thanks

rTi said...

the define just makes the matrix access look two dimensional even it accesses an one dimensional array... so see it as a source code beautifier.