PDA

View Full Version : I want to draw two objects then just move one of them.



John Jenkins
10-04-2002, 08:02 AM
Let's say I want to draw two triangles. I draw them. Then I want to move just one of them around the screen while the other stays still. Also, I would like to rotate just one of them independently of the other. I know this has something to do with, excuse me for using DX terminology, world view and model view. Sorry I am still new to OpenGL and don't know the names of the functions or properties. Can anyone clarify this for me?

pleopard
10-04-2002, 08:32 AM
A simple pseudo-code example ...

struct MyScene
{
float x[2],y[2],z[2];
float rx[2],ry[2],rz[2];
float velocity[3];
float spinRate[3];
void init();
void timeUpdate(float t);
void render();
}

void MyScene::init()
{
memset(&(x[0]),0,2*sizeof(float));
memset(&(y[0]),0,2*sizeof(float));
memset(&(z[0]),0,2*sizeof(float));
memset(&(rx[0]),0,2*sizeof(float));
memset(&(ry[0]),0,2*sizeof(float));
memset(&(rz[0]),0,2*sizeof(float));
velocity[0] = 1;
velocity[1] = 3;
velocity[2] = -1;
spinRate[0] = spinRate[1] = spinRate[2] = 3;
}

void MyScene::timeUpdate(float t)
{
x[1] += velocity[0]*t;
y[1] += velocity[1]*t;
z[1] += velocity[2]*t;

rx[1] += spinRate[0]*t;
ry[1] += spinRate[1]*t;
rz[1] += spinRate[2]*t;
}

void MyScene::render()
{
glMatrixMode(GL_MODELVIEW);

glPushMatrix();
glRotatef(rx[0],1,0,0);
glRotatef(ry[0],0,1,0);
glRotatef(rz[0],0,0,1);
glTranslatef(x[0],y[0],z[0]);
DrawObject1();
glPopMatrix();

glPushMatrix();
glRotatef(rx[1],1,0,0);
glRotatef(ry[1],0,1,0);
glRotatef(rz[1],0,0,1);
glTranslatef(x[1],y[1],z[1]);
DrawObject2();
glPopMatrix();
}

Hope that helps ... dont have time to do more now ...

John Jenkins
10-04-2002, 08:34 AM
thanks so much for your help

nexusone
10-04-2002, 08:51 AM
Hum.. what DX terms did you use?
I think rotate, triangles are common to both.

But back to your question........

Just give each object a variable to hold is position and change only the one that is to move.

In the code would look something like this....

glPushMatrix(); // Store the current matrix, next changes to effect this object only.
glTranslatef(x,y,z)
glRotatef(angle_degrees, 0, 1, 0); // zero = no rotation on that axis, one = rotation of axis.

draw_object();
glPopMatrix(); // return matrix to past state.

Repeat above for each object.


Originally posted by John Jenkins:
Let's say I want to draw two triangles. I draw them. Then I want to move just one of them around the screen while the other stays still. Also, I would like to rotate just one of them independently of the other. I know this has something to do with, excuse me for using DX terminology, world view and model view. Sorry I am still new to OpenGL and don't know the names of the functions or properties. Can anyone clarify this for me?

John Jenkins
10-04-2002, 10:23 AM
In the NEHE example, he uses loadidentity inbetween drawing. He rotates a cube and a pyramid. What is the difference in using the load identity and push and pop matrix.

glClear clrColorBufferBit Or clrDepthBufferBit ' Clear The Screen And The Depth Buffer
glLoadIdentity ' Reset The View

glTranslatef -1.5, 0#, -6# ' Move Left 1.5 Units And Into The Screen 6.0
glRotatef rtri, 0#, 1#, 0# ' Rotate The pyramid On The Y axis ( NEW )


glBegin bmTriangles ' Start drawing the pyramid
glEnd ' Finished Drawing The pyramid

glLoadIdentity ' Reset The Current Modelview Matrix
glTranslatef 1.5, 0#, -7# ' Move Right 1.5 Units And Into The Screen 7.0
glRotatef rquad, 1#, 1#, 1# ' Rotate The Cube on X, Y and Z

