(see "// changed!!!" in the code)
Code: Select all
//! draws an 2d image, using a color (if color is other then Color(255,255,255,255)) and the alpha channel of the texture if wanted.
void CD3D9Driver::draw2DImage(video::ITexture* texture, const core::position2d<s32>& pos,
const core::rect<s32>& sourceRect,
const core::rect<s32>* clipRect, SColor color,
bool useAlphaChannelOfTexture)
{
if (!texture)
return;
if (texture)
{
if (texture->getDriverType() != EDT_DIRECTX9)
{
os::Printer::log("Fatal Error: Tried to copy from a surface not owned by this driver.", ELL_ERROR);
return;
}
}
if (sourceRect.UpperLeftCorner.X >= sourceRect.LowerRightCorner.X ||
sourceRect.UpperLeftCorner.Y >= sourceRect.LowerRightCorner.Y)
return;
core::position2d<s32> targetPos = pos;
core::position2d<s32> sourcePos = sourceRect.UpperLeftCorner;
core::dimension2d<s32> sourceSize(sourceRect.getWidth(), sourceRect.getHeight());
const core::dimension2d<s32> targetSurfaceSize = ScreenSize;
if (clipRect)
{
if (targetPos.X < clipRect->UpperLeftCorner.X)
{
sourceSize.Width += targetPos.X - clipRect->UpperLeftCorner.X;
if (sourceSize.Width <= 0)
return;
sourcePos.X -= targetPos.X - clipRect->UpperLeftCorner.X;
targetPos.X = clipRect->UpperLeftCorner.X;
}
if (targetPos.X + sourceSize.Width > clipRect->LowerRightCorner.X)
{
sourceSize.Width -= (targetPos.X + sourceSize.Width) - clipRect->LowerRightCorner.X;
if (sourceSize.Width <= 0)
return;
}
if (targetPos.Y < clipRect->UpperLeftCorner.Y)
{
sourceSize.Height += targetPos.Y - clipRect->UpperLeftCorner.Y;
if (sourceSize.Height <= 0)
return;
sourcePos.Y -= targetPos.Y - clipRect->UpperLeftCorner.Y;
targetPos.Y = clipRect->UpperLeftCorner.Y;
}
if (targetPos.Y + sourceSize.Height > clipRect->LowerRightCorner.Y)
{
sourceSize.Height -= (targetPos.Y + sourceSize.Height) - clipRect->LowerRightCorner.Y;
if (sourceSize.Height <= 0)
return;
}
}
// clip these coordinates
if (targetPos.X<0)
{
sourceSize.Width += targetPos.X;
if (sourceSize.Width <= 0)
return;
sourcePos.X -= targetPos.X;
targetPos.X = 0;
}
if (targetPos.X + sourceSize.Width > targetSurfaceSize.Width)
{
sourceSize.Width -= (targetPos.X + sourceSize.Width) - targetSurfaceSize.Width;
if (sourceSize.Width <= 0)
return;
}
if (targetPos.Y<0)
{
sourceSize.Height += targetPos.Y;
if (sourceSize.Height <= 0)
return;
sourcePos.Y -= targetPos.Y;
targetPos.Y = 0;
}
if (targetPos.Y + sourceSize.Height > targetSurfaceSize.Height)
{
sourceSize.Height -= (targetPos.Y + sourceSize.Height) - targetSurfaceSize.Height;
if (sourceSize.Height <= 0)
return;
}
// ok, we've clipped everything.
// now draw it.
// changed !!!
if (useAlphaChannelOfTexture)
{
setRenderStates2DMode(false, true, true);
} else
{
if (color == SColor(255,255,255,255))
setRenderStates2DMode(false, true, false);
else
setRenderStates2DMode(true, true, false);
}
setTexture(0, texture);
core::rect<s32> poss(targetPos, sourceSize);
s32 xPlus = -(ScreenSize.Width>>1);
f32 xFact = 1.0f / (ScreenSize.Width>>1);
s32 yPlus = ScreenSize.Height-(ScreenSize.Height>>1);
f32 yFact = 1.0f / (ScreenSize.Height>>1);
const core::dimension2d<s32> sourceSurfaceSize = texture->getOriginalSize();
core::rect<f32> tcoords;
tcoords.UpperLeftCorner.X = (((f32)sourcePos.X)+0.5f) / texture->getOriginalSize().Width ;
tcoords.UpperLeftCorner.Y = (((f32)sourcePos.Y)+0.5f) / texture->getOriginalSize().Height;
tcoords.LowerRightCorner.X = (((f32)sourcePos.X +0.5f + (f32)sourceSize.Width)) / texture->getOriginalSize().Width;
tcoords.LowerRightCorner.Y = (((f32)sourcePos.Y +0.5f + (f32)sourceSize.Height)) / texture->getOriginalSize().Height;
S3DVertex vtx[4];
vtx[0] = S3DVertex((f32)(poss.UpperLeftCorner.X+xPlus) * xFact, (f32)(yPlus-poss.UpperLeftCorner.Y ) * yFact , 0.0f, 0.0f, 0.0f, 0.0f, color, tcoords.UpperLeftCorner.X, tcoords.UpperLeftCorner.Y);
vtx[1] = S3DVertex((f32)(poss.LowerRightCorner.X+xPlus) * xFact, (f32)(yPlus- poss.UpperLeftCorner.Y) * yFact, 0.0f, 0.0f, 0.0f, 0.0f, color, tcoords.LowerRightCorner.X, tcoords.UpperLeftCorner.Y);
vtx[2] = S3DVertex((f32)(poss.LowerRightCorner.X+xPlus) * xFact, (f32)(yPlus-poss.LowerRightCorner.Y) * yFact, 0.0f, 0.0f, 0.0f, 0.0f, color, tcoords.LowerRightCorner.X, tcoords.LowerRightCorner.Y);
vtx[3] = S3DVertex((f32)(poss.UpperLeftCorner.X+xPlus) * xFact, (f32)(yPlus-poss.LowerRightCorner.Y) * yFact, 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));
}
//! draw an 2d rectangle
void CD3D9Driver::draw2DRectangle(SColor color, const core::rect<s32>& position,
const core::rect<s32>* clip)
{
core::rect<s32> pos = position;
if (clip)
pos.clipAgainst(*clip);
if (!pos.isValid())
return;
s32 xPlus = -(ScreenSize.Width>>1);
f32 xFact = 1.0f / (ScreenSize.Width>>1);
s32 yPlus = ScreenSize.Height-(ScreenSize.Height>>1);
f32 yFact = 1.0f / (ScreenSize.Height>>1);
S3DVertex vtx[4];
vtx[0] = S3DVertex((f32)(pos.UpperLeftCorner.X+xPlus) * xFact, (f32)(yPlus-pos.UpperLeftCorner.Y) * yFact , 0.0f, 0.0f, 0.0f, 0.0f, color, 0.0f, 0.0f);
vtx[1] = S3DVertex((f32)(pos.LowerRightCorner.X+xPlus) * xFact, (f32)(yPlus- pos.UpperLeftCorner.Y) * yFact, 0.0f, 0.0f, 0.0f, 0.0f, color, 0.0f, 1.0f);
vtx[2] = S3DVertex((f32)(pos.LowerRightCorner.X+xPlus) * xFact, (f32)(yPlus-pos.LowerRightCorner.Y) * yFact, 0.0f, 0.0f, 0.0f, 0.0f, color, 1.0f, 0.0f);
vtx[3] = S3DVertex((f32)(pos.UpperLeftCorner.X+xPlus) * xFact, (f32)(yPlus-pos.LowerRightCorner.Y) * yFact, 0.0f, 0.0f, 0.0f, 0.0f, color, 1.0f, 1.0f);
s16 indices[6] = {0,1,2,0,2,3};
setRenderStates2DMode(color.getAlpha() < 255, false, false);
setTexture(0,0);
setVertexShader(EVT_STANDARD);
pID3DDevice->DrawIndexedPrimitiveUP( D3DPT_TRIANGLELIST, 0, 4, 2, &indices[0],
D3DFMT_INDEX16, &vtx[0], sizeof(S3DVertex));
}
Code: Select all
void CD3D9Driver::draw2DImage(video::ITexture* texture, const core::rect<s32>& destRect,
const core::rect<s32>& sourceRect, const core::rect<s32>* clipRect,
video::SColor* colors, bool useAlphaChannelOfTexture)
{
if(!texture) return;
// changed!!!
if (useAlphaChannelOfTexture)
{
setRenderStates2DMode(false, true, true);
} else
{
if (!colors)
setRenderStates2DMode(false, true, false);
else
setRenderStates2DMode(true, true, false);
}
setTexture(0, texture);
core::rect<s32> trgRect=destRect;
core::rect<s32> srcRect=sourceRect;
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 = -(ScreenSize.Width>>1);
f32 xFact = 1.0f / (ScreenSize.Width>>1);
s32 yPlus = ScreenSize.Height-(ScreenSize.Height>>1);
f32 yFact = 1.0f / (ScreenSize.Height>>1);
core::rect<float> npos;
npos.UpperLeftCorner.X = (f32)(trgRect.UpperLeftCorner.X+xPlus+0.5f) * xFact;
npos.UpperLeftCorner.Y = (f32)(yPlus-trgRect.UpperLeftCorner.Y+0.5f) * yFact;
npos.LowerRightCorner.X = (f32)(trgRect.LowerRightCorner.X+xPlus+0.5f) * xFact;
npos.LowerRightCorner.Y = (f32)(yPlus-trgRect.LowerRightCorner.Y+0.5f) * yFact;
// changed !!!
SColor TempColors[4];
if(colors==NULL)
{
for(int i=0;i<4;i++) TempColors[i]=SColor(255,255,255,255);
colors = &TempColors[0];
}
S3DVertex vtx[4]; // clock wise
vtx[0] = S3DVertex(npos.UpperLeftCorner.X, npos.UpperLeftCorner.Y , 0.0f, 0.0f, 0.0f, 0.0f, colors[0], tcoords.UpperLeftCorner.X, tcoords.UpperLeftCorner.Y);
vtx[1] = S3DVertex(npos.LowerRightCorner.X, npos.UpperLeftCorner.Y , 0.0f, 0.0f, 0.0f, 0.0f, colors[3], tcoords.LowerRightCorner.X, tcoords.UpperLeftCorner.Y);
vtx[2] = S3DVertex(npos.LowerRightCorner.X, npos.LowerRightCorner.Y, 0.0f, 0.0f, 0.0f, 0.0f, colors[2], tcoords.LowerRightCorner.X, tcoords.LowerRightCorner.Y);
vtx[3] = S3DVertex(npos.UpperLeftCorner.X, npos.LowerRightCorner.Y, 0.0f, 0.0f, 0.0f, 0.0f, colors[1], 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));
}
I also got rid of the new/delete TempColors and declared it as "automatic" which should be better performance-wise.