Permalink
Find file
Fetching contributors…
Cannot retrieve contributors at this time
154 lines (113 sloc) 3.7 KB
#include "GDIPlusTexture.h"
GDIPlusTexture::GDIPlusTexture( IDirect3DDevice9 *gpu, int width, int height, bool smoothingMode )
{
this->gpu = gpu ;
this->width = width ;
this->height = height ;
// create a texture
HRESULT hr ;
hr = D3DXCreateTexture( gpu,
width, height,
1, 0,
D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &tex ) ; // must be X8, since "alpha not clearly defined.."
DX_CHECK( hr, "Create texture for GDI+ usage" ) ;
// Get its surface
hr = tex->GetSurfaceLevel( 0, &surface ) ;
DX_CHECK( hr, "Get surface of GDI+ texture" ) ;
hr = surface->GetDC( &texDC ) ;
DX_CHECK( hr, "GetDC of GDI+ texture" ) ;
// Create the GDI+ graphics object
// connected to the texture via its DC now
g = new Graphics( texDC ) ;
if( !g )
{
printWindowsLastError( "Could not get g, GDI+ texture" ) ;
}
if( smoothingMode )
{
g->SetSmoothingMode( SmoothingModeAntiAlias ) ;
g->SetTextRenderingHint( TextRenderingHintAntiAlias ) ;
}
}
IDirect3DTexture9* GDIPlusTexture::getTexture()
{
// K now i'm going to hack a copy
// of the texture because it doesn't let you use
// A8R8G8B8 when you use a DC. For some silly reason.
// Luckily the X8 DOES preserve the alpha channel values
// generated by GDI+
D3DLOCKED_RECT lockedRectTex, lockedRectCpyA8 ;
// copy texture with A8
IDirect3DTexture9 *cpyA8 ;
DX_CHECK( D3DXCreateTexture(
gpu, width, height,
1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED,
&cpyA8 ), "Create texture from file in memory" ) ;
int dataLen = width*height*sizeof(int) ; // a8r8g8b8!
// To lock, you have to release the DC first.
DX_CHECK( surface->ReleaseDC( texDC ), "Release DC, before lock tex" ) ;
// lock both
DX_CHECK( tex->LockRect( 0, &lockedRectTex, NULL, 0 ), "Lock rect tex" ) ;
DX_CHECK( cpyA8->LockRect( 0, &lockedRectCpyA8, NULL, 0 ), "Lock rect cpyA8" ) ;
memcpy( lockedRectCpyA8.pBits, lockedRectTex.pBits, dataLen ) ;
DX_CHECK( cpyA8->UnlockRect( 0 ), "Unlock rect cpyA8" ) ;
DX_CHECK( tex->UnlockRect( 0 ), "Unlock rect tex" ) ;
// can get the DC back now
DX_CHECK( surface->GetDC( &texDC ), "re-gain DC" ) ;
return cpyA8 ;
}
int GDIPlusTexture::getWidth()
{
return width ;
}
int GDIPlusTexture::getHeight()
{
return height ;
}
void GDIPlusTexture::boxedText( TCHAR* text, Font *font, RECT padding, Color textColor, Color bkgColor, RectF limitingRect, StringAlignment alignment )
{
SolidBrush bkgBrush( bkgColor ) ;
SolidBrush textBrush( textColor ) ;
// draw the bkg rect
g->FillRectangle( &bkgBrush, limitingRect ) ;
StringFormat sf ;
sf.SetAlignment( alignment ) ;
g->DrawString( text, 1, font, limitingRect, &sf, &textBrush ) ;
}
GDIPlusTexture::~GDIPlusTexture()
{
// The user will draw with g onto
// the surface presumably until this
// GDIPlusTexture object is destroyed.
// Then the texture need live on, but
// the surfaceDC can be released
surface->ReleaseDC( texDC ) ;
// the TEX was connected to the
// backDC, and its safe to release it
SAFE_RELEASE( tex ) ;
}
GDIPlusTexture*
GDIPlusTexture::CreateFromFile(
IDirect3DDevice9 *gpu, const char *filename
)
{
// Load the image
Image *image ;
#ifdef _UNICODE
WCHAR *wFilename = getUnicode( filename ) ;
image = new Image( wFilename ) ;
if( image->GetLastStatus() != Status::Ok )
{
warning( "%s failed to load through GDI+", filename ) ;
}
delete[] wFilename ;
#else
image = new Image( filename ) ;
#endif
// Create a surface the right size
GDIPlusTexture *gdiPlusTex = new GDIPlusTexture( gpu, image->GetWidth(), image->GetHeight(), false ) ;
// Draw the sprite into it
gdiPlusTex->g->DrawImage( image, 0, 0 ) ;
// now, just retrieve the IDirect3DTexture9 from it
return gdiPlusTex ;
}