// --------------------------------------------------------------------------- // // @file TwDirect3D9.cpp // @author Philippe Decaudin - http://www.antisphere.com // @license This file is part of the AntTweakBar library. // Copyright © 2005, 2006 Philippe Decaudin. // For conditions of distribution and use, see License.txt // // note: TAB=4 // // --------------------------------------------------------------------------- #include "TwPrecomp.h" #include "TwDirect3D9.h" #include "TwMgr.h" #include #ifdef _DEBUG #include #pragma comment(lib, "dxerr9") #endif // _DEBUG using namespace std; const char *g_ErrCantLoadD3D9 = "Cannot load Direct3D9 library dynamically"; const char *g_ErrCantUnloadD3D9 = "Cannot unload Direct3D9 library"; // --------------------------------------------------------------------------- static IDirect3DTexture9 *BindFont(IDirect3DDevice9 *_Dev, const CTexFont *_Font) { assert(_Font!=NULL); IDirect3DTexture9 *Tex = NULL; HRESULT hr = _Dev->CreateTexture(_Font->m_TexWidth, _Font->m_TexHeight, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &Tex, NULL); if( FAILED(hr) ) return NULL; D3DLOCKED_RECT r; hr = Tex->LockRect(0, &r, NULL, 0); if( SUCCEEDED(hr) ) { color32 *p = static_cast(r.pBits); for( int i=0; i<_Font->m_TexWidth*_Font->m_TexHeight; ++i, ++p ) *p = 0x00ffffff | (((color32)(_Font->m_TexBytes[i]))<<24); Tex->UnlockRect(0); } return Tex; } // --------------------------------------------------------------------------- static void UnbindFont(IDirect3DDevice9 *_Dev, IDirect3DTexture9 *_Tex) { (void)_Dev; if( _Tex ) _Tex->Release(); } // --------------------------------------------------------------------------- struct CState { // viewport D3DVIEWPORT9 m_Vp; // render states DWORD m_Z; DWORD m_CullMode; DWORD m_AlphaTest; DWORD m_AlphaBlend; DWORD m_BlendOp; DWORD m_SrcBlend; DWORD m_DstBlend; DWORD m_ClipPlane; DWORD m_FillMode; DWORD m_LastPixel; DWORD m_Fog; DWORD m_Stencil; DWORD m_ColorWrite; DWORD m_Scissor; DWORD m_SeparateAlphaBlend; DWORD m_AntiAliasedLine; // primitive DWORD m_FVF; IDirect3DVertexBuffer9 *m_StreamData; IDirect3DVertexShader9 *m_VertexShader; UINT m_StreamOffset; UINT m_StreamStride; // texture IDirect3DBaseTexture9 *m_Tex; IDirect3DPixelShader9 *m_PixelShader; // texture stage states DWORD m_ColorOp; DWORD m_ColorArg1; DWORD m_ColorArg2; DWORD m_AlphaOp; DWORD m_AlphaArg1; DWORD m_TexCoordIndex; DWORD m_TexTransfFlags; DWORD m_AddressU; DWORD m_AddressV; DWORD m_MinFilter; DWORD m_MagFilter; DWORD m_MipFilter; // DeviceCaps (filled by constructor) D3DCAPS9 m_Caps; void Save(); void Restore(); CState(IDirect3DDevice9 *_Dev); private: IDirect3DDevice9 *m_D3DDev; }; CState::CState(IDirect3DDevice9 *_Dev) { ZeroMemory(this, sizeof(CState)); m_D3DDev = _Dev; m_D3DDev->GetDeviceCaps(&m_Caps); } void CState::Save() { // viewport m_D3DDev->GetViewport(&m_Vp); // render states m_D3DDev->GetRenderState(D3DRS_ZENABLE, &m_Z); m_D3DDev->GetRenderState(D3DRS_CULLMODE, &m_CullMode); m_D3DDev->GetRenderState(D3DRS_ALPHATESTENABLE, &m_AlphaTest); m_D3DDev->GetRenderState(D3DRS_ALPHABLENDENABLE, &m_AlphaBlend); m_D3DDev->GetRenderState(D3DRS_BLENDOP, &m_BlendOp); m_D3DDev->GetRenderState(D3DRS_SRCBLEND, &m_SrcBlend); m_D3DDev->GetRenderState(D3DRS_DESTBLEND, &m_DstBlend); m_D3DDev->GetRenderState(D3DRS_CLIPPLANEENABLE, &m_ClipPlane); m_D3DDev->GetRenderState(D3DRS_FILLMODE, &m_FillMode); m_D3DDev->GetRenderState(D3DRS_LASTPIXEL, &m_LastPixel); m_D3DDev->GetRenderState(D3DRS_FOGENABLE, &m_Fog); m_D3DDev->GetRenderState(D3DRS_STENCILENABLE, &m_Stencil); m_D3DDev->GetRenderState(D3DRS_COLORWRITEENABLE, &m_ColorWrite); m_D3DDev->GetRenderState(D3DRS_SCISSORTESTENABLE, &m_Scissor); if( m_Caps.PrimitiveMiscCaps & D3DPMISCCAPS_SEPARATEALPHABLEND ) m_D3DDev->GetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, &m_SeparateAlphaBlend); //if( m_Caps.LineCaps & D3DLINECAPS_ANTIALIAS ) m_D3DDev->GetRenderState(D3DRS_ANTIALIASEDLINEENABLE, &m_AntiAliasedLine); // primitive m_D3DDev->GetFVF(&m_FVF); m_D3DDev->GetStreamSource(0, &m_StreamData, &m_StreamOffset, &m_StreamStride); m_D3DDev->GetVertexShader(&m_VertexShader); // texture m_D3DDev->GetTexture(0, &m_Tex); m_D3DDev->GetPixelShader(&m_PixelShader); // texture stage states m_D3DDev->GetTextureStageState(0, D3DTSS_COLOROP, &m_ColorOp); m_D3DDev->GetTextureStageState(0, D3DTSS_COLORARG1, &m_ColorArg1); m_D3DDev->GetTextureStageState(0, D3DTSS_COLORARG2, &m_ColorArg2); m_D3DDev->GetTextureStageState(0, D3DTSS_ALPHAOP, &m_AlphaOp); m_D3DDev->GetTextureStageState(0, D3DTSS_ALPHAARG1, &m_AlphaArg1); m_D3DDev->GetTextureStageState(0, D3DTSS_TEXCOORDINDEX, &m_TexCoordIndex); m_D3DDev->GetTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS, &m_TexTransfFlags); m_D3DDev->GetSamplerState(0, D3DSAMP_ADDRESSU, &m_AddressU); m_D3DDev->GetSamplerState(0, D3DSAMP_ADDRESSV, &m_AddressV); m_D3DDev->GetSamplerState(0, D3DSAMP_MAGFILTER, &m_MagFilter); m_D3DDev->GetSamplerState(0, D3DSAMP_MINFILTER, &m_MinFilter); m_D3DDev->GetSamplerState(0, D3DSAMP_MIPFILTER, &m_MipFilter); } void CState::Restore() { // viewport m_D3DDev->SetViewport(&m_Vp); // render states m_D3DDev->SetRenderState(D3DRS_ZENABLE, m_Z); m_D3DDev->SetRenderState(D3DRS_CULLMODE, m_CullMode); m_D3DDev->SetRenderState(D3DRS_ALPHATESTENABLE, m_AlphaTest); m_D3DDev->SetRenderState(D3DRS_ALPHABLENDENABLE, m_AlphaBlend); m_D3DDev->SetRenderState(D3DRS_BLENDOP, m_BlendOp); m_D3DDev->SetRenderState(D3DRS_SRCBLEND, m_SrcBlend); m_D3DDev->SetRenderState(D3DRS_DESTBLEND, m_DstBlend); m_D3DDev->SetRenderState(D3DRS_CLIPPLANEENABLE, m_ClipPlane); m_D3DDev->SetRenderState(D3DRS_FILLMODE, m_FillMode); m_D3DDev->SetRenderState(D3DRS_LASTPIXEL, m_LastPixel); m_D3DDev->SetRenderState(D3DRS_FOGENABLE, m_Fog); m_D3DDev->SetRenderState(D3DRS_STENCILENABLE, m_Stencil); m_D3DDev->SetRenderState(D3DRS_COLORWRITEENABLE, m_ColorWrite); m_D3DDev->SetRenderState(D3DRS_SCISSORTESTENABLE, m_Scissor); if( m_Caps.PrimitiveMiscCaps & D3DPMISCCAPS_SEPARATEALPHABLEND ) m_D3DDev->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, m_SeparateAlphaBlend); //if( m_Caps.LineCaps & D3DLINECAPS_ANTIALIAS ) m_D3DDev->SetRenderState(D3DRS_ANTIALIASEDLINEENABLE, m_AntiAliasedLine); // primitive m_D3DDev->SetFVF(m_FVF); m_D3DDev->SetStreamSource(0, m_StreamData, m_StreamOffset, m_StreamStride); if( m_StreamData ) m_StreamData->Release(); m_D3DDev->SetVertexShader(m_VertexShader); if( m_VertexShader ) m_VertexShader->Release(); // texture m_D3DDev->SetTexture(0, m_Tex); if( m_Tex ) m_Tex->Release(); m_D3DDev->SetPixelShader(m_PixelShader); if( m_PixelShader ) m_PixelShader->Release(); // texture stage states m_D3DDev->SetTextureStageState(0, D3DTSS_COLOROP, m_ColorOp); m_D3DDev->SetTextureStageState(0, D3DTSS_COLORARG1, m_ColorArg1); m_D3DDev->SetTextureStageState(0, D3DTSS_COLORARG2, m_ColorArg2); m_D3DDev->SetTextureStageState(0, D3DTSS_ALPHAOP, m_AlphaOp); m_D3DDev->SetTextureStageState(0, D3DTSS_ALPHAARG1, m_AlphaArg1); m_D3DDev->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, m_TexCoordIndex); m_D3DDev->SetTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS, m_TexTransfFlags); m_D3DDev->SetSamplerState(0, D3DSAMP_ADDRESSU, m_AddressU); m_D3DDev->SetSamplerState(0, D3DSAMP_ADDRESSV, m_AddressV); m_D3DDev->SetSamplerState(0, D3DSAMP_MAGFILTER, m_MagFilter); m_D3DDev->SetSamplerState(0, D3DSAMP_MINFILTER, m_MinFilter); m_D3DDev->SetSamplerState(0, D3DSAMP_MIPFILTER, m_MipFilter); } // --------------------------------------------------------------------------- int CTwGraphDirect3D9::Init() { assert(g_TwMgr->m_Device!=NULL); m_D3DDev = static_cast(g_TwMgr->m_Device); m_Drawing = false; m_FontTex = NULL; m_FontD3DTex = NULL; D3DDEVICE_CREATION_PARAMETERS cp; m_D3DDev->GetCreationParameters(&cp); m_PureDevice = ( cp.BehaviorFlags & D3DCREATE_PUREDEVICE ) ? true : false; m_WndWidth = 0; m_WndHeight = 0; m_State = new CState(m_D3DDev); return 1; } // --------------------------------------------------------------------------- int CTwGraphDirect3D9::Shut() { assert(m_Drawing==false); UnbindFont(m_D3DDev, m_FontD3DTex); m_FontD3DTex = NULL; delete m_State; m_State = NULL; m_D3DDev = NULL; return 1; } // --------------------------------------------------------------------------- void CTwGraphDirect3D9::BeginDraw(int _WndWidth, int _WndHeight) { assert(m_Drawing==false && _WndWidth>0 && _WndHeight>0); m_Drawing = true; m_WndWidth = _WndWidth; m_WndHeight = _WndHeight; // save context if( !m_PureDevice ) m_State->Save(); if( m_WndWidth>0 && m_WndHeight>0 ) { D3DVIEWPORT9 Vp; Vp.X = 0; Vp.Y = 0; Vp.Width = m_WndWidth; Vp.Height = m_WndHeight; Vp.MinZ = 0; Vp.MaxZ = 1; m_D3DDev->SetViewport(&Vp); //D3DMATRIX Transfo = { 2.0f/_WndWidth,0,0,0, 0,2.0f/_WndHeight,0,0, 0,0,-1,0, 0,0,0,1 }; //m_D3DDev->SetTransform(D3DTS_PROJECTION, &Transfo); } // const D3DMATRIX id = { 1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1 }; // m_D3DDev->SetTransform(D3DTS_VIEW, &id); // m_D3DDev->SetTransform(D3DTS_WORLD, &id); // m_D3DDev->SetTransform(D3DTS_TEXTURE0, &id); m_D3DDev->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE); m_D3DDev->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); m_D3DDev->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE); m_D3DDev->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); m_D3DDev->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD); m_D3DDev->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); m_D3DDev->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); m_D3DDev->SetRenderState(D3DRS_CLIPPLANEENABLE, 0); m_D3DDev->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID); m_D3DDev->SetRenderState(D3DRS_LASTPIXEL, FALSE); m_D3DDev->SetRenderState(D3DRS_FOGENABLE, FALSE); m_D3DDev->SetRenderState(D3DRS_STENCILENABLE, FALSE); m_D3DDev->SetRenderState(D3DRS_COLORWRITEENABLE, 0x0000000F); m_D3DDev->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE); if( m_State->m_Caps.PrimitiveMiscCaps & D3DPMISCCAPS_SEPARATEALPHABLEND ) m_D3DDev->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, FALSE); //if( m_State->m_Caps.LineCaps & D3DLINECAPS_ANTIALIAS ) m_D3DDev->SetRenderState(D3DRS_ANTIALIASEDLINEENABLE, FALSE); m_D3DDev->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); m_D3DDev->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); m_D3DDev->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); m_D3DDev->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); m_D3DDev->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); m_D3DDev->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, D3DTSS_TCI_PASSTHRU); m_D3DDev->SetTextureStageState(0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE); m_D3DDev->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP); m_D3DDev->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP); m_D3DDev->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT); m_D3DDev->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT); m_D3DDev->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_NONE); m_D3DDev->SetVertexShader(NULL); m_D3DDev->SetPixelShader(NULL); } // --------------------------------------------------------------------------- void CTwGraphDirect3D9::EndDraw() { assert(m_Drawing==true); m_Drawing = false; // restore context if( !m_PureDevice ) m_State->Restore(); /* _glPolygonMode(GL_FRONT, m_PrevPolygonMode[0]); _glPolygonMode(GL_BACK, m_PrevPolygonMode[1]); _glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, m_PrevTexEnv); _glLineWidth(m_PrevLineWidth); _glMatrixMode(GL_PROJECTION); _glPopMatrix(); _glMatrixMode(GL_MODELVIEW); _glPopMatrix(); _glMatrixMode(GL_TEXTURE); _glPopMatrix(); _glPopClientAttrib(); _glPopAttrib(); */ } // --------------------------------------------------------------------------- bool CTwGraphDirect3D9::IsDrawing() { return m_Drawing; } // --------------------------------------------------------------------------- void CTwGraphDirect3D9::Restore() { UnbindFont(m_D3DDev, m_FontD3DTex); m_FontD3DTex = NULL; m_FontTex = NULL; } // --------------------------------------------------------------------------- void CTwGraphDirect3D9::DrawLine(int _X0, int _Y0, int _X1, int _Y1, color32 _Color0, color32 _Color1, bool _AntiAliased) { assert(m_Drawing==true); struct CVtx { float m_Pos[4]; DWORD m_Color; }; CVtx p[2]; p[0].m_Pos[0] = (float)_X0; p[0].m_Pos[1] = (float)_Y0; p[0].m_Pos[2] = 0; p[0].m_Pos[3] = 0; p[0].m_Color = _Color0; p[1].m_Pos[0] = (float)_X1; p[1].m_Pos[1] = (float)_Y1; p[1].m_Pos[2] = 0; p[1].m_Pos[3] = 0; p[1].m_Color = _Color1; //if( m_State->m_Caps.LineCaps & D3DLINECAPS_ANTIALIAS ) m_D3DDev->SetRenderState(D3DRS_ANTIALIASEDLINEENABLE, (_AntiAliased ? TRUE : FALSE)); m_D3DDev->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_DISABLE); m_D3DDev->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE); m_D3DDev->SetFVF(D3DFVF_XYZRHW|D3DFVF_DIFFUSE); m_D3DDev->DrawPrimitiveUP(D3DPT_LINELIST, 1, p, sizeof(CVtx)); //if( m_State->m_Caps.LineCaps & D3DLINECAPS_ANTIALIAS ) m_D3DDev->SetRenderState(D3DRS_ANTIALIASEDLINEENABLE, FALSE); } // --------------------------------------------------------------------------- void CTwGraphDirect3D9::DrawRect(int _X0, int _Y0, int _X1, int _Y1, color32 _Color00, color32 _Color10, color32 _Color01, color32 _Color11) { assert(m_Drawing==true); // border adjustment if(_X0<_X1) ++_X1; else if(_X0>_X1) ++_X0; if(_Y0<_Y1) ++_Y1; else if(_Y0>_Y1) ++_Y0; struct CVtx { float m_Pos[4]; DWORD m_Color; }; CVtx p[4]; p[0].m_Pos[0] = (float)_X1; p[0].m_Pos[1] = (float)_Y0; p[0].m_Pos[2] = 0; p[0].m_Pos[3] = 1; p[0].m_Color = _Color10; p[1].m_Pos[0] = (float)_X0; p[1].m_Pos[1] = (float)_Y0; p[1].m_Pos[2] = 0; p[1].m_Pos[3] = 1; p[1].m_Color = _Color00; p[2].m_Pos[0] = (float)_X1; p[2].m_Pos[1] = (float)_Y1; p[2].m_Pos[2] = 0; p[2].m_Pos[3] = 1; p[2].m_Color = _Color11; p[3].m_Pos[0] = (float)_X0; p[3].m_Pos[1] = (float)_Y1; p[3].m_Pos[2] = 0; p[3].m_Pos[3] = 1; p[3].m_Color = _Color01; m_D3DDev->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_DISABLE); m_D3DDev->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE); m_D3DDev->SetFVF(D3DFVF_XYZRHW|D3DFVF_DIFFUSE); m_D3DDev->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, p, sizeof(CVtx)); } // --------------------------------------------------------------------------- void *CTwGraphDirect3D9::NewTextObj() { return new CTextObj; } // --------------------------------------------------------------------------- void CTwGraphDirect3D9::DeleteTextObj(void *_TextObj) { assert(_TextObj!=NULL); delete static_cast(_TextObj); } // --------------------------------------------------------------------------- void CTwGraphDirect3D9::BuildText(void *_TextObj, const std::string *_TextLines, color32 *_LineColors, color32 *_LineBgColors, int _NbLines, const CTexFont *_Font, int _Sep, int _BgWidth) { assert(m_Drawing==true); assert(_TextObj!=NULL); assert(_Font!=NULL); if( _Font != m_FontTex ) { UnbindFont(m_D3DDev, m_FontD3DTex); m_FontD3DTex = BindFont(m_D3DDev, _Font); m_FontTex = _Font; } CTextObj *TextObj = static_cast(_TextObj); TextObj->m_TextVerts.resize(0); TextObj->m_BgVerts.resize(0); TextObj->m_LineColors = (_LineColors!=NULL); TextObj->m_LineBgColors = (_LineBgColors!=NULL); int x, x1, y, y1, i, Len; unsigned char ch; const unsigned char *Text; color32 LineColor = COLOR32_RED; CTextVtx Vtx; Vtx.m_Pos[2] = 0; Vtx.m_Pos[3] = 1; CBgVtx BgVtx; BgVtx.m_Pos[2] = 0; BgVtx.m_Pos[3] = 1; for( int Line=0; Line<_NbLines; ++Line ) { x = 0; y = Line * (_Font->m_CharHeight+_Sep); y1 = y+_Font->m_CharHeight; Len = (int)_TextLines[Line].length(); Text = (const unsigned char *)(_TextLines[Line].c_str()); if( _LineColors!=NULL ) LineColor = _LineColors[Line]; for( i=0; im_CharWidth[ch]; Vtx.m_Color = LineColor; Vtx.m_Pos[0] = (float)x; Vtx.m_Pos[1] = (float)y; Vtx.m_UV [0] = _Font->m_CharU0[ch]; Vtx.m_UV [1] = _Font->m_CharV0[ch]; TextObj->m_TextVerts.push_back(Vtx); Vtx.m_Pos[0] = (float)x1; Vtx.m_Pos[1] = (float)y; Vtx.m_UV [0] = _Font->m_CharU1[ch]; Vtx.m_UV [1] = _Font->m_CharV0[ch]; TextObj->m_TextVerts.push_back(Vtx); Vtx.m_Pos[0] = (float)x; Vtx.m_Pos[1] = (float)y1; Vtx.m_UV [0] = _Font->m_CharU0[ch]; Vtx.m_UV [1] = _Font->m_CharV1[ch]; TextObj->m_TextVerts.push_back(Vtx); Vtx.m_Pos[0] = (float)x1; Vtx.m_Pos[1] = (float)y; Vtx.m_UV [0] = _Font->m_CharU1[ch]; Vtx.m_UV [1] = _Font->m_CharV0[ch]; TextObj->m_TextVerts.push_back(Vtx); Vtx.m_Pos[0] = (float)x1; Vtx.m_Pos[1] = (float)y1; Vtx.m_UV [0] = _Font->m_CharU1[ch]; Vtx.m_UV [1] = _Font->m_CharV1[ch]; TextObj->m_TextVerts.push_back(Vtx); Vtx.m_Pos[0] = (float)x; Vtx.m_Pos[1] = (float)y1; Vtx.m_UV [0] = _Font->m_CharU0[ch]; Vtx.m_UV [1] = _Font->m_CharV1[ch]; TextObj->m_TextVerts.push_back(Vtx); x = x1; } if( _BgWidth>0 && Len>0 ) { if( _LineBgColors!=NULL ) BgVtx.m_Color = _LineBgColors[Line]; else BgVtx.m_Color = COLOR32_BLACK; BgVtx.m_Pos[0] = -1; BgVtx.m_Pos[1] = (float)y; TextObj->m_BgVerts.push_back(BgVtx); BgVtx.m_Pos[0] = (float)(_BgWidth+1); BgVtx.m_Pos[1] = (float)y; TextObj->m_BgVerts.push_back(BgVtx); BgVtx.m_Pos[0] = -1; BgVtx.m_Pos[1] = (float)y1; TextObj->m_BgVerts.push_back(BgVtx); BgVtx.m_Pos[0] = (float)(_BgWidth+1); BgVtx.m_Pos[1] = (float)y; TextObj->m_BgVerts.push_back(BgVtx); BgVtx.m_Pos[0] = (float)(_BgWidth+1); BgVtx.m_Pos[1] = (float)y1; TextObj->m_BgVerts.push_back(BgVtx); BgVtx.m_Pos[0] = -1; BgVtx.m_Pos[1] = (float)y1; TextObj->m_BgVerts.push_back(BgVtx); } } } // --------------------------------------------------------------------------- void CTwGraphDirect3D9::DrawText(void *_TextObj, int _X, int _Y, color32 _Color, color32 _BgColor) { assert(m_Drawing==true); assert(_TextObj!=NULL); CTextObj *TextObj = static_cast(_TextObj); float x = (float)_X; float y = (float)_Y; int nv = (int)TextObj->m_TextVerts.size(); if( nv<4 ) return; // no character to draw int i; int nb = (int)TextObj->m_BgVerts.size(); if( nb>=4 ) { for( i=0; im_BgVerts[i].m_Pos[0] += x; TextObj->m_BgVerts[i].m_Pos[1] += y; if( _BgColor!=0 || !TextObj->m_LineBgColors ) TextObj->m_BgVerts[i].m_Color = _BgColor; } m_D3DDev->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_DISABLE); m_D3DDev->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE); m_D3DDev->SetFVF(D3DFVF_XYZRHW|D3DFVF_DIFFUSE); m_D3DDev->DrawPrimitiveUP(D3DPT_TRIANGLELIST, nb/3, &(TextObj->m_BgVerts[0]), sizeof(CBgVtx)); for( i=0; im_BgVerts[i].m_Pos[0] -= x; TextObj->m_BgVerts[i].m_Pos[1] -= y; } } for( i=0; im_TextVerts[i].m_Pos[0] += x; TextObj->m_TextVerts[i].m_Pos[1] += y; } if( _Color!=0 || !TextObj->m_LineColors ) for( i=0; im_TextVerts[i].m_Color = _Color; m_D3DDev->SetTexture(0, m_FontD3DTex); m_D3DDev->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); m_D3DDev->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); m_D3DDev->SetFVF(D3DFVF_XYZRHW|D3DFVF_DIFFUSE|D3DFVF_TEX1|D3DFVF_TEXCOORDSIZE2(0)); m_D3DDev->DrawPrimitiveUP(D3DPT_TRIANGLELIST, nv/3, &(TextObj->m_TextVerts[0]), sizeof(CTextVtx)); for( i=0; im_TextVerts[i].m_Pos[0] -= x; TextObj->m_TextVerts[i].m_Pos[1] -= y; } } // ---------------------------------------------------------------------------