PDA

View Full Version : basic rotation and textures question



Milk
09-01-2006, 08:10 AM
Hi all,

Ive created a flat square matrix and ive mapped a bitmap onto it. It views fine. However what I want to do is map the bitmap onto the back of the flat square so both sides of the square have the same bitmap on and both are facing the correct way. Here is the code i have so far


glRotatef(over,0,1,0);

glBegin(GL_POLYGON);
//Side1
glTexCoord2f(0.0,0.0);glVertex3f(0.9, 0.628,(cardNum*0.01));
glTexCoord2f(1.0,0.0);glVertex3f(1.12, 0.628,(cardNum*0.01));
glTexCoord2f(1.0,1.0);glVertex3f(1.12, 0.921,(cardNum*0.01));
glTexCoord2f(0.0,1.0);glVertex3f(0.9, 0.921,(cardNum*0.01));
glEnd();

glBegin(GL_POLYGON);
//Side2
glTexCoord2f(0.0,0.0);glVertex3f(0.9, 0.628,(cardNum*0.01));
glTexCoord2f(0.0,1.0);glVertex3f(0.9, 0.921,(cardNum*0.01));
glTexCoord2f(1.0,1.0);glVertex3f(1.12, 0.921,(cardNum*0.01));
glTexCoord2f(1.0,0.0);glVertex3f(1.12, 0.628,(cardNum*0.01));
glEnd();As you can see side1 has been drawn counterclockwise with the texture also being drawn counterclockwise and side2 has been drawn clockwise along with its texture.

This doesnt work because when the square is rotated (hence the glRotate command), the back image is facing the wrong way and even if i remove the "side2" polygon from the code and recompile still exactly the same happens (the image on the back is the wrong way round).

Howcome?

Second question? WIth the rotate command the image is rotated around the Y axis, which is correct. However it is rotated massively across the screen and i only want it to turn around itself, how can i change this?

Thanks :-)

EDIT:

Ive done some reading around and realised that the problem might be with my projection and my camera. Can anyone see if the following piece of code could be causing the problem, because no matter how big or small i make the y variable in glRotatef it always rotates the same width


void changeSize(int w, int h) {

// Prevent a divide by zero, when window is too short
// (you cant make a window of zero width).
if(h == 0)
h = 1;

float ratio = 1.0* w / h;

// Reset the coordinate system before modifying
glMatrixMode(GL_PROJECTION);
glLoadIdentity();

// Set the viewport to be the entire window
glViewport(0,0, w, h);

// Set the correct perspective.
gluPerspective(45,ratio,1,1000);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
//gluLookAt(0.5,0.5,1.2, 0.5,0.5,0.0, 0.0,1.0,0.0);
gluLookAt(0.5,0.5,3.2, 0.5,0.5,0.0, 0.0,1.0,0.0);
}or maybe here


void main (int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowPosition(100,100);
glutInitWindowSize(800,600);
glutCreateWindow("Example");
glutDisplayFunc(renderScene);
// glutIdleFunc(renderScene);
glutReshapeFunc(changeSize);
glutSpecialFunc(processSpecialKeys);

// enable depth testing
glEnable(GL_DEPTH_TEST);
glutMainLoop();
}Thanks

plasmonster
09-02-2006, 12:28 AM
There are basically 2 ways to rotate a texture image. One is to rotate the texture coordinates, the other is to rotate the vertex positions the texture coordinates are attached to.

To rotate texture coordinates, you can use the texture matrix, glMatrixMode(GL_TEXTURE), then apply any transformations you like, just as you would for the modelview matrix. This only works well for textures that can rotate freely without falling off the edge (think tiny sparks, smoke puffs, and other circular/symmetric stuff more or less confined the the center of the texture).

To rotate the geometry, use the modelview matrix, glMatrixMode(GL_MODELVIEW), rotating about the normal of the polygon, in the case of billboards.

Now to rotate some object about its center, just translate that object so that it's centered about the coordinate system origin, then rotate. For the texture matrix case, with texture coordinates in [0,1], this is just a glTranslatef(-0.5, -0.5, 0), for the 2D case, followed by your rotation about the z-axis, glRotatef(a, 0,0,1), followed by a translation back to its original origin, glTranslatef(+0.5, +0.5, 0).

You need to supply your transforms such that the first is closest to the vertex, which in effect reverses the order. So the center rotation matrix would look like

glTranslatef(+cx, +cy, +cz)
glRotatef(a, 0,0,1)
glTranslatef(-cx, -cy, -cz)
...
glVertex(...)

This is because the modelview is built from left to right, and the vertex is multiplied on the far right, so the last transform is applied first. You could also look at the transforms as being concatenated from right to left, but the vertex is instead multiplied on the left. Either way, last comes first in the OpenGL command sequence.

Hope this helps.

09-02-2006, 02:01 AM
Thanks for the reply.

However I wish for the player to be able to see the object spinning round 180 degrees about the y axis without the object being translated as that wouldnt look right on my game.

Is that not possible? Thanks :-)

plasmonster
09-02-2006, 05:55 AM
It's eminently doable, Milk :)

Let's say you have an object located at (300,400,500) in the world, and you'd like to rotate it by 180 degrees, in place, around the y-axis. The OpenGL command sequence for this is


glTranslatef(+300,+400,+500);
glRotatef(180, 0,1,0);
glTranslatef(-300,-400,-500);Intuitively, we first move the object so that its center coincides with the world-space origin; then we rotate the origin-centered object around the y-axis; then finally we move it back into world-space, where it was to begin with. These commands create matrices that combine to form a single matrix (modelview matrix) that's applied to your vertices, so you'll see no intervening translations, if that's what you mean.

Now, if you want to rotate slowly over time, you can accumulate a rotation angle, for example, scaling it by the current time delta. For instance, if you want to rotate by 180 degrees a second, you could do this:


angle += timeDelta * 180;
if (angle >= 360)
angle -= 360;where timeDelta is the difference, in seconds, between consecutive frames. Simply use this accumulated angle instead of the 180 above.

I'm sure there's a more complete example of this here, if you search. Another approach is to use a timer, but I've found that this simple accumulation works great for incremental rotations like this. You could create a Tick() function that's called once a frame to update things like this.

This transformation business can be difficult at first, so don't get blue if this doesn't make sense yet. It will.

I hope this helps.