OpenGL 旋转 2D 纹理
Posted
技术标签:
【中文标题】OpenGL 旋转 2D 纹理【英文标题】:OpenGL rotating a 2D texture 【发布时间】:2012-02-16 13:52:12 【问题描述】:更新
更新见底部。
我一直在互联网上寻找很多,我发现了一些教程来解释我想要实现的目标,但我无法让它工作,要么教程不完整,要么不适用于我的代码。
我正在尝试一些简单的方法,例如围绕其原点(中心)旋转 2D 图像。
我使用 xStart、xEnd、yStart 和 yEnd 来翻转 0 或 1 的纹理。
这就是代码的样子
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);
此代码将以原始大小绘制图像并旋转它,但它会从左上角旋转它,这会大量裁剪图像。通过调用 GameRectangle.getOrigin() 我可以很容易地得到矩形的中心,但是我不知道在哪里使用它。
如果放的话:
glTranslatef(-0.5, -0.5, 0);
在我打电话后:
glRotatef(0.5, 0.5, 0);
它会从中心旋转,但如果不是完美的 90 度旋转,它会拉伸图像。
更新
在尝试了几乎所有可能的方法之后,我得到了我想要的结果。
但我不确定这是否是最好的方法。如果我的代码有问题,请告诉我。
正如我在上面的评论中提到的,我多次使用同一个图像并使用不同的值绘制它,所以我无法将任何内容保存到实际图像中。所以每次渲染后我都必须重置这些值。
我将代码更改为:
//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);
这会将纹理与绘制的四边形一起旋转,它不会拉伸或裁剪。但是,如果图像填充为正方形,边缘会有点锯齿状,但我想如果没有抗锯齿,我无法避免这种情况。
【问题讨论】:
您真的要旋转纹理而不是四边形吗?在任何情况下,如果您已经在使用 OpenGL 矩阵,则应该使用矩阵堆栈,即 glPushMatrix 和 glPopMatrix,而不是在代码末尾重置矩阵。 如果只是旋转四边形就足够了,我想这就是想要的。这会用四边形旋转纹理吗?如何正确旋转四边形? 另外,我不确定在哪里调用 glPushMatrix() 和 glPopMatrix(),无论我把它们放在哪里,我都没有得到想要的结果,它要么旋转所有图像,要么不旋转图像。我不知道这是否有什么不同,但我多次绘制同一张图像,但旋转等值不同,所以我无法将任何内容保存到实际图像中。 一般来说,在你改变任何矩阵之前,你要做这样的事情:glMatrixMode(...); glPushMatrix();做东西(); glPopMatrix();您是否尝试过通过 glTexEnv 启用过滤,看看它是否有助于您的锯齿状边缘? 我的“引擎”看起来很像我调用 renderer.begin() 的 XNA 框架: glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushMatrix(); glOrtho(0, frameWidth, frameHeight, 0, -1, 1);然后是 renderer.end() : glPopMatrix(); SDL_GL_SwapBuffers();在这两者之间,我绘制了每个单独的对象。所以我使用 glPopMatrix 和 PushMatrix(),但并不像你建议的那样。抱歉,我对 glTexEnv 一无所知,但我确实尝试了 glEnable(GL_POLYGON_SMOOTH),它修复了锯齿状边缘,但随后通过我的四边形绘制了一条白色/透明对角线。 :S 【参考方案1】:你想要的是这个:
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();
【讨论】:
你有没有机会知道在 OpenGL ES 2.0 中这是如何完成的?以上是关于OpenGL 旋转 2D 纹理的主要内容,如果未能解决你的问题,请参考以下文章