PDA

View Full Version : problem moving objects using glTranslatef()



cassandra
03-09-2010, 01:04 AM
i'm doing a very simple 2D battleship game. I want to make the ship moves forward so i use glTranslatef(10,0,0) and the enemies move towards the battleship using glTranslatef(-20,0,0). However, the battleship and enemies move together to the left. I tried many ways to move each of them separately but still cannot do it.... Can someone please help me?

my code:
void drawBattleShip()
{
glColor3f(1.0, 1.0, 1.0);
glBegin(GL_POLYGON);
glVertex2i((75+X), (248+Y));
glVertex2i((85+X), (225+Y));
glVertex2i((115+X), (225+Y));
glVertex2i((125+X), (248+Y));
glEnd();

glBegin(GL_POLYGON);
glColor3f(1.0f, 0.0f, 0.0f);
for(float angle1=0; angle1<PI; angle1+=STEP)
glVertex2f((100.0+X) + 55.0 * cos(angle1), (275+Y) + 35.0 * sin(angle1));
glEnd();

glBegin(GL_POLYGON);
glColor3f(1.0f, 1.0f, 1.0f);
for(float angle2=0; angle2<PI; angle2+=STEP)
glVertex2f((100.0+X) + 55.0 * cos(angle2), (275+Y) + 15.0 * sin(angle2));
glEnd();

glBegin(GL_POLYGON);
glColor3f(1.0f, 0.0f, 0.0f);
for(float angle3=0; angle3<PI; angle3+=STEP)
glVertex2f((48.0+X) + 15.0 * cos(angle3), (275+Y) + 5.0 * sin(angle3));
glEnd();
}

void drawEnemies()
{
glColor3f(r1, g1, b1);
glBegin(GL_POLYGON);
glVertex2i(720, 520);
glVertex2i(720, 560);
glVertex2i(760, 560);
glVertex2i(760, 520);
glEnd();

glColor3f(r2, g2, b2);
glBegin(GL_POLYGON);
glVertex2i(800, 420);
glVertex2i(800, 460);
glVertex2i(840, 460);
glVertex2i(840, 420);
glEnd();
}

void drawScene()
{
glClear(GL_COLOR_BUFFER_BIT);
// glLoadIdentity();

glPushMatrix();
glTranslatef(10.0, 0.0, 0.0);
drawBattleShip();
glPopMatrix();

glPushMatrix();
glTranslatef(-10.0, 0.0, 0.0);
drawEnemies();
glPopMatrix();

glFlush();
}

void init(void)
{
glClearColor (0.0, 0.0, 0.0, 0.0);
glMatrixMode (GL_PROJECTION);
glLoadIdentity();
glOrtho (0.0, 900.0, 0.0, 700.0, 0.0, 1.0);
}

Y-tension
03-09-2010, 04:55 AM
Do you reset matrix mode to modelview after init?

cassandra
03-09-2010, 06:40 PM
yes. i just did it last night but still can't work.

latest init code:
void init(void)
{
glClearColor(0.0, 0.0, 0.0, 0.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho (0.0, 900.0, 0.0, 700.0, 0.0, 1.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}

Ehsan Kamrani
03-09-2010, 07:47 PM
There's nothing wrong with the matrices.
Are you sure that both of them move to the left?
You can remove the glTranslate() functions and look at the original( local space )positions of battleship and enemies. Then add those glTranslate() functions again and see the new positions of battleship and enemies to see if both of them really move to the left?
BTW, Have you specified the viewport in your code using glViewport()?

cassandra
03-10-2010, 05:26 AM
Honestly, i'm not familiar with Viewport as i always mess it up and unable to display it on the window so i deleted it from my code. Is it necessary to put in Viewport? Will it affect my program badly?

Sorry, i also forgot to mention that i want the battleship and enemies to move with their own distance (which are battleship moves forwards/ to the right with 10.0 each time and enemies moves backwards/ to the left with 10.0 each time). However, 1 glTranslate moves all of them...

Ehsan Kamrani
03-10-2010, 10:21 AM
glViewport() specifies that the objects should be drawn to which part of the window. So if you want to draw to the whole window you must use the following function:
glViewport( 0,0, gl_window_width, gl_window_height);
if you want to draw to the lower left part of your GL window, then you can use the following function:
glViewport( 0, 0, gl_window_width / 2, gl_window_height / 2 );
and if you want to draw to the lower right part of your GL window, then you can use the following function:
glViewport( gl_window_width / 2, 0, gl_window_width / 2, gl_window_height / 2 );
for example, when you use the above code to draw to the lower part of your OpenGL window, the OpenGL assumes that it's a window with width and heights of (width / 2, height /2 ) and its origin is at width / 2 and 0 relative to to the origin of the actual window which is (0,0). So you get smaller objects when you use smaller viewports.( softwares such as 3DSMax and Maya use four independent viewports to draw the objects ).
You can simply put the following function in your reshape function if you want to draw to the whole window ( I guess you usually want to use this code ):
reshape (int w, int h)
{
glViewport( 0, 0, w, h );
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
//your desired projection matrix such as glOrtho(), gluPerspective(),etc.
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
}

If you want to move the objects like the games, then you need to use a variable and incerement/decrement it in each frame. For example:


void DrawGLScene()
{
static float a = 0.f;
//Setup the view matrix here if available
a += 10.f;

glPushMatrix();
glTranslatef(a, 0.0, 0.0);
drawBattleShip();
glPopMatrix();

glPushMatrix();
glTranslatef(-a, 0.0, 0.0);
drawEnemies();
glPopMatrix();
}

But this code is dependent to the speed of your machine. you need to use timers instead of fixed values if you want to see the same result in other machines.

cassandra
03-10-2010, 07:39 PM
Thank you very much, Ehsan!!!
I understand what is viewport after looking at your explanation and move my battleship and enemies!

Can i ask one more question?
I want to move my battleship manually by using the up, down, left & right keys but it seems like the battleship move away from the window without boundaries. I set the condition where it supposed to stop when it hit the wall of the window no matter the user keeps on pressing the keys.

I use if loop because switch doesn't give me smooth movement. Should i stick to if or switch?

code for controlling the keys:
void BattleshipControl(int button, int x, int y)
{
int x1=0, y1=0;

if(button == GLUT_KEY_LEFT)
{
if(50+x1 >= 10)
{
X += -10;
x1 += X;
}
else
X=0;
}

if(button == GLUT_KEY_RIGHT)
{
if(100+x1 <= 850)
{
X += 10;
x1=X;
}
else
X=0;
}

if(button == GLUT_KEY_UP)
{
if(275+y1 <= 665)
{
Y += 10;
y1=Y;
}
else
Y=0;
}

if(button == GLUT_KEY_DOWN)
{
if(230+y1 >= 230)
{
Y += -10;
y1=Y;
}
else
Y=0;
}

glutPostRedisplay();
}

Ehsan Kamrani
03-11-2010, 03:16 AM
actually your last reply doesn't refer to the OpenGL programming.It's a question about C++.
Note that "if/else" and "switch" are the same if you use them correctly.
You just need to think more and write a code which works.

cassandra
03-11-2010, 04:06 AM
Ok... Thanks... I'll try again and thanks for your help..