0
\$\begingroup\$

Sorry, I searched it but couldn't figure how to apply it to my code reading the other answers to similar questions. I what to rotate a quad, my code is the following:

glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, player_texture);
glBegin(GL_QUADS);
    glColor4ub(255, 255, 255, 255);
    glTexCoord2d(0,0); glVertex2f(hero.xValue(), hero.yValue());
    glTexCoord2d(1,0); glVertex2f(hero.xValue()+hero.lValue(), hero.yValue());
    glTexCoord2d(1,1); glVertex2f(hero.xValue()+hero.lValue(), hero.yValue()+hero.hValue());
    glTexCoord2d(0,1); glVertex2f(hero.xValue(), hero.yValue()+hero.hValue());  
glEnd();
glDisable(GL_TEXTURE_2D);

I'm not sure about how to use the glTranslatef function, I tell it what is the center of my object?

In that case it would be: hero.xValue()+hero.lValue()/2 (x) and hero.yValue()+hero.hValue()/2 (y)

I know I have to use both glTranslatef and glRotate, by the way. When I try, setting glTranslatef with the values I mentioned above, I get a texture floating far from where the hero actually is.

Any help on this matter will be appreciated, thank you.

Obs: hValue = height, lValue = lenght

Edit: New information to show the changes I made after @user55564's comment:

I call init() once, on there I set basic openGL and SDL stuff, among them:

glViewport(0, 0, WIDTH, HEIGHT);
glMatrixMode(GL_MODELVIEW);

then I call my draw function, it has in it:

while (running) {
    glLoadIdentity();

.
. stuff non-related to drawing
.

glClear(GL_COLOR_BUFFER_BIT); 
    glClearColor(0, 0, 0, 0); 
    glPushMatrix(); 
    glOrtho(0, WIDTH, HEIGHT, 0, -1, 1);

    // draws the player     
    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, player_texture);
    glTranslatef(hero.xValue(), hero.yValue(), 0);
    glRotatef(0, 0, 0, 1);
    glTranslatef(-(hero.xValue()+hero.lValue()/2), -(hero.yValue()+hero.hValue()/2), 0);
    glBegin(GL_QUADS);
        glColor4ub(255, 255, 255, 255);
        glTexCoord2d(0,0); glVertex2f(hero.xValue(), hero.yValue());
        glTexCoord2d(1,0); glVertex2f(hero.xValue()+hero.lValue(), hero.yValue());
        glTexCoord2d(1,1); glVertex2f(hero.xValue()+hero.lValue(), hero.yValue()+hero.hValue());
        glTexCoord2d(0,1); glVertex2f(hero.xValue(), hero.yValue()+hero.hValue());  
    glEnd();
    glDisable(GL_TEXTURE_2D);
    glPopMatrix();

// then I use pushmatrix again to draw the enemies and the health bars of both enemies and player (these don't need rotation);
glPushMatrix();
    glOrtho(0, WIDTH, HEIGHT, 0, -1, 1);
.
.
.
\$\endgroup\$
  • \$\begingroup\$ You're using ultra-old and deprecated opengl-functions. If you learned this in a tutorial, look for a newer better tutorial. Btw: You rotate with glRotate. glTranslate is to move it. \$\endgroup\$ – tkausl Dec 10 '14 at 16:54
  • \$\begingroup\$ I know that, I just found they to be super simple to use and decided to use them on this first simple project which is almost finished by now. All I have to do is call glRotate with the desired angle of rotation? \$\endgroup\$ – Thums Dec 10 '14 at 16:57
  • \$\begingroup\$ Yes, your angle as first parameter and for a 2D game the last three parameters should be 0, 0 and 1. \$\endgroup\$ – tkausl Dec 10 '14 at 16:59
  • \$\begingroup\$ No texture is shown for the hero when I call glRotatef(90, 0, 0, 1); before glBegin() and glRotatef(-90, 0, 0, 1); after glEnd() \$\endgroup\$ – Thums Dec 10 '14 at 17:03
  • \$\begingroup\$ Then there is something wrong with your matrix. Are you loading the identitymatrix everytime before rendering? \$\endgroup\$ – tkausl Dec 10 '14 at 17:07
2
\$\begingroup\$

What you need to do to draw a quad with x,y as its top left coords, r as rotation, and cx and cy as the center of rotation (relative to its x,y coord) :

- translate(x,y)
- rotate(r)
- translate(cx, cy);
- draw.
- (reverse/pop the matrix if required. etc)

For your case, try this:

...
glTranslatef(hero.xValue(), hero.yValue(), 0);
glRotatef(0, 0, 0, 1);
glTranslatef(+hero.lValue()/2, +hero.hValue()/2);
glBegin(GL_QUADS);
    glColor4ub(255, 255, 255, 255);
    glTexCoord2d(0,0); glVertex2f(-hero.lValue()/2, -hero.hValue()/2);
    // do the same for other 3 corners.

glEnd();

After the transformations, your (0,0) coord is at where the object's center is. Suppose if object is at (50,50). In your function after the transformation the (0,0) is at (50,50) So if you draw at (50,50) again then in reality you are drawing your object at (100,100).

See http://creativejs.com/2012/01/day-10-drawing-rotated-images-into-canvas/ for more detailed explanation.

\$\endgroup\$
  • \$\begingroup\$ Thank you! It's almost there, but it doesn't actually do a rotation around its center, it is a bit off after the rotation. Off to the left and up, it seems, no more than half of one side of the hero (square, 50x50); \$\endgroup\$ – Thums Dec 10 '14 at 18:33
  • \$\begingroup\$ Try it with translate(-cx, -cy) taken out; if that doesnt work try it with translate(+cx, +cy); \$\endgroup\$ – user55564 Dec 10 '14 at 18:43
  • \$\begingroup\$ Doesnt work either, the hero gets rendereng far away from his spot texture), off screen actually, but I can manage to move him in. \$\endgroup\$ – Thums Dec 10 '14 at 18:49
  • \$\begingroup\$ Did you reset the transformations properly before drawing? Like with glIdentity before translate(x,y). If that doesnt work you have to post your drawing function. \$\endgroup\$ – user55564 Dec 10 '14 at 18:55
  • \$\begingroup\$ Here is a image of what is happening: prntscr.com/5fcecz The red bar is the player's health, since it is full it represents the same lenght as the player and should be right above it. I have glLoadIdentity(); on the begining of each frame. I am using glClear(GL_COLOR_BUFFER_BIT); glPushMatrix(); and glOrtho(0, WIDTH, HEIGHT, 0, -1, 1); before drawing. \$\endgroup\$ – Thums Dec 10 '14 at 19:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.