## OpenGL ES Z axis not working

Code:

`[EAGLContext setCurrentContext:context];`

glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);

glViewport(0, 0, backingWidth, backingHeight);

glMatrixMode(GL_PROJECTION);

glLoadIdentity();

glOrthof(-1.0f, 1.0f, -1.5f, 1.5f, -10.0f, 10.0f);

glClearColor(0.2f, 0.2f, 0.2f, 1.0f);

glClear(GL_COLOR_BUFFER_BIT);

glLoadIdentity();

glPushMatrix();

glTranslatef([object x], [object y], [object z]);

[object drawObjectVBO];

glPopMatrix();

glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);

[context presentRenderbuffer:GL_RENDERBUFFER_OES];

If you want a top-down view with perspective you can use gluPerspective() so set up the projection, and gluLookAt() to place your camera on the Z axis looking at the origin.

Cheers

- Iain

IBethune Wrote:If you want a top-down view with perspective you can use gluPerspective() so set up the projection, and gluLookAt() to place your camera on the Z axis looking at the origin.

...at least, you could if they were included with OpenGL ES. Here's a similar alternative to gluPerspective() (from Matrix.c in my matrix tutorial):

Code:

`struct Matrix {`

float m[16];

};

typedef struct Matrix Matrix;

void Matrix_loadIdentity(Matrix * matrix) {

matrix->m[0] = 1.0;

matrix->m[1] = 0.0;

matrix->m[2] = 0.0;

matrix->m[3] = 0.0;

matrix->m[4] = 0.0;

matrix->m[5] = 1.0;

matrix->m[6] = 0.0;

matrix->m[7] = 0.0;

matrix->m[8] = 0.0;

matrix->m[9] = 0.0;

matrix->m[10] = 1.0;

matrix->m[11] = 0.0;

matrix->m[12] = 0.0;

matrix->m[13] = 0.0;

matrix->m[14] = 0.0;

matrix->m[15] = 1.0;

}

Matrix Matrix_identity() {

Matrix matrix;

Matrix_loadIdentity(&matrix);

return matrix;

}

void Matrix_multiply(Matrix * matrix1, Matrix m2) {

Matrix m1, result;

m1 = *matrix1;

result.m[0] = m1.m[0] * m2.m[0] + m1.m[4] * m2.m[1] + m1.m[8] * m2.m[2] + m1.m[12] * m2.m[3];

result.m[1] = m1.m[1] * m2.m[0] + m1.m[5] * m2.m[1] + m1.m[9] * m2.m[2] + m1.m[13] * m2.m[3];

result.m[2] = m1.m[2] * m2.m[0] + m1.m[6] * m2.m[1] + m1.m[10] * m2.m[2] + m1.m[14] * m2.m[3];

result.m[3] = m1.m[3] * m2.m[0] + m1.m[7] * m2.m[1] + m1.m[11] * m2.m[2] + m1.m[15] * m2.m[3];

result.m[4] = m1.m[0] * m2.m[4] + m1.m[4] * m2.m[5] + m1.m[8] * m2.m[6] + m1.m[12] * m2.m[7];

result.m[5] = m1.m[1] * m2.m[4] + m1.m[5] * m2.m[5] + m1.m[9] * m2.m[6] + m1.m[13] * m2.m[7];

result.m[6] = m1.m[2] * m2.m[4] + m1.m[6] * m2.m[5] + m1.m[10] * m2.m[6] + m1.m[14] * m2.m[7];

result.m[7] = m1.m[3] * m2.m[4] + m1.m[7] * m2.m[5] + m1.m[11] * m2.m[6] + m1.m[15] * m2.m[7];

result.m[8] = m1.m[0] * m2.m[8] + m1.m[4] * m2.m[9] + m1.m[8] * m2.m[10] + m1.m[12] * m2.m[11];

result.m[9] = m1.m[1] * m2.m[8] + m1.m[5] * m2.m[9] + m1.m[9] * m2.m[10] + m1.m[13] * m2.m[11];

result.m[10] = m1.m[2] * m2.m[8] + m1.m[6] * m2.m[9] + m1.m[10] * m2.m[10] + m1.m[14] * m2.m[11];

result.m[11] = m1.m[3] * m2.m[8] + m1.m[7] * m2.m[9] + m1.m[11] * m2.m[10] + m1.m[15] * m2.m[11];

result.m[12] = m1.m[0] * m2.m[12] + m1.m[4] * m2.m[13] + m1.m[8] * m2.m[14] + m1.m[12] * m2.m[15];

result.m[13] = m1.m[1] * m2.m[12] + m1.m[5] * m2.m[13] + m1.m[9] * m2.m[14] + m1.m[13] * m2.m[15];

result.m[14] = m1.m[2] * m2.m[12] + m1.m[6] * m2.m[13] + m1.m[10] * m2.m[14] + m1.m[14] * m2.m[15];

result.m[15] = m1.m[3] * m2.m[12] + m1.m[7] * m2.m[13] + m1.m[11] * m2.m[14] + m1.m[15] * m2.m[15];

*matrix1 = result;

}

