It is an improvement of the draw2DImage-method, that allows also rotation. Since I only use OpenGL, I have only written it for the COpenGLDriver:
Code: Select all
//rotation is given in radians, clockwise.
void COpenGLDriver::draw2DImageRotation(video::ITexture* texture, const core::rect<s32>& destRect, const core::rect<s32>& sourceRect, const core::rect<s32>* clipRect, const f32 rotation, SColor color, bool useAlphaChannelOfTexture)
{
if (!texture)
return;
core::rect<s32> trgRect=destRect;
core::rect<s32> srcRect=sourceRect;
core::dimension2d<s32> currentRendertargetSize = getCurrentRenderTargetSize();
const core::dimension2d<s32> targetSurfaceSize=currentRendertargetSize;
const core::dimension2d<s32> ss = texture->getOriginalSize();
float ssw=1.0f/ss.Width;
float ssh=1.0f/ss.Height;
core::rect<f32> tcoords;
tcoords.UpperLeftCorner.X = (((f32)srcRect.UpperLeftCorner.X)+0.5f) * ssw ;
tcoords.UpperLeftCorner.Y = (((f32)srcRect.UpperLeftCorner.Y)+0.5f) * ssh;
tcoords.LowerRightCorner.X = (((f32)srcRect.UpperLeftCorner.X +0.5f + (f32)srcRect.getWidth())) * ssw;
tcoords.LowerRightCorner.Y = (((f32)srcRect.UpperLeftCorner.Y +0.5f + (f32)srcRect.getHeight())) * ssh;
s32 xPlus = -(currentRendertargetSize.Width>>1);
f32 xFact = 1.0f / (currentRendertargetSize.Width>>1);
s32 yPlus = currentRendertargetSize.Height-(currentRendertargetSize.Height>>1);
f32 yFact = 1.0f / (currentRendertargetSize.Height>>1);
//rotate the points
//center point
float cx = (trgRect.UpperLeftCorner.X + trgRect.LowerRightCorner.X) / 2;
float cy = (trgRect.UpperLeftCorner.Y + trgRect.LowerRightCorner.Y) / 2;
//rotate x axis
float cosr = cos(rotation);
float sinr = sin(rotation);
float x_x = cosr * (trgRect.LowerRightCorner.X - cx);
float x_y = sinr * (trgRect.LowerRightCorner.X - cx);
//rotate y axis
float y_x = sinr * (trgRect.LowerRightCorner.Y - cy);
float y_y = cosr * (trgRect.LowerRightCorner.Y - cy);
//points
float p1x = cx - x_x + y_x; float p1y = cy - x_y - y_y;
float p2x = cx + x_x + y_x; float p2y = cy + x_y - y_y;
float p3x = cx + x_x - y_x; float p3y = cy + x_y + y_y;
float p4x = cx - x_x - y_x; float p4y = cy - x_y + y_y;
//transform points
p1x = (p1x + xPlus + 0.5f) * xFact;
p1y = (yPlus - p1y + 0.5f) * yFact;
p2x = (p2x + xPlus + 0.5f) * xFact;
p2y = (yPlus - p2y + 0.5f) * yFact;
p3x = (p3x + xPlus + 0.5f) * xFact;
p3y = (yPlus - p3y + 0.5f) * yFact;
p4x = (p4x + xPlus + 0.5f) * xFact;
p4y = (yPlus - p4y + 0.5f) * yFact;
setTexture(0, texture);
if (useAlphaChannelOfTexture)
setRenderStates2DMode(false, true, true);
else
setRenderStates2DMode(false, true, false);
bool bTempColors=false;
glBegin(GL_QUADS);
glColor4ub(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha());
glTexCoord2f(tcoords.UpperLeftCorner.X, tcoords.UpperLeftCorner.Y);
glVertex2f(p1x, p1y);
glColor4ub(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha());
glTexCoord2f(tcoords.LowerRightCorner.X, tcoords.UpperLeftCorner.Y);
glVertex2f(p2x, p2y);
glColor4ub(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha());
glTexCoord2f(tcoords.LowerRightCorner.X, tcoords.LowerRightCorner.Y);
glVertex2f(p3x, p3y);
glColor4ub(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha());
glTexCoord2f(tcoords.UpperLeftCorner.X, tcoords.LowerRightCorner.Y);
glVertex2f(p4x, p4y);
glEnd();
}