Skip to main content
gamedev.net
🔒 Locked

problems with object rotation.

Started by TechnoGoth Jul 18, 2003 at 12:31 AM 13 replies 750+ views
Original Post
TechnoGoth
TechnoGoth
I'm trying to rotate an object through keyboard input around its y axis. The object being the game character... at present its just a cube. this is the command I'm using: glRotatef(actorR,0.0f,1.0f,0.0f); but the problem is that turning the actor like I want it to do. It rotates the actor around a fixed point in the center of the scene. Can anyone help me fix this problem? i'm using a modifed version of NeHe's lesson 10 moving through a 3d world... I don't think that should matter though. Or should I just give up and write my rotation function? [edited by - TechnoGoth on July 18, 2003 1:33:57 AM]
MeeZ
MeeZ
Hi TechnoGoth,

I''m only new at this OpenGL coding, but i have a thought. Are you using glLoadIdentity(); before this call. What i recomend is something like:

glPushMatrix();
glLoadIdentity();
DrawActorR(); // Call your draw cube function or whatever it is
glRotatef(actorR,0.0f,1.0f,0.0f); // Then rotate about IT''S axis
glPopMatrix(); // restore previous matrix

What it seems is that you are rotating about the intitial Origin of the screen. Not the center (origin) of your objects axis. In that case your object would appear to spin about the center of the screen, and not about itself on it''s y-axis.

I hope I make sense, I aren''t that good at explaining this stuff.

Happy Coding,

Cheers,

MeeZ
MeeZ
Sphax
Sphax
TechnoGot : Can you post your drawing routine code ?

Meez : glRotate should be called before drawing the object you want to rotate , not after

Sphax
TechnoGoth
TechnoGoth
sure, its a pretty basic code, I''m assuming there something missing thats perventing me from using the objects axis to rotate.

int InitGL(GLvoid) // All Setup For OpenGL Goes Here
{
if (!LoadGLTextures()) // Jump To Texture Loading Routine
{
return FALSE; // If Texture Didn''t Load Return FALSE
}

glEnable(GL_TEXTURE_2D); // Enable Texture Mapping
glBlendFunc(GL_SRC_ALPHA,GL_ONE); // Set The Blending Function For Translucency
glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // This Will Clear The Background Color To Black
glClearDepth(1.0); // Enables Clearing Of The Depth Buffer
glDepthFunc(GL_LESS); // The Type Of Depth Test To Do
glEnable(GL_DEPTH_TEST); // Enables Depth Testing
glShadeModel(GL_SMOOTH); // Enables Smooth Color Shading
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really Nice Perspective Calculations

SetupWorld();

return TRUE; // Initialization Went OK
}

int DrawGLScene(GLvoid) // Here''s Where We Do All The Drawing
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear The Screen And The Depth Buffer
glLoadIdentity(); // Reset The View

GLfloat x_m, y_m, z_m, u_m, v_m;
GLfloat xtrans = -xpos;
GLfloat ztrans = -zpos;
GLfloat ytrans = -walkbias-0.25f;
GLfloat sceneroty = 360.0f - yrot;

int numtriangles;

glRotatef(lookupdown,1.0f,0,0);
glRotatef(sceneroty,0,1.0f,0);

glTranslatef(xtrans, ytrans, ztrans);

glBindTexture(GL_TEXTURE_2D, texture[0]);

numtriangles = sector1.numtriangles;

// Process Each Triangle
for (int loop_m = 0; loop_m < numtriangles; loop_m++)
{
glBegin(GL_TRIANGLES);
glNormal3f( 0.0f, 0.0f, 1.0f);
x_m = sector1.triangle[loop_m].vertex[0].x;
y_m = sector1.triangle[loop_m].vertex[0].y;
z_m = sector1.triangle[loop_m].vertex[0].z;
u_m = sector1.triangle[loop_m].vertex[0].u;
v_m = sector1.triangle[loop_m].vertex[0].v;
glTexCoord2f(u_m,v_m); glVertex3f(x_m,y_m,z_m);

x_m = sector1.triangle[loop_m].vertex[1].x;
y_m = sector1.triangle[loop_m].vertex[1].y;
z_m = sector1.triangle[loop_m].vertex[1].z;
u_m = sector1.triangle[loop_m].vertex[1].u;
v_m = sector1.triangle[loop_m].vertex[1].v;
glTexCoord2f(u_m,v_m); glVertex3f(x_m,y_m,z_m);

x_m = sector1.triangle[loop_m].vertex[2].x;
y_m = sector1.triangle[loop_m].vertex[2].y;
z_m = sector1.triangle[loop_m].vertex[2].z;
u_m = sector1.triangle[loop_m].vertex[2].u;
v_m = sector1.triangle[loop_m].vertex[2].v;
glTexCoord2f(u_m,v_m); glVertex3f(x_m,y_m,z_m);
glEnd();
}

