Here is the d3d9 implementation.
Code: Select all
void CD3D9Driver::draw2DImage(const video::ITexture* texture,
const core::position2d<s32>& pos,
const core::rect<s32>& sourceRect,
const f32 rotation,
const bool filtering,
const core::vector2df scale,
SColor color,
bool useAlphaChannelOfTexture)
{
if (!texture)
return;
if (!sourceRect.isValid())
return;
if (!setActiveTexture(0, const_cast<video::ITexture*>(texture)))
return;
core::position2d<s32> targetPos = pos;
core::position2d<s32> sourcePos = sourceRect.UpperLeftCorner;
// This needs to be signed as it may go negative.
core::dimension2d<s32> sourceSize(sourceRect.getSize());
//FuzzYspo0N :: Needed for scaling the image.
core::vector2df vSourceSize = core::vector2df(f32(sourceSize.Width), f32(sourceSize.Height));
//FuzzYspo0N :: Start at the origin (thanks Josie)
core::rectf imageRect = core::rectf(0, 0, vSourceSize.X, vSourceSize.Y);
core::rectf scaleRect = imageRect;
core::vector2df destCenter = imageRect.getCenter() + core::vector2df(f32(targetPos.X), f32(targetPos.Y));
//FuzzYspo0N :: Points for rendering
core::vector2df topLeft = core::vector2df();
core::vector2df topRight = core::vector2df();
core::vector2df bottomLeft = core::vector2df();
core::vector2df bottomRight = core::vector2df();
//FuzzYspo0N :: Handle scaling of the verts
if(!scale.equals(core::vector2df(1.0f, 1.0f)))
{
//FuzzYspo0N :: Resize the rectangle
imageRect.LowerRightCorner.X *= scale.X;
imageRect.LowerRightCorner.Y *= scale.Y;
//FuzzYspo0N :: Update the translation
imageRect += core::vector2df(f32(destCenter.X - (imageRect.getWidth() / 2.0f)), f32(destCenter.Y - (imageRect.getHeight() / 2.0f)));
scaleRect.UpperLeftCorner = imageRect.UpperLeftCorner;
scaleRect.LowerRightCorner = imageRect.LowerRightCorner;
//FuzzYspo0N :: Adjust rendering coords
topLeft = scaleRect.UpperLeftCorner;
bottomRight = scaleRect.LowerRightCorner;
topRight = core::vector2df(scaleRect.LowerRightCorner.X, scaleRect.UpperLeftCorner.Y);
bottomLeft = core::vector2df(scaleRect.UpperLeftCorner.X, scaleRect.LowerRightCorner.Y);
}
else
{
scaleRect += core::vector2df(f32(targetPos.X), f32(targetPos.Y));
//FuzzYspo0N :: Adjust rendering coords
topLeft = scaleRect.UpperLeftCorner;
bottomRight = scaleRect.LowerRightCorner;
topRight = core::vector2df(scaleRect.LowerRightCorner.X, scaleRect.UpperLeftCorner.Y);
bottomLeft = core::vector2df(scaleRect.UpperLeftCorner.X, scaleRect.LowerRightCorner.Y);
}
//FuzzYspo0N :: Simple rotation of the verts.
f32 lRotation = rotation; // Local rotation
if(lRotation > 0.0f)
{
if(lRotation > 360.0f)
{
//Just cap it for logical reasons.
lRotation = fmodf(lRotation, 360.0f);
}
//Rotate the points seperately
topLeft.rotateBy(rotation, destCenter);
topRight.rotateBy(rotation, destCenter);
bottomLeft.rotateBy(rotation, destCenter);
bottomRight.rotateBy(rotation, destCenter);
}
//FuzzYspo0N :: Some clarity on the clipping. Dont draw when its off screen, when it was offscreen it was "shifted".
const core::dimension2d<u32>& renderTargetSize = getCurrentRenderTargetSize();
core::rectf renderSize = core::rectf(0.0f, 0.0f, f32(renderTargetSize.Width), f32(renderTargetSize.Height));
// clip these coordinates
if(!renderSize.isPointInside(topLeft) && !renderSize.isPointInside(topRight) && !renderSize.isPointInside(bottomLeft) && !renderSize.isPointInside(bottomRight))
{
//FuzzYspo0N :: Offscreen , dont bother rendering
return;
}
// ok, we've clipped everything.
// now draw it.
core::rect<f32> tcoords;
tcoords.UpperLeftCorner.X = (((f32)sourcePos.X)) / texture->getOriginalSize().Width ;
tcoords.UpperLeftCorner.Y = (((f32)sourcePos.Y)) / texture->getOriginalSize().Height;
tcoords.LowerRightCorner.X = tcoords.UpperLeftCorner.X + ((f32)(sourceSize.Width) / texture->getOriginalSize().Width);
tcoords.LowerRightCorner.Y = tcoords.UpperLeftCorner.Y + ((f32)(sourceSize.Height) / texture->getOriginalSize().Height);
const core::rect<s32> poss(targetPos, sourceSize);
setRenderStates2DMode(color.getAlpha()<255, true, useAlphaChannelOfTexture);
S3DVertex vtx[4];
vtx[0] = S3DVertex((f32)topLeft.X, (f32)topLeft.Y, 0.0f,
0.0f, 0.0f, 0.0f, color,
tcoords.UpperLeftCorner.X, tcoords.UpperLeftCorner.Y);
vtx[1] = S3DVertex((f32)topRight.X, (f32)topRight.Y, 0.0f,
0.0f, 0.0f, 0.0f, color,
tcoords.LowerRightCorner.X, tcoords.UpperLeftCorner.Y);
vtx[2] = S3DVertex((f32)bottomRight.X, (f32)bottomRight.Y, 0.0f,
0.0f, 0.0f, 0.0f, color,
tcoords.LowerRightCorner.X, tcoords.LowerRightCorner.Y);
vtx[3] = S3DVertex((f32)bottomLeft.X, (f32)bottomLeft.Y, 0.0f,
0.0f, 0.0f, 0.0f, color,
tcoords.UpperLeftCorner.X, tcoords.LowerRightCorner.Y);
s16 indices[6] = {0,1,2,0,2,3};
setVertexShader(EVT_STANDARD);
pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST, 0, 4, 2, &indices[0],
D3DFMT_INDEX16,&vtx[0], sizeof(S3DVertex));
}
The same declarations in the headers etc, so its just a copy paste mostly.