Archived

This topic is now archived and is closed to further replies.

Newby Q about rotating and transforming

This topic is 5667 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Alright, I'm doing some experimenting with a small piece of code. I'm using GLUT so I don't have to mess with windows stuff yet. I'm trying to move a triangle arond the screen with the arrow keys. I use the up and down arrows to translate, and the left and right arrows to rotate. The problem is that if I translate then rotate my triangle rotates around the origin, instead of the center of the triangle. If I rotate then translate it rotates fine but the triangle only goes up and down the screen. I tried doing several things including have it translate, render, rotate, render, but that made TWO flickering triangles. I want to keep it simple. Can it be done with out doing some complicated matrix stuff? [edited by - rictus on June 4, 2002 8:16:11 PM]

Share this post


Link to post
Share on other sites
quote:
If I rotate then translate it rotates fine but the triangle only goes up and down the screen

Could you explain this a bit more? Above you said you use the up/down keys for translating, what direction are they translating?
Rotate then translate should work fine.
(could you maybe post the drawing code?)

------------
aud.vze.com - The Audacious Engine <-- Newbie alert, look at your own risk. Can induce severe laughing fits and other variations of hysterical outburst.

Share this post


Link to post
Share on other sites
Oh, sorry. I'll see if I can get this to work.

void render(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glTranslatef(0.0, m, -3.0);
glRotatef(r, 0.0, 0.0, 1.0);
glBegin(GL_TRIANGLES);
glColor3f(0.68, 0.32, 0.21);
glVertex3f(0.0, 0.1, 0.0);
glColor3f(0.12, 0.21, 0.22);
glVertex3f(-0.1, -0.1, 0.0);
glColor3f(0.12, 0.21, 0.22);
glVertex3f(0.1, -0.1, 0.0);
glEnd();
// Swap The Buffers To Become Our Rendering Visible
glutSwapBuffers ( );
}

stuff....

void keyboard(unsigned char key, int x, int y)
{
if (key == 27)
exit (0);
}

void special_keys(int a_keys, int x, int y)
{
switch (a_keys){
case GLUT_KEY_UP:
m += 0.1;
glutPostRedisplay();
break;
case GLUT_KEY_DOWN:
m -= 0.1;
glutPostRedisplay();
break;
case GLUT_KEY_LEFT:
r += 5;
glutPostRedisplay();
break;
case GLUT_KEY_RIGHT:
r -= 5;
glutPostRedisplay();
break;
default:
break;
}
}

This is not all my code I'm modifying it so I can learn how things work. Maybe I need to make the up and down keys do more than just translate on the y axis.
Nice start on the engine!

[edited by - rictus on June 4, 2002 8:59:35 PM]

Share this post


Link to post
Share on other sites
Yes, that''s right. The reason it only goes up and down is because you only tell it to go up and down
Try using w,s,a,d for translating up/down/left/right and have the arrow keys rotate.

------------
aud.vze.com - The Audacious Engine <-- Newbie alert, look at your own risk. Can induce severe laughing fits and other variations of hysterical outburst.

Share this post


Link to post
Share on other sites
I have the "r" int the rotation function as the angle of roatation. glRotatef(r, 0.0, 0.0, 1.0). I need a way so that when it rotates, the axis of the triangle rotates too. Kinda like an asteroids game. Then tranlate would always make it go forward. I think I''m trying to do too much with too little knowledge he he.

Share this post


Link to post
Share on other sites
Hi Rictus

quote:
Original post by Rictus
case GLUT_KEY_UP:
m += 0.1;
glutPostRedisplay();
break;



When the player presses the ''up'' key, you want the triangle (spaceship?) to move not only up, but forward in the direction that the triangle is actually facing - like in asteroid, as you said.

This means that you have to take the angle of rotation into consideration when you tell the triangle to move. For example, if the ship/triangle was facing with the front straight towards the top of the screen, you would like it to move Y units along the y-axis and 0 units along the x-axis. But if the triangle/ship was facing straight towards the left edge of the screen, the ship should move 0 units along the y-axis and X units along the x-axis instead. Similarily, if the ship was facing towards a corner on the screen, it should move both along the y-axis and along the a-axis (making it seem as if it moved diagonally across the screen).

To find out how much along each axis you should move, you should use the cos() and sin() functions on the angle of rotation of your triangle/ship, like this:


  
case GLUT_KEY_UP:
xpos += cos(r);
ypos += sin(r);
glutPostRedisplay();
break;


When you render your ship/triangle you can use either of the following methods:

a) Setup a Translation/Rotation matrix yourself and use glLoadMatrix(). The formula for setting up a matrix for rotation around the z-axis you can find in the article about matrixes currently featured on the front page of GameDev (it''s called ''Matrix Primer'' or something along those lines). It would look something like this:


  
/* Clear Screen And Depth Buffer... */
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

/* Transpose & Rotate around z-axis Using MATRIXES... */
GLfloat matrix[16] = {
cosl(r), sinl(r),0.0 , 0.0,
-sinl(r), cosl(r),0.0 , 0.0,
0.0 , 0.0 ,1.0 , 0.0,
xpos , ypos , zpos , 1.0};

glLoadMatrixf(matrix);

/* Render Triangle... */

.....


The formula for the matrix gets a lot more complicated if you wish to rotate around multiple more than one axis at the same time. Still, I think its a fairly simple method of doing things. And you need not worry about wether to rotate or translate first. You simply do both in one operation.

I don''t really know about how it is performance-wise. I would guess you saves some of the matrix multiplications performed by the glTranslate/glRotate functions "behind the scenes". But then you have to compute several cos()''s and sin()''s instead.

b) The second method of rendering the triangle is using glTranslatef() and glRotatef(). There are two things to remember: The order of the operations and the fact that glRotatef() uses Degrees while cos() and sin() uses Radians for the angle of rotation. You need to convert in between the two. The code would look something like this:


  
/* Clear Screen And Depth Buffer... */
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

/* Transpose & Rotate around z-axis... */
glLoadIdentity();
glTranslatef(xpos,ypos,zpos);
glRotatef((rotation/(M_PI))*180,0.0,0.0,1.0);

/* Render Triangle... */



A final thing to note is that if you are indeed making a asteroid-type game, you should look into some simple physics (Newton''s laws). Instead of just adding to the position when the player presses the ''up'' button, you should instead add to the velocity or even the acceleration of the ship. And then in each frame you should use the velocity and acceleration to compute the new postion of the ship. That way, you get a more realistic movement of the spaceship. For example it will no longer just stop as soon as you release the ''up'' button.

OK. I hope that helped. Hope that I''ve explained everything correctly and that there''s not (too many) errors in my code .

Regards

Nicolai

Share this post


Link to post
Share on other sites