glRotatef(actorR,0.0f,1.0f,0.0f);
DrawGLActor(); // Reset The View
return TRUE; // Everything Went OK
}

int DrawGLActor()
{
glBindTexture(GL_TEXTURE_2D, texture[0]);
//FRONT
glBegin(GL_QUADS);
glTexCoord2f(1.0f, 1.0f); glVertex3f(actorX, actorY, actorZ);
glTexCoord2f(1.0f, 0.0f); glVertex3f(actorX+actorW, actorY, actorZ);
glTexCoord2f(0.0f, 0.0f); glVertex3f(actorX+actorW, actorY+actorH, actorZ);
glTexCoord2f(0.0f, 1.0f); glVertex3f(actorX, actorY+actorH, actorZ);
glEnd();

glBindTexture(GL_TEXTURE_2D, texture[1]);
//BACK
glBegin(GL_QUADS);
glTexCoord2f(1.0f, 1.0f); glVertex3f(actorX, actorY, actorZ+actorW);
glTexCoord2f(1.0f, 0.0f); glVertex3f(actorX+actorW, actorY, actorZ+actorW);
glTexCoord2f(0.0f, 0.0f); glVertex3f(actorX+actorW, actorY+actorH, actorZ+actorW);
glTexCoord2f(0.0f, 1.0f); glVertex3f(actorX, actorY+actorH, actorZ+actorW);
glEnd();
//LEFT
glBegin(GL_QUADS);
glTexCoord2f(1.0f, 1.0f); glVertex3f(actorX, actorY, actorZ);
glTexCoord2f(1.0f, 0.0f); glVertex3f(actorX, actorY, actorZ+actorW);
glTexCoord2f(0.0f, 0.0f); glVertex3f(actorX, actorY+actorH, actorZ+actorW);
glTexCoord2f(0.0f, 1.0f); glVertex3f(actorX, actorY+actorH, actorZ);
glEnd();
//RIGHT
glBegin(GL_QUADS);
glTexCoord2f(1.0f, 1.0f); glVertex3f(actorX+actorW, actorY, actorZ);
glTexCoord2f(1.0f, 0.0f); glVertex3f(actorX+actorW, actorY, actorZ+actorW);
glTexCoord2f(0.0f, 0.0f); glVertex3f(actorX+actorW, actorY+actorH, actorZ+actorW);
glTexCoord2f(0.0f, 1.0f); glVertex3f(actorX+actorW, actorY+actorH, actorZ);
glEnd();
//TOP
glBegin(GL_QUADS);
glTexCoord2f(1.0f, 1.0f); glVertex3f(actorX, actorY+actorH, actorZ);
glTexCoord2f(1.0f, 0.0f); glVertex3f(actorX+actorW, actorY+actorH, actorZ);
glTexCoord2f(0.0f, 0.0f); glVertex3f(actorX+actorW, actorY+actorH, actorZ+actorW);
glTexCoord2f(0.0f, 1.0f); glVertex3f(actorX, actorY+actorH, actorZ+actorW);
glEnd();


}

as you can see its just a basic drawing routine
Sphax
Sphax
Is your "actor" centered in the origin when you draw it with no call to glRotate and glTranslate before ? If no, then it should. glRotate makes a rotation around the world axes not your object''s one, i don''t know if i''m clear , but what you should do is :

glTranslate(MyActorLocation)
glRotate(RotationAngle,0, 1,0)
DrawYourActorCenteredInTheOrigin()

and you''ll obtain what i think you want
Sphax
mheikela
mheikela
Hi TechnoGoth,

I''ll first try to explain briefly what this is all about, but if that''s confusing you might just try to look at the example commands at the end.

