CD3D8Driver::draw2DImage(video::ITexture* texture, const core::rect<s32>& destRect, const core::rect<s32>& sourceRect, const core::rect<s32>* clipRect, video::SColor* colors, bool useAlphaChannelOfTexture)
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)
I think that's been mentioned already some years ago, but I found no working solution for that so far. I fixed it for me and it seems to work, but no guarantees - I'm not so firm with DirectX. Maybe I find some time to provide a real patch one day (which is not so easy right now as I modified more stuff in that function), but for now just my solution, maybe someone wants to create a better patch out of it:
In Direct3D9 we can use the scissors, so instead of:
Code: Select all
pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST, 0, 4, 2, &indices[0],
D3DFMT_INDEX16, &vtx[0], sizeof(S3DVertex));
Code: Select all
// clip
RECT oldScissorRect;
DWORD oldScissorTestRenderState;
if ( clipRect )
{
pID3DDevice->GetScissorRect(&oldScissorRect);
pID3DDevice->GetRenderState(D3DRS_SCISSORTESTENABLE, &oldScissorTestRenderState);
pID3DDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE);
RECT scissor;
scissor.left = clipRect->UpperLeftCorner.X;
scissor.top = clipRect->UpperLeftCorner.Y;
scissor.right = clipRect->LowerRightCorner.X;
scissor.bottom = clipRect->LowerRightCorner.Y;
pID3DDevice->SetScissorRect(&scissor);
}
pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST, 0, 4, 2, &indices[0],
D3DFMT_INDEX16,&vtx[0], sizeof(S3DVertex));
if ( clipRect )
{
pID3DDevice->SetScissorRect(&oldScissorRect);
pID3DDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, oldScissorTestRenderState);
}
So instead of that old code:
Code: Select all
const core::dimension2d<s32>& ss = texture->getOriginalSize();
core::rect<f32> tcoords;
tcoords.UpperLeftCorner.X = (f32)sourceRect.UpperLeftCorner.X / (f32)ss.Width;
tcoords.UpperLeftCorner.Y = (f32)sourceRect.UpperLeftCorner.Y / (f32)ss.Height;
tcoords.LowerRightCorner.X = (f32)sourceRect.LowerRightCorner.X / (f32)ss.Width;
tcoords.LowerRightCorner.Y = (f32)sourceRect.LowerRightCorner.Y / (f32)ss.Height;
const core::dimension2d<s32>& renderTargetSize = getCurrentRenderTargetSize();
core::rect<f32> npos;
f32 xFact = 2.0f / ( renderTargetSize.Width );
f32 yFact = 2.0f / ( renderTargetSize.Height );
npos.UpperLeftCorner.X = ( destRect.UpperLeftCorner.X * xFact ) - 1.0f;
npos.UpperLeftCorner.Y = 1.0f - ( destRect.UpperLeftCorner.Y * yFact );
npos.LowerRightCorner.X = ( destRect.LowerRightCorner.X * xFact ) - 1.0f;
npos.LowerRightCorner.Y = 1.0f - ( destRect.LowerRightCorner.Y * yFact );
Code: Select all
const core::dimension2d<s32>& ss = texture->getOriginalSize();
core::rect<f32> tcoords;
tcoords.UpperLeftCorner.X = (f32)sourceRect.UpperLeftCorner.X / (f32)ss.Width;
tcoords.UpperLeftCorner.Y = (f32)sourceRect.UpperLeftCorner.Y / (f32)ss.Height;
tcoords.LowerRightCorner.X = (f32)sourceRect.LowerRightCorner.X / (f32)ss.Width;
tcoords.LowerRightCorner.Y = (f32)sourceRect.LowerRightCorner.Y / (f32)ss.Height;
// clip
core::rect<s32> clippedRect(destRect);
if ( clipRect )
{
clippedRect.clipAgainst(*clipRect);
// tcoords must be clipped by the same factors
core::rect<f32> tcoordsOrig(tcoords);
f32 fac = f32(clippedRect.UpperLeftCorner.X - destRect.UpperLeftCorner.X) / f32(destRect.getWidth());
tcoords.UpperLeftCorner.X += fac * (f32)tcoordsOrig.getWidth();
fac = f32(destRect.LowerRightCorner.X - clippedRect.LowerRightCorner.X) / f32(destRect.getWidth());
tcoords.LowerRightCorner.X -= fac * (f32)tcoordsOrig.getWidth();
fac = f32(clippedRect.UpperLeftCorner.Y - destRect.UpperLeftCorner.Y) / f32(destRect.getHeight());
tcoords.UpperLeftCorner.Y += fac * (f32)tcoordsOrig.getHeight();
fac = f32(destRect.LowerRightCorner.Y - clippedRect.LowerRightCorner.Y) / f32(destRect.getHeight());
tcoords.LowerRightCorner.Y -= fac * (f32)tcoordsOrig.getHeight();
}
const core::dimension2d<s32>& renderTargetSize = getCurrentRenderTargetSize();
core::rect<f32> npos;
f32 xFact = 2.0f / ( renderTargetSize.Width );
f32 yFact = 2.0f / ( renderTargetSize.Height );
npos.UpperLeftCorner.X = ( clippedRect.UpperLeftCorner.X * xFact ) - 1.0f;
npos.UpperLeftCorner.Y = 1.0f - ( clippedRect.UpperLeftCorner.Y * yFact );
npos.LowerRightCorner.X = ( clippedRect.LowerRightCorner.X * xFact ) - 1.0f;
npos.LowerRightCorner.Y = 1.0f - ( clippedRect.LowerRightCorner.Y * yFact );