I am reading a book on OpenGL, SDL, and have read some of the OpenGL documentation. I have also read this post: What does glLoadIdentity() do in OpenGL?
I am grasping what glLoadIdentity() does, and why it is used in a general sense (to return the current matrix back to its original state). What I do not know is why I am returning it to its original state. For instance:
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0f, 640, 480, 0.0f, -1.0f, 1.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
I am not exactly sure why glLoadIdentity() has to be called after each call to glMatrixMode.
When to call glMatrixMode() -- 1st answer tries to explain:
glLoadIdentity() is typically called immediately after a matrix mode change so you are starting "fresh" if you will. Matrix transforms such as the gluPerspective(), glOrtho(), glFrustum(), glRotate(), glMultMatrix(), glTranslate() are cumulative operations because they aggregate to allow you to describe complex 3D world space transforms or to describe your OpenGL viewing volume. Example: if I want a cube translated in the +X direction then rotated around the Z axis I issue a glRotate() followed by a glTranslate().
glLoadIdentity() wipes out the matrix (of the current matrix mode) with the identity matrix so following a gluPerspective() by glLoadIdentity() is equivalent to a single call to glLoadIdentity(). In other words, that sequence is nonsensical.
Related
I am doing in a simplistic experiment as below:
glPushMatrix();
glGetDoublev(GL_MODELVIEW, modelMatrix);
glTranslatef(...);
glGetDoublev(GL_MODELVIEW, modelMatrix);
glPopMatrix();
However, after the translation, there is not change in the modelview matrix. I am wondering why is that, and how can I see the effect of this translation? In other words, how can I get the transformation marix?
Your code is invalid. The correct enum for glGet...() is GL_MODELVIEW_MATRIX, not GL_MODELVIEW (which is a constant for use glMatrixMode()), so all you get is some GL error, and the memory at modelMatrix will be not touched at all, so it is probably just left uninitialized.
I'm currently trying to get to know the basics with the means of OpenGL.
At the time I try to render a Floating Cube with a Pyramid beneath it. I want the Cube to rotate on Input (which is already working) and the Pyramid to stay where it's supposed to be.
After figuring out the use of Push- and PopMatrix I managed to rotate only the cube.
My Problem is, that the Cube stops rotating as soon as I let go of the key.
The player.X and Player.Z aren't reset at that point (checked that).
So my guess is that PushMatrix puts some kind of standard matrix onto the stack, then rotates it and displays it. Because of 1 * x always equalling x there is no rotation.
So the question is:
How do I manage to push the "old" matrix onto the stack, rather than the new one?
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glPushMatrix();
glRotatef( -(player->Z), 1.0f, 0.0f, 0.0f );
glRotatef( -(player->X), 0.0f, 1.0f, 0.0f );
glBegin( GL_QUADS );
//Draw Cube
glEnd();
glPopMatrix( );
glBegin( GL_TRIANGLES );
//Draw Pyramid
glEnd();
glFlush();
SwapBuffers (hDC);
glPushMatrix() does not push a 'standard' matrix onto the stack, it pushes the current matrix. Hopefully you've initialised the matrix at some point with a glLoadIdentity(), and possibly some initial transforms to set up the view, and so this is what will be pushed.
You should not generally keep updating that matrix from frame to frame, as errors will eventually accumulate.
Instead, update your rotation values in some update loop, rather than in the key-down routine.
Also, note that this method of rendering with GL is considered deprecated. The recommended approach is to use the programmable pipeline, which involves creating your own matrices (amongst other changes).
(if you desperately want to keep a persistent transform while also pushing and popping to render other things, it is possible to read the current matrix with a glGet(), store it somewhere, and then perform a glLoadMatrix() to restore it again later... but don't do that for this.)
(Using OpenGL, GLUT, GLU, and C)
I am trying to create a 3D game in C, and I have the camera movement, collision detection and all of the main stuff ready, however I have failed at the first hurdle. To create my rectangles I am using
glutSolidCube (2.0);
And I know about tranformations and scale and rotations, however I am looking for how to place it in a precise location. Say I had a 3D space, with XYZ. Say I had the camera at 5,5,20, looking towards 0,0,0 (So at an angle) and wanted to place a Cube at 5,2,10, and then another at -5,-2,20. How would I use these absolute positions? Also, how would I use absolute sizes, so say I wanted the one at -5,-2,20 to be 20,5,10 in size. How would I do this in OpenGL?
You'll have to use the functions:
glTranslatef()
glRotatef()
glScalef()
Additionally, also learn these:
glPushMatrix()
glPopMatrix()
Read the OpenGL reference for details.
First forget about glutSolidCube. GLUT is not a part of OpenGL, it's just a small convenience library for it.
You must understand the OpenGL only deals with points, lines and tranangles. And it doesn't maintain a scene, but its merely drawing points, lines and triangles. Each on its own without any connotation of topology. Also OpenGL should not be confused for some math library. The functions glTranslate, glRotate, glScale and so on are a pure legacy and have been removed from contemporary OpenGL versions.
That being said...
Say I had the camera at 5,5,20, looking towards 0,0,0 (So at an angle) and wanted to place a Cube at 5,2,10, and then another at -5,-2,20. How would I use these absolute positions? Also, how would I use absolute sizes, so say I wanted the one at -5,-2,20 to be 20,5,10 in size. How would I do this in OpenGL?
I'll go along with what you already know (which mans old OpenGL-1.1 and GLUT):
void draw()
{
/* Viewport and projection really should be set in the
drawing handler. They don't belong into the reshape. */
glViewport(...);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
your_projection();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(5, 5, 20, 0, 0, 0, 0, 1, 0);
glPushMatrix();
glTranslatef(5, 2, 10);
draw_cube();
glPopMatrix();
glPushMatrix();
glTranslatef(-5, -2, 20);
draw_cube();
glPopMatrix();
glPushMatrix();
glTranslatef(-5, -2, 20);
glScalef(20, 5, 10);
draw_cube();
glPopMatrix();
}
I am working with C and OpenGL. I am trying to load a 3D model with skeletal animation, but I just can't seem to calculate the absolute matrix of each bone for each frame of the animation.
I have: For each bone, I have a matrix and an inverse matrix and for each frame of the animation, I have a rotation(Euler) and a translation for each bone.
Blender Import/Export scripts:
http://pastebin.com/xMJ2fG26
http://pastebin.com/9D42RKRf
edit: if someone knows how to get a bone's absolute matrix with blender and export that, that would also be fine (I'm new to Blender)
for each frame f
for each bone i
glLoadIdentity();
glMultMatrixd(bones[i].matrix);
for each parent bone ii(starting from the top)
glTranslated(bones[ii].translation[f].x, bones[ii].translation[f].y, bones[ii].translation[f].z);
glRotated(bones[ii].degrees[f].z, 0.0, 0.0, 1.0);
glRotated(bones[ii].degrees[f].x, 1.0, 0.0, 0.0);
glRotated(bones[ii].degrees[f].y, 0.0, 1.0, 0.0);
glMultMatrixd(bones[i].inversematrix);
glGetDoublev(GL_PROJECTION_MATRIX, bones[i].absmatrix[f]);
Those scripts look like they were written for the obsolete 2.4*x* versions of Blender. For 2.5*x*/2.6*x*, you have a much-improved Python API that includes Bone objects with “matrix” and “matrix_local” attributes.
I’d recommend you try to do what you want to do with a current version of Blender. Much less likely to be hitting your head against a brick wall that way.
In your comment to Lawrence you're right that your 2.4 scripts will not work for Blender 2.5. However your problem is not very complicated. The matrices you get are the local transformation from each bone to the next one. So all you need to do it multiplying them one after another in the dependency tree.
So what you do is a depth-first traversal of the tree, and for each iteration down the tree you ad a glPushMatrix(); glMultMatrix(bone_matrix); and when going up a step reverse the effect with glPopMatrix();
I've been trying to get a HUD texture to display for a simulator for a while now, without success.
First I bind the texture like this:
glGenTextures(1,&hudTexObj);
gHud = getPPM("textures/purplenebula/hud.ppm",&n,&m,&s);
glBindTexture(GL_TEXTURE_2D,hudTexObj);
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
//glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,n,m,0,GL_RGB,GL_UNSIGNED_INT, gHud);
And then I attempt to map it to a QUAD, which results in the whole quad being a single brown color, and I want it to use all the texels. Here's how I map:
glBindTexture(GL_TEXTURE_2D,hudTexObj);
glBegin(GL_QUADS);
glTexCoord2f(0.0,0.0);
glVertex2f(0,0);
glTexCoord2f(0.0,1.0);
glVertex2f(0,m);
glTexCoord2f(1.0,1.0);
glVertex2f(n,m);
glTexCoord2f(1.0,0.0);
glVertex2f(n,0);
glEnd();
The weird thing is that I've been able to get the exact above code to display the texture in a program of its own, yet when I put it into my main program it fails. Could it have to do with the texture matrix? I'm dumbfounded at this point.
Stupidly, I had enabled automatic tex coord generation far away in another part of the code. So if you see one texel's color covering a whole image, that is the likely cause.