GlRotatef does basically the following: It first constructs a transformation matrix that corresponds to rotation about an axis that goes through the origin and points to the direction of the vector given as the last three arguments. Then it multiplies the current model-view matrix with this new matrix and stores the resulting matrix as the model-view matrix (assuming the correct matrix-mode, which you probably were using - given the symptoms you describe).

In practice this multiplication means that when processing vertices the rotation is applied first, and then any transformations that were in the model-view matrix before the call to glRotatef.

So to get around the fact that glRotatef always rotates about the origin, you''ll want the rotation to happen first, and only then translate your object where it belongs. This means you must do the translation with glTranslatef command and not by hand.

Example code: (may contain severe syntax errors, I''ve lately used OpenGL through lisp mostly, so my C is rusty. The point is the ordering of the commands)

glLoadIdentity();

// If you have a complex scene you may do other
// transformations here.

glTranslatef(actorX,actorY,actorZ);
glRotatef(actorR,0.0f,1.0f,0.0f);

// Here come commands that would alone draw your character
// in the origin facing in a fixed direction.

Hope this helps,

Mikko
Kaezin
Kaezin
Try replacing your DrawGLActor with this instead:


int DrawGLActor()
{
glPushMatrix();
glLoadIdentity();
glTranslatef(actorX,actorY,actorZ);

glRotatef(actorR,0.0f,1.0f,0.0f);

glBindTexture(GL_TEXTURE_2D, texture[0]);
//FRONT

glBegin(GL_QUADS);
glTexCoord2f(1.0f, 1.0f); glVertex3f(0, 0, 0);
glTexCoord2f(1.0f, 0.0f); glVertex3f(actorW, 0, 0);
glTexCoord2f(0.0f, 0.0f); glVertex3f(actorW, actorH, 0);
glTexCoord2f(0.0f, 1.0f); glVertex3f(0, actorH, 0);
glEnd();

glBindTexture(GL_TEXTURE_2D, texture[1]);
//BACK

glBegin(GL_QUADS);
glTexCoord2f(1.0f, 1.0f); glVertex3f(0, 0, actorW);
glTexCoord2f(1.0f, 0.0f); glVertex3f(actorW, 0, actorW);
glTexCoord2f(0.0f, 0.0f); glVertex3f(actorW, actorH, actorW);
glTexCoord2f(0.0f, 1.0f); glVertex3f(0, actorH, actorW);
glEnd();
//LEFT

glBegin(GL_QUADS);
glTexCoord2f(1.0f, 1.0f); glVertex3f(0, 0, 0);
glTexCoord2f(1.0f, 0.0f); glVertex3f(0, 0, actorW);
glTexCoord2f(0.0f, 0.0f); glVertex3f(0, actorH, actorW);
glTexCoord2f(0.0f, 1.0f); glVertex3f(0, actorH, 0);
glEnd();
//RIGHT

glBegin(GL_QUADS);
glTexCoord2f(1.0f, 1.0f); glVertex3f(actorW, 0, 0);
glTexCoord2f(1.0f, 0.0f); glVertex3f(actorW, 0, actorW);
glTexCoord2f(0.0f, 0.0f); glVertex3f(actorW, actorH, actorW);
glTexCoord2f(0.0f, 1.0f); glVertex3f(actorW, actorH, 0);
glEnd();
//TOP

glBegin(GL_QUADS);
glTexCoord2f(1.0f, 1.0f); glVertex3f(0, actorH, 0);
glTexCoord2f(1.0f, 0.0f); glVertex3f(actorW, actorH, 0);
glTexCoord2f(0.0f, 0.0f); glVertex3f(actorW, actorH, actorW);
glTexCoord2f(0.0f, 1.0f); glVertex3f(0, actorH, actorW);
glEnd();

glPopMatrix();
}


I hope that works. If it does and you need me to explain what your problem was, I'd be happy to.

And use the source tags with brackets [].

[edited by - Kaezin on July 19, 2003 1:29:45 AM]
Half the people you know are below average.Trogdor the Burninator
LockePick
LockePick
load identity
rotate/translate "camera"
push matrix
translate actor
rotate actor
pop matrix

Don''t put an extra glLoadIdentity in the DrawGLActor, it will kill any previous camera setup you have and just place objects around the physical screen (z-axis pointing out of the screen).
TechnoGoth
TechnoGoth
It still not working, It still the same result no matter what I try. Can some please post a link to some source code that does what I''m trying to do? Maybe If i look at some one else work I can find where the fault is in my code. There is obviously something wrong with some where in my code.