glColor3f 0.5, 0.5, 1# ' Set The Color To Blue One Time Only
glBegin bmQuads ' Draw A Quad

glEnd

Anitox
10-04-2002, 11:00 AM
Let's try to clear this up a bit.

For each view you have a stack. Let's take the modelview stack for example. First you LoadIdentity() which will clear the top of the current stack. When you translate, rotate, or scale, it modifies the top of this stack.

When you call glPushMatrix(), it puts a clean, new layer on top of the current stack. You'll now be back as if you did LoadIdentity(), and you can move, rotate, etc.

Now, when you call glPopMatrix(), it takes the top of the current stack off, and reads the layer you were on before you called glPushMatrix().

ex:

void DrawTriangle() // draws a triangle
{
glBegin(GL_TRIANGLES);
glVertex3f(-1.0f, -1.0f, 0.0f);
glVertex3f( 1.0f, -1.0f, 0.0f);
glVertex3f( 0.0f, 1.0f, 0.0f);
glEnd();
}

...

void DrawScene()
{
glLoadIdentity();
glTranslatef(0.0f, 0.0f, -10.0f);

glPushMatrix(); // make a new layer
glTranslatef(-5.0f, 0.0f, 0.0f);
glColor3f(1.0f, 0.0f, 0.0f);
DrawTriangle();
glPopMatrix(); // remove the layer

glPushMatrix(); // make another layer
glTranslatef(5.0f, 0.0f, 0.0f);
glColor3f(0.0f, 1.0f, 0.0f);
DrawTriangle();
glPopMatrix(); // remove the layer
}

This will draw 2 triangles at different places. If you wanted one to move/animate, you could modify it's stack. Just make sure your translate, rotate, or scale function is inside the glPushMatrix() - glPopMatrix() area and it will only modify that triangle.

I hope this helps.

Danny
anitox@subdimension.com

nexusone
10-04-2002, 11:16 AM
Here is a sample answer...

loadidentity reset's the matrix to a set state. You use this before you start to draw to make sure your matrix is not been effected by past scene rendering matrix changes.

So when your start to draw a new scene, you loadidentity to the model matrix. Just like a painter, you want to start with a clean canvas, before you draw.

If you used this and not push/pop you would not get the correct results when trying to change camera views.

Push/Pop matrix, push saves the current matrix values to the matrix stack, pop restores them from the stack it.
If you know about how a stack works, the last pushed stack is pop by the next matrix command.

glRotate(......)// This effects all objects drawn after it, ever those inside of the push/pop.

glPushMatrix()// Save to stack
glRotate(......)
glTranslate(.....)
drawObject() // Draw object
glPopMatrix() // Load from stack, the Rotate/translate inside the push/pop has no effect outside the push/pop.



Originally posted by John Jenkins:
In the NEHE example, he uses loadidentity inbetween drawing. He rotates a cube and a pyramid. What is the difference in using the load identity and push and pop matrix.

glClear clrColorBufferBit Or clrDepthBufferBit ' Clear The Screen And The Depth Buffer
glLoadIdentity ' Reset The View

glTranslatef -1.5, 0#, -6# ' Move Left 1.5 Units And Into The Screen 6.0
glRotatef rtri, 0#, 1#, 0# ' Rotate The pyramid On The Y axis ( NEW )


glBegin bmTriangles ' Start drawing the pyramid
glEnd ' Finished Drawing The pyramid

glLoadIdentity ' Reset The Current Modelview Matrix
glTranslatef 1.5, 0#, -7# ' Move Right 1.5 Units And Into The Screen 7.0
glRotatef rquad, 1#, 1#, 1# ' Rotate The Cube on X, Y and Z

glColor3f 0.5, 0.5, 1# ' Set The Color To Blue One Time Only
glBegin bmQuads ' Draw A Quad

glEnd



[This message has been edited by nexusone (edited 10-04-2002).]

John Jenkins
10-04-2002, 11:16 AM
WOOO HOOO I think I understand. I have the red book but man it takes a long time for all that to sink.