diff -abBdpuNPr --exclude='*.svn' irrlicht-svn-ss/trunk/include/IVideoDriver.h Irrlicht_starsonata/include/IVideoDriver.h --- irrlicht-svn-ss/trunk/include/IVideoDriver.h 2007-07-26 02:11:22.000000000 +0200 +++ Irrlicht_starsonata/include/IVideoDriver.h 2008-08-04 00:01:04.000000000 +0200 @@ -424,10 +424,14 @@ namespace video Color(255,255,255,255), the color is ignored. Note that the alpha component is used: If alpha is other than 255, the image will be transparent. \param useAlphaChannelOfTexture: If true, the alpha channel of the texture is - used to draw the image.*/ + used to draw the image. + \param angleInDegree: rotation angle + \param rotationCenter in local coordinates of the texture (if non is set the center of the texture is used) + */ virtual void draw2DImage(video::ITexture* texture, const core::position2d& destPos, const core::rect& sourceRect, const core::rect* clipRect = 0, - SColor color=SColor(255,255,255,255), bool useAlphaChannelOfTexture=false) = 0; + SColor color=SColor(255,255,255,255), bool useAlphaChannelOfTexture=false + , f32 angleInDegree=0.f, const core::position2d * rotationCenter=NULL) = 0; //! draws a set of 2d images, using a color and the alpha /** channel of the texture if desired. The images are drawn @@ -462,10 +466,14 @@ namespace video \param sourceRect: the rectangle denoting a part of the texture \param clipRect: clips the destination rectangle (may be 0) \param colors: array of 4 colors denoting the color values of the corners of the destRect - \param useAlphaChannelOfTexture: true if alpha channel will be blended. */ + \param useAlphaChannelOfTexture: true if alpha channel will be blended. + \param angleInDegree: rotation angle + \param rotationCenter in local coordinates of the texture (if non is set the center of the texture is used) + */ virtual void draw2DImage(video::ITexture* texture, const core::rect& destRect, const core::rect& sourceRect, const core::rect* clipRect = 0, - video::SColor* colors=0, bool useAlphaChannelOfTexture=false) = 0; + video::SColor* colors=0, bool useAlphaChannelOfTexture=false + , f32 angleInDegree=0.f, const core::position2d * rotationCenter=NULL) = 0; //!Draws an 2d rectangle. /** \param color: Color of the rectangle to draw. The alpha component will not diff -abBdpuNPr --exclude='*.svn' irrlicht-svn-ss/trunk/source/Irrlicht/CD3D8Driver.cpp Irrlicht_starsonata/source/Irrlicht/CD3D8Driver.cpp --- irrlicht-svn-ss/trunk/source/Irrlicht/CD3D8Driver.cpp 2007-07-26 02:11:08.000000000 +0200 +++ Irrlicht_starsonata/source/Irrlicht/CD3D8Driver.cpp 2008-08-05 02:03:58.000000000 +0200 @@ -878,7 +878,8 @@ void CD3D8Driver::drawVertexPrimitiveLis void CD3D8Driver::draw2DImage(video::ITexture* texture, const core::position2d& pos, const core::rect& sourceRect, const core::rect* clipRect, SColor color, - bool useAlphaChannelOfTexture) + bool useAlphaChannelOfTexture + , f32 angleInDegree, const core::position2d * rotationCenter) { if (!texture) return; @@ -976,12 +977,16 @@ void CD3D8Driver::draw2DImage(video::ITe s32 yPlus = renderTargetSize.Height-(renderTargetSize.Height>>1); f32 yFact = 1.0f / (renderTargetSize.Height>>1); - const core::dimension2d sourceSurfaceSize = texture->getOriginalSize(); + core::dimension2d ss; + if ( texture->hasPaddingForPOT() ) + ss = texture->getSize(); + else + ss = texture->getOriginalSize(); core::rect 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; + tcoords.UpperLeftCorner.X = (((f32)sourcePos.X)+0.5f) / ss.Width ; + tcoords.UpperLeftCorner.Y = (((f32)sourcePos.Y)+0.5f) / ss.Height; + tcoords.LowerRightCorner.X = (((f32)sourcePos.X +0.5f + (f32)sourceSize.Width)) / ss.Width; + tcoords.LowerRightCorner.Y = (((f32)sourcePos.Y +0.5f + (f32)sourceSize.Height)) / ss.Height; core::rect poss(targetPos, sourceSize); @@ -997,34 +1002,100 @@ void CD3D8Driver::draw2DImage(video::ITe setVertexShader(EVT_STANDARD); + if ( angleInDegree != 0.f ) + { + f32 cx = (vtx[0].Pos.X + vtx[2].Pos.X) / 2; + f32 cy = (vtx[0].Pos.Y + vtx[2].Pos.Y) / 2; + + if ( rotationCenter ) + { + cx = vtx[0].Pos.X + ((f32)rotationCenter->X / (f32)texture->getSize().Width)* (vtx[2].Pos.X - vtx[0].Pos.X); + cy = vtx[0].Pos.Y + ((f32)rotationCenter->Y / (f32)texture->getSize().Height)* (vtx[2].Pos.Y - vtx[0].Pos.Y); + } + + D3DXMATRIX mtrans1; + D3DXMATRIX mRotation; + D3DXMATRIX mtrans2; + D3DXMATRIX mAllTogetherNow; + + D3DXMatrixTranslation( &mtrans1, cx, cy, 0.f ); + D3DXMatrixRotationZ( &mRotation, D3DXToRadian( angleInDegree ) ); + D3DXMatrixTranslation( &mtrans2, -cx, -cy, 0.f ); + + // This is a real bad hack to avoid trouble with the projection matrix. + // I tried to fix it otherwise, but when doing that I break some other part of Irrlicht. + // I suppose it won't be a problem anymore with newer Irrlicht versions and as evil + // as this hack is here - it works. + D3DXMATRIX mScale; + float hackhackhack=float(renderTargetSize.Width)/float(renderTargetSize.Height); + D3DXMatrixScaling(&mScale, 1.0, hackhackhack, 1.0); + + mAllTogetherNow = mtrans2 * mRotation * mScale * mtrans1; + + pID3DDevice->SetTransform( D3DTS_WORLD, &mAllTogetherNow ); + } + pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST, 0, 4, 2, &indices[0], D3DFMT_INDEX16,&vtx[0], sizeof(S3DVertex)); + + if ( angleInDegree != 0.f ) + { + core::matrix4 mat; + pID3DDevice->SetTransform(D3DTS_WORLD, (D3DMATRIX*)((void*)mat.pointer())); + } } void CD3D8Driver::draw2DImage(video::ITexture* texture, const core::rect& destRect, const core::rect& sourceRect, const core::rect* clipRect, - video::SColor* colors, bool useAlphaChannelOfTexture) + video::SColor* colors, bool useAlphaChannelOfTexture + , f32 angleInDegree, const core::position2d * rotationCenter) { if(!texture) return; - const core::dimension2d& ss = texture->getOriginalSize(); + core::dimension2d ss; + if ( texture->hasPaddingForPOT() ) + ss = texture->getSize(); + else + ss = texture->getOriginalSize(); core::rect 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 clippedRect(destRect); + if ( clipRect ) + { + clippedRect.clipAgainst(*clipRect); + + // tcoords must be clipped by the same factors + core::rect 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& renderTargetSize = getCurrentRenderTargetSize(); core::rect 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 ); + 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 ); video::SColor temp[4] = { @@ -1050,8 +1121,47 @@ void CD3D8Driver::draw2DImage(video::ITe setVertexShader(EVT_STANDARD); + if ( angleInDegree != 0.f ) + { + f32 cx = (vtx[0].Pos.X + vtx[2].Pos.X) / 2; + f32 cy = (vtx[0].Pos.Y + vtx[2].Pos.Y) / 2; + + if ( rotationCenter ) + { + cx = vtx[0].Pos.X + ((f32)rotationCenter->X / (f32)texture->getSize().Width)* (vtx[2].Pos.X - vtx[0].Pos.X); + cy = vtx[0].Pos.Y + ((f32)rotationCenter->Y / (f32)texture->getSize().Height)* (vtx[2].Pos.Y - vtx[0].Pos.Y); + } + + D3DXMATRIX mtrans1; + D3DXMATRIX mRotation; + D3DXMATRIX mtrans2; + D3DXMATRIX mAllTogetherNow; + + D3DXMatrixTranslation( &mtrans1, cx, cy, 0.f ); + D3DXMatrixRotationZ( &mRotation, D3DXToRadian( angleInDegree ) ); + D3DXMatrixTranslation( &mtrans2, -cx, -cy, 0.f ); + + // This is a real bad hack to avoid trouble with the projection matrix. + // I tried to fix it otherwise, but when doing that I break some other part of Irrlicht. + // I suppose it won't be a problem anymore with newer Irrlicht versions and as evil + // as this hack is here - it works. + D3DXMATRIX mScale; + float hackhackhack=float(renderTargetSize.Width)/float(renderTargetSize.Height); + D3DXMatrixScaling(&mScale, 1.0, hackhackhack, 1.0); + + mAllTogetherNow = mtrans2 * mRotation * mScale * mtrans1; + + pID3DDevice->SetTransform( D3DTS_WORLD, &mAllTogetherNow ); + } + pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST, 0, 4, 2, &indices[0], D3DFMT_INDEX16,&vtx[0], sizeof(S3DVertex)); + + if ( angleInDegree != 0.f ) + { + core::matrix4 mat; + pID3DDevice->SetTransform(D3DTS_WORLD, (D3DMATRIX*)((void*)mat.pointer())); + } } diff -abBdpuNPr --exclude='*.svn' irrlicht-svn-ss/trunk/source/Irrlicht/CD3D8Driver.h Irrlicht_starsonata/source/Irrlicht/CD3D8Driver.h --- irrlicht-svn-ss/trunk/source/Irrlicht/CD3D8Driver.h 2007-07-26 02:11:08.000000000 +0200 +++ Irrlicht_starsonata/source/Irrlicht/CD3D8Driver.h 2008-08-04 00:03:20.000000000 +0200 @@ -71,12 +71,14 @@ namespace video //! 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. virtual void draw2DImage(video::ITexture* texture, const core::position2d& destPos, const core::rect& sourceRect, const core::rect* clipRect = 0, - SColor color=SColor(255,255,255,255), bool useAlphaChannelOfTexture=false); + SColor color=SColor(255,255,255,255), bool useAlphaChannelOfTexture=false + , f32 angleInDegree=0.f, const core::position2d * rotationCenter=NULL); //! Draws a part of the texture into the rectangle. virtual void draw2DImage(video::ITexture* texture, const core::rect& destRect, const core::rect& sourceRect, const core::rect* clipRect = 0, - video::SColor* colors=0, bool useAlphaChannelOfTexture=false); + video::SColor* colors=0, bool useAlphaChannelOfTexture=false + , f32 angleInDegree=0.f, const core::position2d * rotationCenter=NULL); //!Draws an 2d rectangle with a gradient. virtual void draw2DRectangle(const core::rect& pos, diff -abBdpuNPr --exclude='*.svn' irrlicht-svn-ss/trunk/source/Irrlicht/CD3D9Driver.cpp Irrlicht_starsonata/source/Irrlicht/CD3D9Driver.cpp --- irrlicht-svn-ss/trunk/source/Irrlicht/CD3D9Driver.cpp 2007-07-26 02:11:08.000000000 +0200 +++ Irrlicht_starsonata/source/Irrlicht/CD3D9Driver.cpp 2008-08-05 02:00:58.000000000 +0200 @@ -870,12 +870,18 @@ void CD3D9Driver::drawVertexPrimitiveLis void CD3D9Driver::draw2DImage(video::ITexture* texture, const core::rect& destRect, const core::rect& sourceRect, const core::rect* clipRect, - video::SColor* colors, bool useAlphaChannelOfTexture) + video::SColor* colors, bool useAlphaChannelOfTexture + , f32 angleInDegree, const core::position2d * rotationCenter) { if(!texture) return; - const core::dimension2d& ss = texture->getOriginalSize(); + core::dimension2d ss; + if ( texture->hasPaddingForPOT() ) + ss = texture->getSize(); + else + ss = texture->getOriginalSize(); + core::rect tcoords; tcoords.UpperLeftCorner.X = (f32)sourceRect.UpperLeftCorner.X / (f32)ss.Width; tcoords.UpperLeftCorner.Y = (f32)sourceRect.UpperLeftCorner.Y / (f32)ss.Height; @@ -915,9 +921,71 @@ void CD3D9Driver::draw2DImage(video::ITe setVertexShader(EVT_STANDARD); + // 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); + } + + if ( angleInDegree != 0.f ) + { + f32 cx = (vtx[0].Pos.X + vtx[2].Pos.X) / 2; + f32 cy = (vtx[0].Pos.Y + vtx[2].Pos.Y) / 2; + + if ( rotationCenter ) + { + cx = vtx[0].Pos.X + ((f32)rotationCenter->X / (f32)texture->getSize().Width)* (vtx[2].Pos.X - vtx[0].Pos.X); + cy = vtx[0].Pos.Y + ((f32)rotationCenter->Y / (f32)texture->getSize().Height)* (vtx[2].Pos.Y - vtx[0].Pos.Y); + } + + D3DXMATRIX mtrans1; + D3DXMATRIX mRotation; + D3DXMATRIX mtrans2; + D3DXMATRIX mAllTogetherNow; + + D3DXMatrixTranslation( &mtrans1, cx, cy, 0.f ); + + // This is a real bad hack to avoid trouble with the projection matrix. + // I tried to fix it otherwise, but when doing that I break some other part of Irrlicht. + // I suppose it won't be a problem anymore with newer Irrlicht versions and as evil + // as this hack is here - it works. + D3DXMATRIX mScale; + float hackhackhack=float(renderTargetSize.Width)/float(renderTargetSize.Height); + D3DXMatrixScaling(&mScale, 1.0, hackhackhack, 1.0); + + D3DXMatrixRotationZ( &mRotation, D3DXToRadian( angleInDegree ) ); + D3DXMatrixTranslation( &mtrans2, -cx, -cy, 0.f ); + + mAllTogetherNow = mtrans2 * mRotation * mScale * mtrans1; + + pID3DDevice->SetTransform( D3DTS_WORLD, &mAllTogetherNow ); + } + pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST, 0, 4, 2, &indices[0], D3DFMT_INDEX16,&vtx[0], sizeof(S3DVertex)); + if ( angleInDegree != 0.f ) + { + core::matrix4 mat; + pID3DDevice->SetTransform(D3DTS_WORLD, (D3DMATRIX*)((void*)mat.pointer())); + } + + if ( clipRect ) + { + pID3DDevice->SetScissorRect(&oldScissorRect); + pID3DDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, oldScissorTestRenderState); + } } @@ -928,7 +996,8 @@ void CD3D9Driver::draw2DImage(video::ITe const core::position2d& pos, const core::rect& sourceRect, const core::rect* clipRect, SColor color, - bool useAlphaChannelOfTexture) + bool useAlphaChannelOfTexture + , f32 angleInDegree, const core::position2d * rotationCenter) { if (!texture) return; @@ -1027,11 +1096,17 @@ void CD3D9Driver::draw2DImage(video::ITe f32 yPlus = renderTargetSize.Height-(renderTargetSize.Height / 2.f); f32 yFact = 1.0f / (renderTargetSize.Height / 2.f); + core::dimension2d ss; + if ( texture->hasPaddingForPOT() ) + ss = texture->getSize(); + else + ss = texture->getOriginalSize(); + core::rect 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; + tcoords.UpperLeftCorner.X = (((f32)sourcePos.X)+0.5f) / ss.Width ; + tcoords.UpperLeftCorner.Y = (((f32)sourcePos.Y)+0.5f) / ss.Height; + tcoords.LowerRightCorner.X = (((f32)sourcePos.X +0.5f + (f32)sourceSize.Width)) / ss.Width; + tcoords.LowerRightCorner.Y = (((f32)sourcePos.Y +0.5f + (f32)sourceSize.Height)) / ss.Height; core::rect poss(targetPos, sourceSize); @@ -1047,8 +1122,48 @@ void CD3D9Driver::draw2DImage(video::ITe setVertexShader(EVT_STANDARD); + if ( angleInDegree != 0.f ) + { + f32 cx = (vtx[0].Pos.X + vtx[2].Pos.X) / 2; + f32 cy = (vtx[0].Pos.Y + vtx[2].Pos.Y) / 2; + + if ( rotationCenter ) + { + cx = vtx[0].Pos.X + ((f32)rotationCenter->X / (f32)texture->getSize().Width)* (vtx[2].Pos.X - vtx[0].Pos.X); + cy = vtx[0].Pos.Y + ((f32)rotationCenter->Y / (f32)texture->getSize().Height)* (vtx[2].Pos.Y - vtx[0].Pos.Y); + } + + D3DXMATRIX mtrans1; + D3DXMATRIX mRotation; + D3DXMATRIX mtrans2; + D3DXMATRIX mAllTogetherNow; + + D3DXMatrixTranslation( &mtrans1, cx, cy, 0.f ); + + // This is a real bad hack to avoid trouble with the projection matrix. + // I tried to fix it otherwise, but when doing that I break some other part of Irrlicht. + // I suppose it won't be a problem anymore with newer Irrlicht versions and as evil + // as this hack is here - it works. + D3DXMATRIX mScale; + float hackhackhack=float(renderTargetSize.Width)/float(renderTargetSize.Height); + D3DXMatrixScaling(&mScale, 1.0, hackhackhack, 1.0); + + D3DXMatrixRotationZ( &mRotation, D3DXToRadian( angleInDegree ) ); + D3DXMatrixTranslation( &mtrans2, -cx, -cy, 0.f ); + + mAllTogetherNow = mtrans2 * mRotation * mScale * mtrans1; + + pID3DDevice->SetTransform( D3DTS_WORLD, &mAllTogetherNow ); + } + pID3DDevice->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST, 0, 4, 2, &indices[0], D3DFMT_INDEX16,&vtx[0], sizeof(S3DVertex)); + + if ( angleInDegree != 0.f ) + { + core::matrix4 mat; + pID3DDevice->SetTransform(D3DTS_WORLD, (D3DMATRIX*)((void*)mat.pointer())); + } } diff -abBdpuNPr --exclude='*.svn' irrlicht-svn-ss/trunk/source/Irrlicht/CD3D9Driver.h Irrlicht_starsonata/source/Irrlicht/CD3D9Driver.h --- irrlicht-svn-ss/trunk/source/Irrlicht/CD3D9Driver.h 2007-07-26 02:11:08.000000000 +0200 +++ Irrlicht_starsonata/source/Irrlicht/CD3D9Driver.h 2008-08-04 00:03:42.000000000 +0200 @@ -65,12 +65,14 @@ namespace video //! 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. virtual void draw2DImage(video::ITexture* texture, const core::position2d& destPos, const core::rect& sourceRect, const core::rect* clipRect = 0, - SColor color=SColor(255,255,255,255), bool useAlphaChannelOfTexture=false); + SColor color=SColor(255,255,255,255), bool useAlphaChannelOfTexture=false + , f32 angleInDegree=0.f, const core::position2d * rotationCenter=NULL); //! Draws a part of the texture into the rectangle. virtual void draw2DImage(video::ITexture* texture, const core::rect& destRect, const core::rect& sourceRect, const core::rect* clipRect = 0, - video::SColor* colors=0, bool useAlphaChannelOfTexture=false); + video::SColor* colors=0, bool useAlphaChannelOfTexture=false + , f32 angleInDegree=0.f, const core::position2d * rotationCenter=NULL); //!Draws an 2d rectangle with a gradient. virtual void draw2DRectangle(const core::rect& pos, diff -abBdpuNPr --exclude='*.svn' irrlicht-svn-ss/trunk/source/Irrlicht/CNullDriver.cpp Irrlicht_starsonata/source/Irrlicht/CNullDriver.cpp --- irrlicht-svn-ss/trunk/source/Irrlicht/CNullDriver.cpp 2007-07-26 02:11:08.000000000 +0200 +++ Irrlicht_starsonata/source/Irrlicht/CNullDriver.cpp 2008-08-04 00:03:52.000000000 +0200 @@ -602,7 +602,8 @@ void CNullDriver::draw2DImage(video::ITe //! Draws a part of the texture into the rectangle. void CNullDriver::draw2DImage(video::ITexture* texture, const core::rect& destRect, const core::rect& sourceRect, const core::rect* clipRect, - video::SColor* colors, bool useAlphaChannelOfTexture) + video::SColor* colors, bool useAlphaChannelOfTexture + , f32 angleInDegree, const core::position2d * rotationCenter) { } @@ -612,7 +613,8 @@ void CNullDriver::draw2DImage(video::ITe void CNullDriver::draw2DImage(video::ITexture* texture, const core::position2d& destPos, const core::rect& sourceRect, const core::rect* clipRect, SColor color, - bool useAlphaChannelOfTexture) + bool useAlphaChannelOfTexture + , f32 angleInDegree, const core::position2d * rotationCenter) { } diff -abBdpuNPr --exclude='*.svn' irrlicht-svn-ss/trunk/source/Irrlicht/CNullDriver.h Irrlicht_starsonata/source/Irrlicht/CNullDriver.h --- irrlicht-svn-ss/trunk/source/Irrlicht/CNullDriver.h 2007-07-26 02:11:08.000000000 +0200 +++ Irrlicht_starsonata/source/Irrlicht/CNullDriver.h 2008-08-04 00:03:58.000000000 +0200 @@ -150,12 +150,14 @@ namespace video //! 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. virtual void draw2DImage(video::ITexture* texture, const core::position2d& destPos, const core::rect& sourceRect, const core::rect* clipRect = 0, - SColor color=SColor(255,255,255,255), bool useAlphaChannelOfTexture=false); + SColor color=SColor(255,255,255,255), bool useAlphaChannelOfTexture=false + , f32 angleInDegree=0.f, const core::position2d * rotationCenter=NULL); //! Draws a part of the texture into the rectangle. virtual void draw2DImage(video::ITexture* texture, const core::rect& destRect, const core::rect& sourceRect, const core::rect* clipRect = 0, - video::SColor* colors=0, bool useAlphaChannelOfTexture=false); + video::SColor* colors=0, bool useAlphaChannelOfTexture=false + , f32 angleInDegree=0.f, const core::position2d * rotationCenter=NULL); //! draw an 2d rectangle virtual void draw2DRectangle(SColor color, const core::rect& pos, const core::rect* clip = 0); diff -abBdpuNPr --exclude='*.svn' irrlicht-svn-ss/trunk/source/Irrlicht/COpenGLDriver.cpp Irrlicht_starsonata/source/Irrlicht/COpenGLDriver.cpp --- irrlicht-svn-ss/trunk/source/Irrlicht/COpenGLDriver.cpp 2007-07-26 02:11:08.000000000 +0200 +++ Irrlicht_starsonata/source/Irrlicht/COpenGLDriver.cpp 2008-08-05 01:50:24.000000000 +0200 @@ -659,7 +659,8 @@ void COpenGLDriver::draw2DImage(video::I const core::position2d& pos, const core::rect& sourceRect, const core::rect* clipRect, SColor color, - bool useAlphaChannelOfTexture) + bool useAlphaChannelOfTexture + , f32 angleInDegree, const core::position2d * rotationCenter) { if (!texture) return; @@ -747,9 +748,13 @@ void COpenGLDriver::draw2DImage(video::I // ok, we've clipped everything. // now draw it. - const core::dimension2d& ss = texture->getOriginalSize(); - core::rect tcoords; + core::dimension2d ss; + if ( texture->hasPaddingForPOT() ) + ss = texture->getSize(); + else + ss = texture->getOriginalSize(); + core::rect tcoords; tcoords.UpperLeftCorner.X = (f32)sourcePos.X / (f32)ss.Width; tcoords.UpperLeftCorner.Y = (f32)sourcePos.Y / (f32)ss.Height; tcoords.LowerRightCorner.X = ((f32)sourcePos.X +(f32)sourceSize.Width) / (f32)ss.Width; @@ -765,10 +770,37 @@ void COpenGLDriver::draw2DImage(video::I npos.LowerRightCorner.X = ( poss.LowerRightCorner.X * xFact ) - 1.0f; npos.LowerRightCorner.Y = 1.0f - ( poss.LowerRightCorner.Y * yFact ); - setRenderStates2DMode(color.getAlpha()<255, true, useAlphaChannelOfTexture); disableTextures(1); if (!setTexture(0, texture)) return; + setRenderStates2DMode(color.getAlpha()<255, true, useAlphaChannelOfTexture); + + if ( angleInDegree != 0.f ) + { + f32 cx = (npos.UpperLeftCorner.X + npos.LowerRightCorner.X) / 2; + f32 cy = (npos.UpperLeftCorner.Y + npos.LowerRightCorner.Y) / 2; + + if ( rotationCenter ) + { + cx = npos.UpperLeftCorner.X + ((f32)rotationCenter->X / (f32)(texture->getSize().Width))*npos.getWidth(); + cy = npos.UpperLeftCorner.Y + ((f32)rotationCenter->Y / (f32)(texture->getSize().Height))*npos.getHeight(); + } + + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + + glTranslatef(cx, cy, 0); + + // This is a real bad hack to avoid trouble with the projection matrix. + // I tried to fix it otherwise, but when doing that I break some other part of Irrlicht. + // I suppose it won't be a problem anymore with newer Irrlicht versions and as evil + // as this hack is here - it works. + float hackhackhack=float(renderTargetSize.Width)/float(renderTargetSize.Height); + glScalef(1.0, hackhackhack, 1.0); + + glRotatef(angleInDegree, 0.0, 0.0, 1.0); + glTranslatef(-cx, -cy, 0); + } glColor4ub(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha()); glBegin(GL_QUADS); @@ -786,6 +818,11 @@ void COpenGLDriver::draw2DImage(video::I glVertex2f(npos.UpperLeftCorner.X, npos.LowerRightCorner.Y); glEnd(); + + if ( angleInDegree != 0.f ) + { + glPopMatrix(); + } } @@ -806,10 +843,10 @@ void COpenGLDriver::draw2DImage(video::I return; const core::dimension2d& renderTargetSize = getCurrentRenderTargetSize(); - setRenderStates2DMode(color.getAlpha()<255, true, useAlphaChannelOfTexture); disableTextures(1); if (!setTexture(0, texture)) return; + setRenderStates2DMode(color.getAlpha()<255, true, useAlphaChannelOfTexture); glColor4ub(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha()); if (clipRect) @@ -822,7 +859,12 @@ void COpenGLDriver::draw2DImage(video::I clipRect->getWidth(),clipRect->getHeight()); } - const core::dimension2d& ss = texture->getOriginalSize(); + core::dimension2d ss; + if ( texture->hasPaddingForPOT() ) + ss = texture->getSize(); + else + ss = texture->getOriginalSize(); + core::position2d targetPos(pos); core::position2d sourcePos; core::dimension2d sourceSize; @@ -877,12 +919,18 @@ void COpenGLDriver::draw2DImage(video::I void COpenGLDriver::draw2DImage(video::ITexture* texture, const core::rect& destRect, const core::rect& sourceRect, const core::rect* clipRect, - video::SColor* colors, bool useAlphaChannelOfTexture) + video::SColor* colors, bool useAlphaChannelOfTexture + , f32 angleInDegree, const core::position2d * rotationCenter) { if (!texture) return; - const core::dimension2d& ss = texture->getOriginalSize(); + core::dimension2d ss; + if ( texture->hasPaddingForPOT() ) + ss = texture->getSize(); + else + ss = texture->getOriginalSize(); + core::rect tcoords; tcoords.UpperLeftCorner.X = (f32)sourceRect.UpperLeftCorner.X / (f32)ss.Width; tcoords.UpperLeftCorner.Y = (f32)sourceRect.UpperLeftCorner.Y / (f32)ss.Height; @@ -908,10 +956,9 @@ void COpenGLDriver::draw2DImage(video::I video::SColor* useColor = colors ? colors : temp; - setRenderStates2DMode(useColor[0].getAlpha()<255 || useColor[1].getAlpha()<255 || useColor[2].getAlpha()<255 || useColor[3].getAlpha()<255, true, useAlphaChannelOfTexture); - disableTextures(1); setTexture(0, texture); + setRenderStates2DMode(useColor[0].getAlpha()<255 || useColor[1].getAlpha()<255 || useColor[2].getAlpha()<255 || useColor[3].getAlpha()<255, true, useAlphaChannelOfTexture); if (clipRect) { @@ -923,6 +970,33 @@ void COpenGLDriver::draw2DImage(video::I clipRect->getWidth(),clipRect->getHeight()); } + if ( angleInDegree != 0.f ) + { + f32 cx = (npos.UpperLeftCorner.X + npos.LowerRightCorner.X) / 2; + f32 cy = (npos.UpperLeftCorner.Y + npos.LowerRightCorner.Y) / 2; + + if ( rotationCenter ) + { + cx = npos.UpperLeftCorner.X + ((f32)rotationCenter->X / (f32)(texture->getSize().Width))*npos.getWidth(); + cy = npos.UpperLeftCorner.Y + ((f32)rotationCenter->Y / (f32)(texture->getSize().Height))*npos.getHeight(); + } + + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + glTranslatef(cx, cy, 0); + + // This is a real bad hack to avoid trouble with the projection matrix. + // I tried to fix it otherwise, but when doing that I break some other part of Irrlicht. + // I suppose it won't be a problem anymore with newer Irrlicht versions and as evil + // as this hack is here - it works. + float hackhackhack=float(renderTargetSize.Width)/float(renderTargetSize.Height); + glScalef(1.0, hackhackhack, 1.0); + + glRotatef(angleInDegree, 0.0, 0.0, 1.0); + glTranslatef(-cx, -cy, 0); + } + glBegin(GL_QUADS); glColor4ub(useColor[0].getRed(), useColor[0].getGreen(), useColor[0].getBlue(), useColor[0].getAlpha()); @@ -943,6 +1017,12 @@ void COpenGLDriver::draw2DImage(video::I glEnd(); + if ( angleInDegree != 0.f ) + { + glPopMatrix(); + glPopMatrix(); + } + if (clipRect) glDisable(GL_SCISSOR_TEST); } @@ -953,8 +1033,8 @@ void COpenGLDriver::draw2DImage(video::I void COpenGLDriver::draw2DRectangle(SColor color, const core::rect& position, const core::rect* clip) { - setRenderStates2DMode(color.getAlpha() < 255, false, false); disableTextures(); + setRenderStates2DMode(color.getAlpha() < 255, false, false); core::rect pos = position; @@ -1006,13 +1086,13 @@ void COpenGLDriver::draw2DRectangle(cons npos.LowerRightCorner.X = (f32)(pos.LowerRightCorner.X-xPlus) * xFact; npos.LowerRightCorner.Y = (f32)(yPlus-pos.LowerRightCorner.Y) * yFact; + disableTextures(); + setRenderStates2DMode(colorLeftUp.getAlpha() < 255 || colorRightUp.getAlpha() < 255 || colorLeftDown.getAlpha() < 255 || colorRightDown.getAlpha() < 255, false, false); - disableTextures(); - glBegin(GL_QUADS); glColor4ub(colorLeftUp.getRed(), colorLeftUp.getGreen(), colorLeftUp.getBlue(), colorLeftUp.getAlpha()); @@ -1058,9 +1138,10 @@ void COpenGLDriver::draw2DLine(const cor npos_end.X = (f32)(end.X - xPlus) * xFact; npos_end.Y = (f32)(yPlus - end.Y) * yFact; - setRenderStates2DMode(color.getAlpha() < 255, false, false); disableTextures(); + setRenderStates2DMode(color.getAlpha() < 255, false, false); + glBegin(GL_LINES); glColor4ub(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha()); glVertex2f(npos_start.X, npos_start.Y); @@ -1582,7 +1663,6 @@ void COpenGLDriver::setRenderStates2DMod glDisable(GL_ALPHA_TEST); glCullFace(GL_BACK); - } if (texture) diff -abBdpuNPr --exclude='*.svn' irrlicht-svn-ss/trunk/source/Irrlicht/COpenGLDriver.h Irrlicht_starsonata/source/Irrlicht/COpenGLDriver.h --- irrlicht-svn-ss/trunk/source/Irrlicht/COpenGLDriver.h 2007-07-26 02:11:08.000000000 +0200 +++ Irrlicht_starsonata/source/Irrlicht/COpenGLDriver.h 2008-08-04 00:04:18.000000000 +0200 @@ -122,7 +122,8 @@ namespace video //! 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. virtual void draw2DImage(video::ITexture* texture, const core::position2d& destPos, const core::rect& sourceRect, const core::rect* clipRect = 0, - SColor color=SColor(255,255,255,255), bool useAlphaChannelOfTexture=false); + SColor color=SColor(255,255,255,255), bool useAlphaChannelOfTexture=false + , f32 angleInDegree=0.f, const core::position2d * rotationCenter=NULL); //! draws a set of 2d images, using a color and the alpha /** channel of the texture if desired. The images are drawn @@ -151,7 +152,8 @@ namespace video //! Draws a part of the texture into the rectangle. virtual void draw2DImage(video::ITexture* texture, const core::rect& destRect, const core::rect& sourceRect, const core::rect* clipRect = 0, - video::SColor* colors=0, bool useAlphaChannelOfTexture=false); + video::SColor* colors=0, bool useAlphaChannelOfTexture=false + , f32 angleInDegree=0.f, const core::position2d * rotationCenter=NULL); //! draw an 2d rectangle virtual void draw2DRectangle(SColor color, const core::rect& pos, diff -abBdpuNPr --exclude='*.svn' irrlicht-svn-ss/trunk/source/Irrlicht/CSoftwareDriver2.cpp Irrlicht_starsonata/source/Irrlicht/CSoftwareDriver2.cpp --- irrlicht-svn-ss/trunk/source/Irrlicht/CSoftwareDriver2.cpp 2007-07-26 02:11:08.000000000 +0200 +++ Irrlicht_starsonata/source/Irrlicht/CSoftwareDriver2.cpp 2008-08-04 00:03:06.000000000 +0200 @@ -1570,7 +1570,8 @@ void CSoftwareDriver2::lightVertex ( s4D void CSoftwareDriver2::draw2DImage(video::ITexture* texture, const core::position2d& destPos, const core::rect& sourceRect, const core::rect* clipRect, SColor color, - bool useAlphaChannelOfTexture) + bool useAlphaChannelOfTexture + , f32 angleInDegree, const core::position2d * rotationCenter) { if (texture) { diff -abBdpuNPr --exclude='*.svn' irrlicht-svn-ss/trunk/source/Irrlicht/CSoftwareDriver2.h Irrlicht_starsonata/source/Irrlicht/CSoftwareDriver2.h --- irrlicht-svn-ss/trunk/source/Irrlicht/CSoftwareDriver2.h 2007-07-26 02:11:08.000000000 +0200 +++ Irrlicht_starsonata/source/Irrlicht/CSoftwareDriver2.h 2008-08-04 00:01:54.000000000 +0200 @@ -67,7 +67,8 @@ namespace video //! 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. virtual void draw2DImage(video::ITexture* texture, const core::position2d& destPos, const core::rect& sourceRect, const core::rect* clipRect = 0, - SColor color=SColor(255,255,255,255), bool useAlphaChannelOfTexture=false); + SColor color=SColor(255,255,255,255), bool useAlphaChannelOfTexture=false + , f32 angleInDegree=0.f, const core::position2d * rotationCenter=NULL); //! Draws a 3d line.diff -abBpNPwrU2 --exclude="*.svn" irrlicht-svn-ss/trunk Irrlicht_starsonata > svn_808_all.patch virtual void draw3DLine(const core::vector3df& start, diff -abBdpuNPr --exclude='*.svn' irrlicht-svn-ss/trunk/source/Irrlicht/CSoftwareDriver.cpp Irrlicht_starsonata/source/Irrlicht/CSoftwareDriver.cpp --- irrlicht-svn-ss/trunk/source/Irrlicht/CSoftwareDriver.cpp 2007-07-26 02:11:08.000000000 +0200 +++ Irrlicht_starsonata/source/Irrlicht/CSoftwareDriver.cpp 2008-08-04 00:04:24.000000000 +0200 @@ -732,7 +732,8 @@ void CSoftwareDriver::createPlanes(const void CSoftwareDriver::draw2DImage(video::ITexture* texture, const core::position2d& destPos, const core::rect& sourceRect, const core::rect* clipRect, SColor color, - bool useAlphaChannelOfTexture) + bool useAlphaChannelOfTexture + , f32 angleInDegree, const core::position2d * rotationCenter) { if (texture) { diff -abBdpuNPr --exclude='*.svn' irrlicht-svn-ss/trunk/source/Irrlicht/CSoftwareDriver.h Irrlicht_starsonata/source/Irrlicht/CSoftwareDriver.h --- irrlicht-svn-ss/trunk/source/Irrlicht/CSoftwareDriver.h 2007-07-26 02:11:08.000000000 +0200 +++ Irrlicht_starsonata/source/Irrlicht/CSoftwareDriver.h 2008-08-04 00:04:32.000000000 +0200 @@ -55,7 +55,8 @@ namespace video //! 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. virtual void draw2DImage(video::ITexture* texture, const core::position2d& destPos, const core::rect& sourceRect, const core::rect* clipRect = 0, - SColor color=SColor(255,255,255,255), bool useAlphaChannelOfTexture=false); + SColor color=SColor(255,255,255,255), bool useAlphaChannelOfTexture=false + , f32 angleInDegree=0.f, const core::position2d * rotationCenter=NULL); //! draw an 2d rectangle virtual void draw2DRectangle(SColor color, const core::rect& pos,