void Matrix_applyPerspective(Matrix * matrix, float fovY, float aspect, float zNear, float zFar) {

Matrix perspectiveMatrix;

float sine, cotangent, deltaZ;

fovY = (degreesToRadians(fovY) / 2.0f);

deltaZ = (zFar - zNear);

sine = sin(fovY);

if (deltaZ == 0.0f || sine == 0.0f || aspect == 0.0f) {

return;

}

cotangent = (cos(fovY) / sine);

Matrix_loadIdentity(&perspectiveMatrix);

perspectiveMatrix.m[0] = (cotangent / aspect);

perspectiveMatrix.m[5] = cotangent;

perspectiveMatrix.m[10] = (-(zFar + zNear) / deltaZ);

perspectiveMatrix.m[11] = -1.0f;

perspectiveMatrix.m[14] = ((-2.0f * zNear * zFar) / deltaZ);

perspectiveMatrix.m[15] = 0.0f;

Matrix_multiply(matrix, perspectiveMatrix);

}

Matrix Matrix_perspective(Matrix matrix, float fovY, float aspect, float zNear, float zFar) {

Matrix_applyPerspective(&matrix, fovY, aspect, zNear, zFar);

return matrix;

}

void setPerspective(float fovY, float aspect, float zNear, float zFar) {

Matrix matrix;

matrix = Matrix_perspective(Matrix_identity(), fovY, aspect, zNear, zFar);

glMultMatrixf(matrix.m);

}

With that, you can call setPerspective() the same way you'd call gluPerspective().

ThemsAllTook Wrote:...at least, you could if they were included with OpenGL ES.

My bad, didn't notice we were in the iPhone forum. The explanation still stands though.

lightbringer Wrote:For simplicity you could manually scale (glScale) the object based on it's depth value - make it smaller when it's further away or larger when it's close.

That kinda defeats the purpose of an orthographic projection -- just use glFrustum()l.

In regards to the above link, note that OpenGL man pages are best read in Terminal for the simple reason that their web-counterparts aren't translated 100% correctly -- dividends, for example, are absent altogether in division.

For those that don't know, reading man pages is as simple as firing up Terminal and typing

Code:

`man glFrustum`

As an easy example of where you could beat the GL: OpenGL always does 3 dimensional calculations. If you're only transforming in two then you can cut out a bunch right there. Or if you know what order you're doing your transforms, and/or don't need to stack them, you can cut out matrices altogether with a custom calculation. Simply put: No matter how much highly optimized assembly is built into the API for the general case, skipping all of it for a single add or multiply will utterly smoke it, if you know that's all you need for your particular transform.

Personally though, I prefer the easier approach of just letting the GL do it for me in the general case first. If there's a performance or usage issue discovered later, then I roll my own, which is fun too.

They're convenient for small demos, but not much beyond that.

OneSadCookie Wrote:... the most you'll use is PushMatrix/PopMatrix/MultMatrix, and that's scarcely rocket science to replicate given you already have your own matrix multiplication .

In fact, I *just* did that myself (for 3x3 2D matrix transforms) so I can testify that it is brain-dead simple to do. It's like a total of 60 lines of code, including embellishments for init/loadIdentity/push/pop. Oh, and then another 15 for transformVerts. Tack on another hundred for translate rotate scale and extra stuff and that's my entire 2D transform library. Definitely no rocket science required.

But still, I can't see having to copy/paste transform utilities into every stinkin little demo. And that would add a big notch of uncertainty to what beginners are using for their transforms too. Maybe the transform utilities will just be moved out of the core GL and into a utility library instead, like glu or something?

Isn't this what hardware T&L was supposed to do? Seems kind of backwards.