all I''m trying to do for now, is have a 3d scene with an object that can be rotated around its own axis using the left or right keys
RGH
RGH
I think you''re main problem is the way you''re positioning you''re "actor". The entire box is not centered on the origin, the bottom corner is. Try this for your DrawGLActor routine (then move on to the glPushMatrix and glPopMatrix methods discussed earlier):

int DrawGLActor()
{

glBindTexture(GL_TEXTURE_2D, texture[0]);

float halfwidth = actorW/2;

//FRONT
glBegin(GL_QUADS);
glTexCoord2f(1.0f, 1.0f); glVertex3f(-halfwidth, 0, -halfwidth);
glTexCoord2f(1.0f, 0.0f); glVertex3f(halfwidth, 0, -halfwidth);
glTexCoord2f(0.0f, 0.0f); glVertex3f(halfwidth, actorH, -halfwidth);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-halfwidth, actorH, -halfwidth);
glEnd();

glBindTexture(GL_TEXTURE_2D, texture[1]);
//BACK
glBegin(GL_QUADS);
glTexCoord2f(1.0f, 1.0f); glVertex3f(-halfwidth, 0, halfwidth);
glTexCoord2f(1.0f, 0.0f); glVertex3f(halfwidth, 0, halfwidth);
glTexCoord2f(0.0f, 0.0f); glVertex3f(halfwidth, actorH, halfwidth);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-halfwidth, actorH, halfwidth);
glEnd();
//LEFT
glBegin(GL_QUADS);
glTexCoord2f(1.0f, 1.0f); glVertex3f(-halfwidth, 0, -halfwidth);
glTexCoord2f(1.0f, 0.0f); glVertex3f(-halfwidth, 0, halfwidth);
glTexCoord2f(0.0f, 0.0f); glVertex3f(-halfwidth, actorH, halfwidth);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-halfwidth, actorH, -halfwidth);
glEnd();
//RIGHT
glBegin(GL_QUADS);
glTexCoord2f(1.0f, 1.0f); glVertex3f(halfwidth, actorY, actorZ-halfwidth);
glTexCoord2f(1.0f, 0.0f); glVertex3f(halfwidth, actorY, actorZ+halfwidth);
glTexCoord2f(0.0f, 0.0f); glVertex3f(halfwidth, actorY+actorH, actorZ+halfwidth);
glTexCoord2f(0.0f, 1.0f); glVertex3f(halfwidth, actorY+actorH, actorZ-halfwidth);
glEnd();
//TOP
glBegin(GL_QUADS);
glTexCoord2f(1.0f, 1.0f); glVertex3f(-halfwidth, actorH, -halfwidth);
glTexCoord2f(1.0f, 0.0f); glVertex3f(halfwidth, actorH, -halfwidth);
glTexCoord2f(0.0f, 0.0f); glVertex3f(halfwidth, actorH, +halfwidth);
glTexCoord2f(0.0f, 1.0f); glVertex3f(-halfwidth, actorH, halfwidth);
glEnd();

return TRUE; // Initialization Went OK

}

Trienco
Trienco
quote:
Original post by mheikela
In practice this multiplication means that when processing vertices the rotation is applied first, and then any transformations that were in the model-view matrix before the call to glRotatef.


i really dont like this way of looking at it. it feels like a weird mental workaround so one can stick with his global coord system and ignore the existence of a local system. like imagining the sun rotating around earth so you dont have to accept that the earth isnt the center of the universe.

nothing is happening in reverse order, but its applied to your current local system as it is inside the model view matrix. rotating 90deg to the left and then translating along x will happen in exactly this order, just that the x axis has changed when you rotated and now happens to be the same as the global z (or -z in opengl).

i consider understanding the concept of a local coord system a lot easier when going through complex scene hierachies than that "everything will be backwards"-approach.

f@dzhttp://festini.device-zero.de
Geocyte
Geocyte
Yeah, I can''t think of it like that either, but I guess some peoples brains just work differently. I can''t be bothered to read this whole thread but every time I have come across a problem like this it is because the transformations are being done in the wrong order. GL applies transformations locally so if the very last thing you do before draw() is apply the rotation then the rotation will be be around the objects origin, not the world origin.


Geocyte Has Committed Suicide.
Geocyte Has Committed Suicide.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.