Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OpenGL rotating a 2D texture

UPDATE

See bottom for update.


I've been looking alot around the internet and I have found a few tutorials that explain what I'm trying to achieve but I can't get it to work, either the tutorial is incomplete or not applicable on my code.

I'm trying something as simple as rotating a 2D image around its origin (center).

I use xStart, xEnd, yStart and yEnd to flip the texture which are either 0 or 1.

This is what the code looks like

GameRectangle dest = destination;
Vector2 position = dest.getPosition();

glEnable(GL_TEXTURE_2D);

glBindTexture(GL_TEXTURE_2D, this->image);

//If the rotation isn't 0 we'll rotate it
if (rotation != 0)
{
    glMatrixMode(GL_TEXTURE);

    glLoadIdentity();
    glTranslatef(0.5, 0.5, 0);
    glRotatef(rotation, 0, 0, 1);

    glMatrixMode(GL_PROJECTION);
}

glBegin(GL_QUADS);
glTexCoord2d(xStart,yStart);
glVertex2f(position.x, position.y);

glTexCoord2d(xEnd,yStart);
glVertex2f(position.x + this->bounds.getWidth(), position.y);

glTexCoord2d(xEnd,yEnd); 
glVertex2f(position.x + this->bounds.getWidth(), position.y + this->bounds.getHeight());

glTexCoord2d(xStart,yEnd);
glVertex2f(position.x, position.y + this->bounds.getHeight());

glEnd();

glDisable(GL_TEXTURE_2D);

//Reset the rotation so next object won't be rotated
glMatrixMode(GL_TEXTURE);

glLoadIdentity();
glRotatef(0, 0, 0, 1);

glMatrixMode(GL_PROJECTION);

This code will draw the image in it's original size and it will rotate it, but it will rotate it from the top left corner which crops the image a lot. By calling GameRectangle.getOrigin() I can easily get the center of the rectangle, but I don't know where to use it.

Bit if put:

 glTranslatef(-0.5, -0.5, 0);

After I call the:

 glRotatef(0.5, 0.5, 0);

It will rotate from the center, but it will strech the image if it's not a perfect 90 degrees rotation.

UPDATE


After trying pretty much everything possible, I got the result I was looking for.

But I'm not sure if this is the best approach. Please tell me if there's something wrong with my code.

As I mentioned in a comment above, I use the same image multiple times and draw it with different values, so I can't save anything to the actual image. So I must reset the values everytime after I have rendered it.

I changed my code to this:

//Store the position temporary
GameRectangle dest = destination;
Vector2 position = dest.getPosition();

glEnable(GL_TEXTURE_2D);

glBindTexture(GL_TEXTURE_2D, this->image);

glTranslatef(dest.getOrigin().x, dest.getOrigin().y, 0);
glRotatef(rotation, 0, 0, 1);

glBegin(GL_QUADS);
glTexCoord2d(xStart,yStart);
glVertex2f(-dest.getWidth()/2, -dest.getHeight()/2);

glTexCoord2d(xEnd,yStart);
glVertex2f(dest.getWidth()/2, -dest.getHeight()/2);

glTexCoord2d(xEnd,yEnd); 
glVertex2f(dest.getWidth()/2, dest.getHeight()/2);

glTexCoord2d(xStart,yEnd);
glVertex2f(-dest.getWidth()/2, dest.getHeight()/2);

glEnd();

//Reset the rotation and translation
glRotatef(-rotation,0,0,1);
glTranslatef(-dest.getOrigin().x, -dest.getOrigin().y, 0);

glDisable(GL_TEXTURE_2D);

This rotates the texture together with the quad it's drawn in, it doesn't strech or crop. However the edges are a bit jagged if the image is filled square but I guess I can't avoid that with out antialiasing.

like image 940
Orujimaru Avatar asked Nov 13 '22 10:11

Orujimaru


1 Answers

What you want is this:

glPushMatrix(); //Save the current matrix.
//Change the current matrix.
glTranslatef(dest.getOrigin().x, dest.getOrigin().y, 0);
glRotatef(rotation, 0, 0, 1);

glBegin(GL_QUADS);
glTexCoord2d(xStart,yStart);
glVertex2f(-dest.getWidth()/2, -dest.getHeight()/2);

glTexCoord2d(xEnd,yStart);
glVertex2f(dest.getWidth()/2, -dest.getHeight()/2);

glTexCoord2d(xEnd,yEnd); 
glVertex2f(dest.getWidth()/2, dest.getHeight()/2);

glTexCoord2d(xStart,yEnd);
glVertex2f(-dest.getWidth()/2, dest.getHeight()/2);

glEnd();

//Reset the current matrix to the one that was saved.
glPopMatrix();
like image 147
Nicol Bolas Avatar answered Dec 10 '22 02:12

Nicol Bolas