#define D3D_OVERLOADS #include #include #include #include "PUBLIB2\winutil.h" #include "D3DRenderer.h" ////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////// // ------------CRenderer-------------- ////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////// #define INIT_DIRECTDRAW_STRUCT(x) (ZeroMemory(&x, sizeof(x)), x.dwSize=sizeof(x)) void InitColorConversionFunctions(); BOOL ConvertColorFormat(BYTE* psrc, COLORFORMAT src_format,BYTE* pdst,DWORD dst_pitch,COLORFORMAT dst_format,SIZE roi,DWORD scale_factor); BOOL ReleaseSurfacePointer(LPDIRECTDRAWSURFACE7 pDDSurface); static D3DTLVERTEX normalface[4]={ D3DTLVERTEX(D3DVECTOR( 0,1024,0.9f),0.1f,0xFFFFFFFF,0x00000000,0.0f,1.0f), D3DTLVERTEX(D3DVECTOR( 0, 0,0.9f),0.1f,0xFFFFFFFF,0x00000000,0.0f,0.0f), D3DTLVERTEX(D3DVECTOR(1024,1024,0.9f),0.1f,0xFFFFFFFF,0x00000000,1.0f,1.0f), D3DTLVERTEX(D3DVECTOR(1024, 0,0.9f),0.1f,0xFFFFFFFF,0x00000000,1.0f,0.0f), }; BOOL WINAPI CD3DRenderer::AdapterEnumCallbackWrapper( GUID* pGUID, LPSTR strDesc,LPSTR strName, VOID* lpContext, HMONITOR hmonitor) { return ((CD3DRenderer*)lpContext)->AdapterEnumCallback(pGUID,strDesc,strName,hmonitor); } LPDIRECTDRAWSURFACE7 g_tempTexture; void CD3DRenderer::MakeStateBlock() { for( UINT which=0; which<2; which++ ){ m_pd3dDevice->BeginStateBlock(); m_pd3dDevice->SetTexture( 0, NULL);//g_tempTexture); m_pd3dDevice->SetRenderState( D3DRENDERSTATE_ALPHABLENDENABLE, TRUE ); m_pd3dDevice->SetRenderState( D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA ); m_pd3dDevice->SetRenderState( D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCALPHA ); m_pd3dDevice->SetRenderState( D3DRENDERSTATE_ALPHATESTENABLE, TRUE ); m_pd3dDevice->SetRenderState( D3DRENDERSTATE_ALPHAREF, 0x08 ); m_pd3dDevice->SetRenderState( D3DRENDERSTATE_ALPHAFUNC, D3DCMP_GREATEREQUAL ); m_pd3dDevice->SetRenderState( D3DRENDERSTATE_FILLMODE, D3DFILL_SOLID ); m_pd3dDevice->SetRenderState( D3DRENDERSTATE_CULLMODE, D3DCULL_CCW ); m_pd3dDevice->SetRenderState( D3DRENDERSTATE_ZENABLE, TRUE ); // m_pd3dDevice->SetRenderState( D3DRENDERSTATE_ZENABLE, TRUE ); m_pd3dDevice->SetRenderState( D3DRENDERSTATE_STENCILENABLE, FALSE ); m_pd3dDevice->SetRenderState( D3DRENDERSTATE_CLIPPING, TRUE ); m_pd3dDevice->SetRenderState( D3DRENDERSTATE_EDGEANTIALIAS, FALSE ); m_pd3dDevice->SetRenderState( D3DRENDERSTATE_CLIPPLANEENABLE, FALSE ); m_pd3dDevice->SetRenderState( D3DRENDERSTATE_VERTEXBLEND, FALSE ); //ÀÌ ÆĶó¹ÌÅÍ´Â ¾ø´Â°Í °°´Ù. //m_pd3dDevice->SetRenderState( D3DRENDERSTATE_INDEXEDVERTEXBLENDENABLE, FALSE ); m_pd3dDevice->SetRenderState( D3DRENDERSTATE_FOGENABLE, FALSE ); m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE ); m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE ); m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE ); m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE ); m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE ); m_pd3dDevice->SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTFN_LINEAR ); m_pd3dDevice->SetTextureStageState( 0, D3DTSS_MAGFILTER, D3DTFG_LINEAR ); m_pd3dDevice->SetTextureStageState( 0, D3DTSS_MIPFILTER, D3DTFP_NONE); m_pd3dDevice->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, 0 ); m_pd3dDevice->SetTextureStageState( 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE ); m_pd3dDevice->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_DISABLE ); m_pd3dDevice->SetTextureStageState( 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE ); if( which==0 ) m_pd3dDevice->EndStateBlock( &m_dwSavedStateBlock ); else m_pd3dDevice->EndStateBlock( &m_dwDrawTextStateBlock ); } } #define OutRefrenceCount(c) if(c){c->AddRef();UINT count=c->Release();TRACE(#c":RefCount:%d\n",count);}else{TRACE(#c":RefCount: is NULL\n");} BOOL CD3DRenderer::AdapterEnumCallback( GUID* pGUID, LPSTR strDesc,LPSTR strName, HMONITOR hmonitor) { HRESULT hr; LPDIRECT3D7 pD3D = NULL; LPDIRECTDRAW7 pDD = NULL; if(!FAILED(hr = DirectDrawCreateEx( pGUID, (VOID**)&pDD, IID_IDirectDraw7, NULL ))){ if(!FAILED(hr = pDD->QueryInterface( IID_IDirect3D7, (VOID**)&pD3D ))){ //strncpy(driver_info.strVGADesc,strDesc,39);//<== //driver_info.guidDriver=(*pGUID);//<== pDD->SetCooperativeLevel( NULL, DDSCL_NORMAL ); LPDIRECTDRAWSURFACE7 pddsPrimary = NULL; LPDIRECT3DDEVICE7 pd3dDevice = NULL; LPDIRECTDRAWSURFACE7 pddsTexture = NULL; LPDIRECTDRAWSURFACE7 pddsBackBuffer = NULL; ///create major objects.. pddsPrimary = CreateCustomSurface(pDD,SURFACETYPE_PRIMARY,NULL,0,0); pddsBackBuffer = CreateCustomSurface(pDD,SURFACETYPE_3DCANVAS,&pd3dDevice,0,0); DDPIXELFORMAT pixelFormat; if(m_colorformat==CF_BGR565)pixelFormat=DDPF_RGB565; else if(m_colorformat==CF_BGR555)pixelFormat=DDPF_RGB555; else if(m_colorformat==CF_BGRX)pixelFormat=DDPF_RGB32; LPDIRECTDRAWSURFACE7 pddsTextures[8]={0,0,0,0,0,0,0,0}; pddsTextures[0]=CreateCustomSurface(pDD,SURFACETYPE_AGPTEXTURE,&pixelFormat, 256, 128); pddsTextures[1]=CreateCustomSurface(pDD,SURFACETYPE_AGPTEXTURE,&pixelFormat, 256, 256); pddsTextures[2]=CreateCustomSurface(pDD,SURFACETYPE_AGPTEXTURE,&pixelFormat, 512, 128); pddsTextures[3]=CreateCustomSurface(pDD,SURFACETYPE_AGPTEXTURE,&pixelFormat, 512, 256); pddsTextures[4]=CreateCustomSurface(pDD,SURFACETYPE_AGPTEXTURE,&pixelFormat, 512, 512); pddsTextures[5]=CreateCustomSurface(pDD,SURFACETYPE_AGPTEXTURE,&pixelFormat,1024, 256); pddsTextures[6]=CreateCustomSurface(pDD,SURFACETYPE_AGPTEXTURE,&pixelFormat,1024, 512); pddsTextures[7]=CreateCustomSurface(pDD,SURFACETYPE_AGPTEXTURE,&pixelFormat,1024,1024); if(pddsTextures[7] ==NULL){ m_bAgpSupported=FALSE; pddsTexture = CreateCustomSurface(pDD,SURFACETYPE_VIDMEMTEXTURE,&pixelFormat,1024,1024); if(pddsTexture ==NULL){ pddsTexture = CreateCustomSurface(pDD,SURFACETYPE_VIDMEMTEXTURE,&DDPF_RGB32,1024,1024); if(pddsTexture){ m_colorformat=CF_BGRX; } } }else{ m_bAgpSupported=TRUE; } //if(pddsTexture==NULL){ //é©error ó¸®ÇÒ°Í.. // MessageBox(NULL,"Failed to create D3D Objects","D3DRenderer Error",MB_OK); //} if(pddsPrimary!=NULL && pddsBackBuffer!=NULL && pd3dDevice!=NULL && (pddsTexture!=NULL ||m_bAgpSupported)){ //¸ðµç ¿ÀºêÁ§Æ® »ý¼º¿¡ ¼º°øÇÏ¿´´Ù.. m_pDD = pDD; m_pD3D = pD3D; m_pddsPrimary = pddsPrimary; m_pd3dDevice = pd3dDevice; m_pddsTexture = pddsTexture; m_pddsBackbuffer= pddsBackBuffer; m_pDD->CreateClipper(0,&m_pcClipper,NULL); pddsPrimary->SetClipper( m_pcClipper ); if(m_bAgpSupported){ CopyMemory(m_pddsTextures,pddsTextures,sizeof(m_pddsTextures)); } pd3dDevice->Clear(0,NULL,D3DCLEAR_TARGET |D3DCLEAR_ZBUFFER,0,1.0f,0); //GET DRIVER'S MONITOR INFO.. if(hmonitor==NULL){ m_rcMonitor.left=0; m_rcMonitor.top=0; m_rcMonitor.right=::GetSystemMetrics(SM_CXSCREEN); m_rcMonitor.bottom=::GetSystemMetrics(SM_CYSCREEN); }else{ MONITORINFO mi; mi.cbSize=sizeof(mi); GetMonitorInfo(hmonitor,&mi); m_rcMonitor = mi.rcMonitor; m_hMonitor = hmonitor; } m_bSetup = TRUE; return 0;//stop enumerate.. } SAFE_RELEASE(pddsPrimary); SAFE_RELEASE(pd3dDevice); SAFE_RELEASE(pddsTexture); SAFE_RELEASE(pddsBackBuffer); pD3D->Release(); } pDD->Release(); } //ÇØ´ç guid·Î ¿ÀºêÁ§Æ®µéÀ» »ý¼ºÇÒ ¼ö ¾ø´Ù. return D3DENUMRET_OK; } CD3DRenderer::CD3DRenderer():m_colorformat() { m_pDD = 0; m_pd3dDevice = 0; m_pddsTexture = 0; m_pddsPrimary = 0; m_pD3D = 0; m_pddsBackbuffer= 0; m_pcClipper = 0;//·»´õ·¯ ¸¶´Ù º°µµ·Î °¡Áö°í ÀÖÀ»°ÍÀÎÁö °áÁ¤ÇÒ°Í.. m_Th =1024; m_Tw =1024; ZeroMemory(m_pddsTextures,sizeof(m_pddsTextures)); m_colorformat = CF_NOTDEFINED; m_pixelbyte = 0; m_bAgpSupported=FALSE; ZeroMemory(&m_MonitorSize,sizeof(SIZE)); //==> pixel size; m_hMonitor=0; ZeroMemory(&m_rcMonitor,sizeof(RECT)); m_bIsInited=FALSE; D3DTLVERTEX nfBase[1]={D3DTLVERTEX(D3DVECTOR( 0,0,0.9f),0.1f,0xFFFFFFFF,0x00000000,0.0f,0.0f)}; m_nf=new D3DTLVERTEX[0x4000]; for(int i=0;i<0x4000;i++){ m_nf[i]=nfBase[0]; } InitializeCriticalSection(&m_crit); InitColorConversionFunctions(); } CD3DRenderer::~CD3DRenderer() { Endup(); DeleteCriticalSection(&m_crit); delete m_nf; } #ifndef SAFE_RELEASE2 #define SAFE_RELEASE2(c) if(c){UINT count=c->Release();c=NULL;TRACE("RefCount After Release:"#c":%d\n",count);}else{} #endif HRESULT WINAPI EnumSurfacesCallback2( LPDIRECTDRAWSURFACE7 lpDDSurface, LPDDSURFACEDESC2 lpDDSurfaceDesc, LPVOID lpContext ) { LPDIRECTDRAWSURFACE7* lppSurf=(LPDIRECTDRAWSURFACE7* )lpContext; *lppSurf=lpDDSurface; return DDENUMRET_CANCEL; } BOOL CD3DRenderer::Endup() { SAFE_RELEASE2(m_pd3dDevice); if(m_pddsBackbuffer){ LPDIRECTDRAWSURFACE7 lpAttachedSurf; m_pddsBackbuffer->EnumAttachedSurfaces(&lpAttachedSurf,EnumSurfacesCallback2); m_pddsBackbuffer->DeleteAttachedSurface(0,lpAttachedSurf); SAFE_RELEASE2(lpAttachedSurf); } SAFE_RELEASE2(m_pddsBackbuffer); if(m_pddsPrimary){ m_pddsPrimary->SetClipper(NULL); } SAFE_RELEASE2(m_pddsPrimary); SAFE_RELEASE2(m_pcClipper); if(m_bAgpSupported){ for(int i=0;i<8;i++){ SAFE_RELEASE2(m_pddsTextures[i]); } }else{ SAFE_RELEASE2(m_pddsTexture); } SAFE_RELEASE2(m_pDD); SAFE_RELEASE2(m_pD3D); //SAFE_RELEASE(m_pddsTexture2); TRACE("CD3DRenderer::Endup()\n"); return TRUE; } BOOL CD3DRenderer::Setup(COLORFORMAT renderer_color_format) { m_bSetup=FALSE; TRACE("CD3DRenderer::Setup()\n"); //check color format first.. //24bit rgb is not supported. if((renderer_color_format!=CF_BGR565) && (renderer_color_format!=CF_BGR555) && (renderer_color_format!=CF_BGRX) ) return FALSE; m_colorformat=renderer_color_format; DirectDrawEnumerateEx( CD3DRenderer::AdapterEnumCallbackWrapper, this, DDENUM_ATTACHEDSECONDARYDEVICES | DDENUM_DETACHEDSECONDARYDEVICES | DDENUM_NONDISPLAYDEVICES ); return m_bSetup; } void CD3DRenderer::SetVertexColorValue(int indexFrom,int indexTo,DWORD colorValue) { for(int i=indexFrom;iSetTexture( 0, NULL); m_pd3dDevice->SetRenderState( D3DRENDERSTATE_ALPHABLENDENABLE, TRUE ); m_pd3dDevice->SetRenderState( D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA ); m_pd3dDevice->SetRenderState( D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCALPHA ); m_pd3dDevice->SetRenderState( D3DRENDERSTATE_ALPHATESTENABLE, TRUE ); m_pd3dDevice->SetRenderState( D3DRENDERSTATE_ALPHAREF, 0x08 ); m_pd3dDevice->SetRenderState( D3DRENDERSTATE_ALPHAFUNC, D3DCMP_GREATEREQUAL ); m_pd3dDevice->SetRenderState( D3DRENDERSTATE_FILLMODE, D3DFILL_SOLID ); m_pd3dDevice->SetRenderState( D3DRENDERSTATE_CULLMODE, D3DCULL_CCW ); m_pd3dDevice->SetRenderState( D3DRENDERSTATE_ZENABLE, TRUE ); } BOOL CD3DRenderer::DrawRecords(RECT tr,D3DVALUE zValue,ULONG nRecords,DrawRecord* pRecords) { //RECT trOrg=tr; OffsetRect(&tr,-m_rcMonitor.left,-m_rcMonitor.top); ULONG lastz=0; m_pd3dDevice->BeginScene(); EnterCriticalSection(&m_crit); //m_pd3dDevice->Clear(0,NULL,D3DCLEAR_ZBUFFER ,0,1.0,0); for(ULONG i=0;idrawType){ case DRT_IMAGE://image { BYTE * pSurf; DWORD pitch; int scale_factor = 1; //±³Â÷¿µ¿ª üũ.. //clip ¿µ¿ª üũ.. if((tr.right-tr.left<=(pRecords->srcSize.cx/2)) && (tr.bottom-tr.top<=(pRecords->srcSize.cy/2)) &&(pRecords->srcSize.cx%16 == 0)) scale_factor=2; RECT surfRc={0,0,pRecords->srcSize.cx/scale_factor,pRecords->srcSize.cy/scale_factor}; if(GetSurfacePointer(&surfRc,&pSurf,&pitch)){ ConvertColorFormat(pRecords->img.pSrc,pRecords->img.colorFormat,pSurf,pitch,m_colorformat,pRecords->srcSize,scale_factor); SIZE source = pRecords->srcSize; if(scale_factor==2){ source.cx/=2; source.cy/=2; } ReleaseSurfacePointer(); m_pd3dDevice->SetRenderState( D3DRENDERSTATE_ALPHABLENDENABLE, FALSE ); RECT src={0,0,source.cx,source.cy}; if(pRecords->img.flag){ if(scale_factor==2){ src.left=pRecords->img.roi.left/2; src.right=pRecords->img.roi.right/2; src.top=pRecords->img.roi.top/2; src.bottom=pRecords->img.roi.bottom/2; }else{ src=pRecords->img.roi; } } DrawImageTexture(tr,src,pRecords->colorValue,zValue); } } break; case DRT_TEXT://text { if(pRecords->text.pText && pRecords->text.pFont && pRecords->text.pText[0]){ int trW=tr.right-tr.left; int trH=tr.bottom-tr.top; int srW=pRecords->srcSize.cx; int srH=pRecords->srcSize.cy; POINT pt=pRecords->text.pt; pt.x=pt.x*trW/srW +tr.left; pt.y=pt.y*trH/srH +tr.top; pRecords->text.pFont->DrawText((float)pt.x,(float)pt.y,tr,pRecords->colorValue,pRecords->text.pText); } } break; case DRT_RECTLIST://Primitives.. { //DrawPrimitive... RECT *pRc=pRecords->rects.rects; int trW=tr.right-tr.left; int trH=tr.bottom-tr.top; int srW=pRecords->srcSize.cx; int srH=pRecords->srcSize.cy; ULONG n=0; for(ULONG i=0;irects.nRect;i++){ //clip rect.. RECT rc=*pRc; if(rc.left< 0) rc.left= 0; if(rc.top< 0) rc.top= 0; if(rc.right> pRecords->srcSize.cx) rc.right= pRecords->srcSize.cx; if(rc.bottom> pRecords->srcSize.cy) rc.bottom=pRecords->srcSize.cy; m_nf[n+0].dvSX=(float)(rc.left * trW/srW + tr.left); m_nf[n+0].dvSY=(float)(rc.top * trH/srH + tr.top); m_nf[n+1].dvSX=(float)(rc.right * trW/srW + tr.left); m_nf[n+1].dvSY=(float)(rc.bottom* trH/srH + tr.top); m_nf[n+2].dvSX=(float)(rc.left * trW/srW + tr.left); m_nf[n+2].dvSY=(float)(rc.bottom* trH/srH + tr.top); m_nf[n+3].dvSX=(float)(rc.left * trW/srW + tr.left); m_nf[n+3].dvSY=(float)(rc.top * trH/srH + tr.top); m_nf[n+4].dvSX=(float)(rc.right * trW/srW + tr.left); m_nf[n+4].dvSY=(float)(rc.top * trH/srH + tr.top); m_nf[n+5].dvSX=(float)(rc.right * trW/srW + tr.left); m_nf[n+5].dvSY=(float)(rc.bottom* trH/srH + tr.top); n+=6; pRc++; } SetVertexColorValue(0,n,pRecords->colorValue); SetVertexZValue(lastz,n,zValue); if(n>lastz)lastz=n; EnableAlpha(); m_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, D3DFVF_TLVERTEX, m_nf, n, NULL ); } break; case DRT_POINTLIST: case DRT_LINELIST: case DRT_LINESTRIP: { //DrawPrimitive... POINT *pPt=pRecords->pts.pts; int trW=tr.right-tr.left; int trH=tr.bottom-tr.top; int srW=pRecords->srcSize.cx; int srH=pRecords->srcSize.cy; ULONG n=0; for(ULONG i=0;ipts.nPt;i++){ //clip rect.. POINT pt=*pPt; if(pt.x< 0) pt.x= 0; if(pt.y< 0) pt.y= 0; if(pt.x> pRecords->srcSize.cx) pt.x= pRecords->srcSize.cx; if(pt.y> pRecords->srcSize.cy) pt.y =pRecords->srcSize.cy; m_nf[n].dvSX=(float)(pt.x * trW/srW + tr.left); m_nf[n].dvSY=(float)(pt.y * trH/srH + tr.top); n++; pPt++; } SetVertexColorValue(0,n,pRecords->colorValue); SetVertexZValue(lastz,n,zValue); if(n>lastz)lastz=n; EnableAlpha(); m_pd3dDevice->DrawPrimitive( (D3DPRIMITIVETYPE)pRecords->drawType, D3DFVF_TLVERTEX, m_nf, n, NULL ); } break; } pRecords++; } LeaveCriticalSection(&m_crit); m_pd3dDevice->EndScene(); return TRUE; } BOOL HasRectsNoIntersection(RECT rc1,RECT rc2) { if((rc1.right<=rc2.left)|| (rc2.right<=rc1.left)|| (rc1.bottom<=rc2.top)|| (rc2.bottom<=rc2.top))return TRUE; return FALSE; } BOOL CD3DRenderer::Commit(RECT tr) { if(HasRectsNoIntersection(tr,m_rcMonitor))return FALSE; if(m_rcMonitor.left > tr.left) tr.left = m_rcMonitor.left; if(m_rcMonitor.top > tr.top) tr.left = m_rcMonitor.top; if(m_rcMonitor.right < tr.right) tr.right = m_rcMonitor.right; if(m_rcMonitor.bottom < tr.bottom) tr.bottom = m_rcMonitor.bottom; //RECT trOrg=tr; OffsetRect(&tr,-m_rcMonitor.left,-m_rcMonitor.top); m_pddsPrimary->Blt(&tr,m_pddsBackbuffer,&tr,DDBLT_ASYNC |DDBLT_DONOTWAIT ,NULL); return TRUE; } BOOL CD3DRenderer::Clear(RECT tr) { if(HasRectsNoIntersection(tr,m_rcMonitor))return FALSE; if(m_rcMonitor.left > tr.left) tr.left = m_rcMonitor.left; if(m_rcMonitor.top > tr.top) tr.left = m_rcMonitor.top; if(m_rcMonitor.right < tr.right) tr.right = m_rcMonitor.right; if(m_rcMonitor.bottom < tr.bottom) tr.bottom = m_rcMonitor.bottom; //RECT trOrg=tr; OffsetRect(&tr,-m_rcMonitor.left,-m_rcMonitor.top); D3DRECT trD3D={tr.left,tr.top,tr.right,tr.bottom}; m_pd3dDevice->Clear(1,&trD3D,D3DCLEAR_TARGET |D3DCLEAR_ZBUFFER,RGB(0,0,0),1.0f,0); return TRUE; } BOOL CD3DRenderer::Draw(RECT target_rect,SIZE source,COLORFORMAT src_img_format,BYTE* psrc,CD3DFont* pFont,char * text,DWORD color) { #if 1 static RECT * prc; if(prc==NULL){ prc=new RECT[320*240/16/16]; } int k=0; for(int y=0;y<120/32;y++){ for(int x=0;x<160/32;x++){ if((y+x)%2){ prc[k].left=x*32; prc[k].top=y*32; prc[k].right=(x+1)*32; prc[k].bottom=(y+1)*32; k++; } } } #endif DrawRecord recs[4]; RECT rcs[2]={ {0,0,160,120},{200,200,300,220} }; recs[0].drawType = DRT_IMAGE; recs[0].colorValue = 0x30FFFFFF; recs[0].srcSize = source; recs[0].img.colorFormat= src_img_format; recs[0].img.pSrc = psrc; recs[0].img.flag = 0; recs[1].drawType = DRT_TEXT; recs[1].colorValue = 0x60F0F080;//color; recs[1].srcSize = source; recs[1].text.pFont = pFont; recs[1].text.pText = text; recs[1].text.pt.x = 0; recs[1].text.pt.y = 0; recs[2].drawType = DRT_RECTLIST; recs[2].colorValue = 0x60F0F080; recs[2].srcSize = source; recs[2].rects.nRect = k; recs[2].rects.rects = prc; recs[3].drawType = DRT_LINESTRIP; recs[3].colorValue = 0x30FF0080; recs[3].srcSize = source; recs[3].pts.nPt = k*2; recs[3].pts.pts = (POINT*)prc; DrawRecords(target_rect,0.9f,2,recs); return TRUE; } BOOL CD3DRenderer::GetSurfacePointer(RECT* prcdst,BYTE **ppSurf,DWORD * pitch) { if(prcdst){ //calcuate rect size and int w=prcdst->right; int h=prcdst->bottom; if(m_bAgpSupported){ #if 1 if (w<= 256 && h<= 128){m_pddsTexture = m_pddsTextures[0]; m_Tw= 256;m_Th= 128;} else if(w<= 256 && h<= 256){m_pddsTexture = m_pddsTextures[1]; m_Tw= 256;m_Th= 256;} else if(w<= 512 && h<= 128){m_pddsTexture = m_pddsTextures[2]; m_Tw= 512;m_Th= 128;} else if(w<= 512 && h<= 256){m_pddsTexture = m_pddsTextures[3]; m_Tw= 512;m_Th= 256;} else if(w<= 512 && h<= 512){m_pddsTexture = m_pddsTextures[4]; m_Tw= 512;m_Th= 512;} else if(w<=1024 && h<= 256){m_pddsTexture = m_pddsTextures[5]; m_Tw=1024;m_Th= 256;} else if(w<=1024 && h<= 512){m_pddsTexture = m_pddsTextures[6]; m_Tw=1024;m_Th= 512;} else {m_pddsTexture = m_pddsTextures[7]; m_Tw=1024;m_Th=1024;}//if(w<=1024 && h<=1024){ #else {m_pddsTexture = m_pddsTextures[7]; m_Tw=1024;m_Th=1024;}//if(w<=1024 && h<=1024){ #endif }else{ } } return ::GetSurfacePointer(m_pddsTexture,ppSurf,pitch,prcdst); } CD3DRenderer::ReleaseSurfacePointer() { ::ReleaseSurfacePointer(m_pddsTexture); return 0; } BOOL CD3DRenderer::DrawImageTexture(RECT t,RECT s,DWORD color,D3DVALUE zValue) { HRESULT hr; //±×¸± ¿µ¿ªÀ» ¹þ¾î³µ´ÂÁö ¾Ë¾Æº»´Ù. RECT rcMonitor={0,0,m_rcMonitor.right-m_rcMonitor.left,m_rcMonitor.bottom-m_rcMonitor.top}; if(HasRectsNoIntersection(t,rcMonitor))return FALSE; int t_width =t.right-t.left; int t_height=t.bottom-t.top; int monitor_width =rcMonitor.right-rcMonitor.left; int monitor_height=rcMonitor.bottom-rcMonitor.top; //Setup the Vertex Coordinate and Texture Coordinate int x1 = t.left -rcMonitor.left; int y1 = t.top -rcMonitor.top ; int x2 = t.right -rcMonitor.left; int y2 = t.bottom-rcMonitor.top ; int xorg=x1; int yorg=y1; //texture ÁÂÇ¥.. ÀÏ´Ü pixelÁÂÇ¥¸¦ ¾´´Ù. float u1=(float)s.left,v1=(float)s.top,u2=(float)s.right,v2=(float)s.bottom; #if 0 if(x1<0) {u1=(float)(-x1*s.cx/t_width); x1=0;} if(y1<0) {v1=(float)(-y1*s.cy/t_height); y1=0;} if(x2>monitor_width) {u2=(float)((monitor_width-x1)*s.cx/t_width); x2=monitor_width;} if(y2>monitor_height){v2=(float)((monitor_height-y1)*s.cy/t_height); x2=monitor_height;} #endif float fx1=(float)x1-0.5f; float fy1=(float)y1-0.5f; float fx2=(float)x2-0.5f; float fy2=(float)y2-0.5f; normalface[0].dvSX = fx1; normalface[0].dvSY = fy2; normalface[1].dvSX = fx1; normalface[1].dvSY = fy1; normalface[2].dvSX = fx2; normalface[2].dvSY = fy2; normalface[3].dvSX = fx2; normalface[3].dvSY = fy1; u1/=m_Tw; v1/=m_Th; u2/=m_Tw; v2/=m_Th; normalface[0].dvTU = u1; normalface[0].dvTV = v2; normalface[1].dvTU = u1; normalface[1].dvTV = v1; normalface[2].dvTU = u2; normalface[2].dvTV = v2; normalface[3].dvTU = u2; normalface[3].dvTV = v1; normalface[0].dcColor=color; normalface[1].dcColor=color; normalface[2].dcColor=color; normalface[3].dcColor=color; normalface[0].dvSZ= zValue; normalface[1].dvSZ= zValue; normalface[2].dvSZ= zValue; normalface[3].dvSZ= zValue; // Draw the front and back faces of the cube using texture 1 m_pd3dDevice->SetTexture( 0, m_pddsTexture); m_pd3dDevice->SetTextureStageState(0,D3DTSS_MINFILTER,D3DTFN_LINEAR); m_pd3dDevice->SetTextureStageState(0,D3DTSS_MAGFILTER,D3DTFG_LINEAR); hr=m_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, D3DFVF_TLVERTEX, normalface, 4, NULL ); m_pd3dDevice->SetTexture( 0, NULL); return 0; } BOOL CD3DRenderer::SetHWnd(HWND hwnd) { return m_pcClipper->SetHWnd(0,hwnd); } BOOL CD3DRenderer::MoveBackBuffer(RECT & rcNew,RECT& rcOld) { /* if(HasRectsNoIntersection(tr,m_rcMonitor))return FALSE; if(m_rcMonitor.left > tr.left) tr.left = m_rcMonitor.left; if(m_rcMonitor.top > tr.top) tr.left = m_rcMonitor.top; if(m_rcMonitor.right < tr.right) tr.right = m_rcMonitor.right; if(m_rcMonitor.bottom < tr.bottom) tr.bottom = m_rcMonitor.bottom; RECT trOrg=tr; OffsetRect(&tr,-m_rcMonitor.left,-m_rcMonitor.top); */ m_pddsBackbuffer->Blt(&rcNew,m_pddsBackbuffer,&rcOld,DDBLT_ASYNC |DDBLT_DONOTWAIT ,NULL); return TRUE; } //////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////// // ------------Utility Fuctions-------------- //////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////// BOOL ConvertColorFormat_SimpleCopy(BYTE* psrc,DWORD src_pitch,BYTE* pdst,DWORD dst_pitch,SIZE roi,DWORD pixelbyte) { DWORD line_byte=roi.cx*pixelbyte; DWORD line_word=line_byte/4; return TRUE; } #include "colorconversion.h" static void InitColorConversionFunctions() { BOOL sse2_support=IsSSE2Supported(); if(sse2_support){ cc_YUY2_To_RGB32 = YUY2_To_RGB32 ; cc_YUY2_To_RGB32_Resize_2 = YUY2_To_RGB32_Resize_2_SSE;//YUY2_To_RGB32_Resize_2; cc_YUY2_To_RGB555 = YUY2_To_RGB555 ; cc_YUY2_To_RGB555_Resize_2 = YUY2_To_RGB555_Resize_2_2; cc_YUY2_To_RGB565 = YUY2_To_RGB565 ; cc_YUY2_To_RGB565_Resize_2 = YUY2_To_RGB565_Resize_2_2; //cc_YUY2_To_RGB565_Resize_2 = YUY2_To_RGB565_Resize_2_SSE; }else{ cc_YUY2_To_RGB32 = YUY2_To_RGB32_SSE ; cc_YUY2_To_RGB32_Resize_2 = YUY2_To_RGB32_Resize_2_SSE; cc_YUY2_To_RGB555 = YUY2_To_RGB555_SSE ; cc_YUY2_To_RGB555_Resize_2 = YUY2_To_RGB555_Resize_2_SSE; cc_YUY2_To_RGB565 = YUY2_To_RGB565_SSE ; cc_YUY2_To_RGB565_Resize_2 = YUY2_To_RGB565_Resize_2_SSE; } } BOOL ConvertColorFormat(BYTE* psrc, COLORFORMAT src_format, BYTE* pdst,DWORD dst_pitch,COLORFORMAT dst_format, SIZE roi,DWORD scale_factor) { //dstÀÇ BGR565 ´Â ¸ðµÎ BGRX·Î ¹Ù²ð ¿¹Á¤ const DWORD pixel_bytes[]={0,2,4,3,2,2}; if(src_format != CF_YUY2 && src_format != CF_YV12 && src_format != CF_IYUV)return FALSE; if(src_format==dst_format && scale_factor==1){ HSH_CopySameFormatImage(pdst,psrc,dst_pitch,roi.cx,roi.cy,pixel_bytes[src_format]); }else if( dst_format == CF_YUY2 && src_format==CF_YUY2){ if(scale_factor==1){ HSH_CopyYUYVImage(pdst,psrc,dst_pitch,roi.cx,roi.cy); }else if(scale_factor==2){ HSH_CopyYUYVImageBy2(pdst,psrc,dst_pitch,roi.cx,roi.cy); }else if(scale_factor==4){ HSH_CopyYUYVImageBy4(pdst,psrc,dst_pitch,roi.cx,roi.cy); } }else if( dst_format == CF_BGR555 && src_format==CF_YUY2){ if(scale_factor==1){ cc_YUY2_To_RGB555(psrc,pdst,dst_pitch,roi.cx,roi.cy); }else if(scale_factor==2){ cc_YUY2_To_RGB555_Resize_2(psrc,pdst,dst_pitch,roi.cx,roi.cy); }else{ return FALSE; } }else if( dst_format == CF_BGR565 && src_format==CF_YUY2){ if(scale_factor==1){ cc_YUY2_To_RGB565(psrc,pdst,dst_pitch,roi.cx,roi.cy); }else if(scale_factor==2){ cc_YUY2_To_RGB565_Resize_2(psrc,pdst,dst_pitch,roi.cx,roi.cy); }else{ return FALSE; } }else if( dst_format == CF_BGRX && src_format==CF_YUY2){ if(scale_factor==1){ cc_YUY2_To_RGB32(psrc,pdst,dst_pitch,roi.cx,roi.cy); }else if(scale_factor==2){ cc_YUY2_To_RGB32_Resize_2(psrc,pdst,dst_pitch,roi.cx,roi.cy); }else{ return FALSE; } }else if( dst_format == CF_BGR565 && src_format==CF_IYUV){ //Æ÷ÀÎÅÍ¿¡ ´ëÇÑ Ãß°¡ÀûÀÎ º¯¼ö°¡ ÇÊ¿äÇÏ´Ù.. BYTE* u_src=psrc+roi.cx*roi.cy; BYTE* v_src=psrc+roi.cx*roi.cy*5/4; if(scale_factor==1){ YUY12_To_RGB565_mmx(pdst,dst_pitch,psrc,u_src,v_src,roi.cx,roi.cx/2,roi.cx,roi.cy); }else if(scale_factor==2){ YUY12_To_RGB565_mmx_resize_2(pdst,dst_pitch,psrc,u_src,v_src,roi.cx,roi.cx/2,roi.cx,roi.cy); }else{ return FALSE; } }else if( dst_format == CF_BGR565 && src_format==CF_YV12){ //Æ÷ÀÎÅÍ¿¡ ´ëÇÑ Ãß°¡ÀûÀÎ º¯¼ö°¡ ÇÊ¿äÇÏ´Ù.. BYTE* v_src=psrc+roi.cx*roi.cy; BYTE* u_src=psrc+roi.cx*roi.cy*5/4; if(scale_factor==1){ YUY12_To_RGB565_mmx(pdst,dst_pitch,psrc,u_src,v_src,roi.cx,roi.cx/2,roi.cx,roi.cy); }else if(scale_factor==2){ YUY12_To_RGB565_mmx_resize_2(pdst,dst_pitch,psrc,u_src,v_src,roi.cx,roi.cx/2,roi.cx,roi.cy); }else{ return FALSE; } } return TRUE; } static DDPIXELFORMAT DDPF_RGBA16={ sizeof(DDPIXELFORMAT), DDPF_RGB|DDPF_ALPHAPIXELS , 0, 16, 0x00000F00,0x000000F0,0x0000000F,0x0000F000, }; static DDPIXELFORMAT DDPF_RGB32={ sizeof(DDPIXELFORMAT), DDPF_RGB, 0, 32, 0x00FF0000,0x0000FF00,0x000000FF,0x00000000, }; static DDPIXELFORMAT DDPF_RGB24={ sizeof(DDPIXELFORMAT), DDPF_RGB, 0, 24, 0x00FF0000,0x0000FF00,0x000000FF,0x00000000, }; static DDPIXELFORMAT DDPF_RGB565={ sizeof(DDPIXELFORMAT), DDPF_RGB, 0, 16, 0x0000F800,0x000007E0,0x0000001F,0x00000000, }; static DDPIXELFORMAT DDPF_RGB555={ sizeof(DDPIXELFORMAT), DDPF_RGB, 0, 16, 0x00007C00,0x000003E0,0x0000001F,0x00000000, }; static DDPIXELFORMAT DDPF_YUY2= { sizeof(DDPIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('Y','U','Y','2'), 0, 0,0,0,0 }; LPVOID GetSurfacePointer(LPDIRECTDRAWSURFACE7 psurf) { DDSURFACEDESC2 desc={0,}; desc.dwSize=sizeof(desc); psurf->Lock(NULL,&desc,DDLOCK_WAIT ,NULL); return desc.lpSurface; } BOOL GetSurfacePointer(LPDIRECTDRAWSURFACE7 pDDSurface,BYTE **ppSurf, DWORD* pitch,LPRECT prect) { HRESULT hRet; DDSURFACEDESC2 ddsd; //HRESULT isLost = pDDSurface->IsLost(); // Lock down the surface so we can modify it's contents. INIT_DIRECTDRAW_STRUCT(ddsd); //if(time_interval<5500000) hRet=pDDSurface->Lock( prect, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT|DDLOCK_NOSYSLOCK|DDLOCK_WRITEONLY, NULL); if (FAILED(hRet)) return FALSE; //drawÇÒ memoryÀÇ À§Ä¡¸¦ °áÁ¤ÇÑ´Ù. *ppSurf = (BYTE*)ddsd.lpSurface; *pitch = ddsd.lPitch; return TRUE; } BOOL ReleaseSurfacePointer(LPDIRECTDRAWSURFACE7 pDDSurface) { pDDSurface->Unlock(NULL); return TRUE; } static HRESULT WINAPI EnumZBufferCallback( DDPIXELFORMAT* pddpf, VOID* pddpfDesired ) { // For this tutorial, we are only interested in z-buffers, so ignore any // other formats (e.g. DDPF_STENCILBUFFER) that get enumerated. An app // could also check the depth of the z-buffer (16-bit, etc,) and make a // choice based on that, as well. For this tutorial, we'll take the first // one we get. if( pddpf->dwFlags == DDPF_ZBUFFER ) { memcpy( pddpfDesired, pddpf, sizeof(DDPIXELFORMAT) ); // Return with D3DENUMRET_CANCEL to end the search. return D3DENUMRET_CANCEL; } // Return with D3DENUMRET_OK to continue the search. return D3DENUMRET_OK; } //lParam is Pointer to DDPIXELFORMAT or Pointer to LPDIRECT3DDEIVCE7 LPDIRECTDRAWSURFACE7 CreateCustomSurface( LPDIRECTDRAW7 pDD,SurfaceType surfaceType,void *lpParam, DWORD dwWidth,DWORD dwHeight) { HRESULT hr; LPDIRECTDRAWSURFACE7 pddsTexture=NULL; DDSURFACEDESC2 ddsd; INIT_DIRECTDRAW_STRUCT(ddsd); switch(surfaceType){ case SURFACETYPE_AGPTEXTURE:{ ddsd.dwFlags = DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT; ddsd.dwWidth = dwWidth; ddsd.dwHeight = dwHeight; ddsd.ddpfPixelFormat = *(DDPIXELFORMAT*)lpParam; ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE|DDSCAPS_VIDEOMEMORY|DDSCAPS_NONLOCALVIDMEM; break;} case SURFACETYPE_VIDMEMTEXTURE:{ ddsd.dwFlags = DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT; ddsd.dwWidth = dwWidth; ddsd.dwHeight = dwHeight; ddsd.ddpfPixelFormat = *(DDPIXELFORMAT*)lpParam; ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE|DDSCAPS_VIDEOMEMORY|DDSCAPS_LOCALVIDMEM ; break;} case SURFACETYPE_3DCANVAS:{ DDSURFACEDESC2 ddsdesc; INIT_DIRECTDRAW_STRUCT(ddsdesc); pDD->GetDisplayMode(&ddsdesc); ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS; ddsd.ddsCaps.dwCaps = DDSCAPS_VIDEOMEMORY | DDSCAPS_3DDEVICE|DDSCAPS_LOCALVIDMEM ;//DDSCAPS_OFFSCREENPLAIN ddsd.dwWidth = ddsdesc.dwWidth; ddsd.dwHeight = ddsdesc.dwHeight; break;} case SURFACETYPE_PRIMARY:{ ddsd.dwFlags = DDSD_CAPS; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; break;} case SURFACETYPE_MANAGEDTEXTURE:{ ddsd.dwFlags = DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH|DDSD_TEXTURESTAGE|DDSD_PIXELFORMAT; ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE; ddsd.dwWidth = dwWidth; ddsd.dwHeight = dwHeight; ddsd.ddpfPixelFormat = *(DDPIXELFORMAT*)lpParam; ddsd.ddsCaps.dwCaps2 = DDSCAPS2_TEXTUREMANAGE; break;} default: return NULL; } if( FAILED( hr = pDD->CreateSurface( &ddsd, &pddsTexture, NULL ) ) ) return NULL; //special case... if(surfaceType==SURFACETYPE_3DCANVAS){ //create 3d Device.. LPDIRECT3D7 pD3D; if(!FAILED(hr = pDD->QueryInterface( IID_IDirect3D7, (VOID**)&pD3D ))){ //enumerate z buffer format.. DDPIXELFORMAT pixFormat; pD3D->EnumZBufferFormats(IID_IDirect3DHALDevice,EnumZBufferCallback,&pixFormat); DDSURFACEDESC2 ddsdesc; INIT_DIRECTDRAW_STRUCT(ddsdesc); pDD->GetDisplayMode(&ddsdesc); ddsd.dwFlags = DDSD_CAPS|DDSD_WIDTH|DDSD_HEIGHT|DDSD_PIXELFORMAT; ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER|DDSCAPS_VIDEOMEMORY; ddsd.dwWidth = ddsdesc.dwWidth; ddsd.dwHeight = ddsdesc.dwHeight; ddsd.ddpfPixelFormat= pixFormat; LPDIRECTDRAWSURFACE7 pddsZBuffer=NULL; if( FAILED( hr = pDD->CreateSurface( &ddsd, &pddsZBuffer, NULL ) ) ) return 0; if( FAILED( hr = pddsTexture->AddAttachedSurface( pddsZBuffer ) ) ) return 0; SAFE_RELEASE2(pddsZBuffer); if(!FAILED(hr = pD3D->CreateDevice(IID_IDirect3DHALDevice,pddsTexture,(LPDIRECT3DDEVICE7 * )lpParam ))){ pD3D->Release(); (*(LPDIRECT3DDEVICE7* )lpParam)->SetRenderState( D3DRENDERSTATE_ZENABLE, TRUE ); (*(LPDIRECT3DDEVICE7* )lpParam)->Clear(0,NULL,D3DCLEAR_ZBUFFER ,0,1.0,0); return pddsTexture; } pD3D->Release(); } pddsTexture->Release(); return NULL; } return pddsTexture; } //////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////// //// D3D Font.. //////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////// inline static D3DTLVERTEX InitFont2DVertex( const D3DXVECTOR4& p, D3DCOLOR color,float tu, float tv ) { D3DTLVERTEX v; v.sx = p.x; v.sy = p.y; v.sz = p.z; v.rhw = p.w; v.color = color; v.tu = tu; v.tv = tv; return v; } static DWORD GetFontAreaHeight(DWORD width,HFONT hfont,int margin_x,int margin_y) { HDC hdc=GetDC(NULL); HFONT holdfont=(HFONT)SelectObject(hdc,hfont); char str[4]; int x=0,y=0; SIZE size={0,}; for( char c=32; c<127; c++ ){ str[0] = c; GetTextExtentPoint32( hdc, str, 1, &size ); if( (DWORD)(x+size.cx+1+2) > width ){ x = 0; y += size.cy+1+margin_y; } x += size.cx+1+margin_x; } SelectObject(hdc,holdfont); ReleaseDC(NULL,hdc); return (y+ size.cy+1); } static DWORD GetTextureDimension(DWORD org_length) { if(org_length <= 128) return 128; if(org_length <= 256) return 256; if(org_length <= 512) return 512; if(org_length <= 1024) return 1024; if(org_length <= 2048) return 2048; return 0xFFFFFFFF; } #define MAX_NUM_VERTICES 50*6 BOOL CD3DFont::Setup(CD3DRenderer* renderer,const char* strFontName, DWORD dwHeight, DWORD dwFlags) { LPDIRECTDRAW7 pDD=renderer->m_pDD; m_pd3dDevice = renderer->m_pd3dDevice; m_pVB=new D3DTLVERTEX[300]; m_pd3dDevice->AddRef(); int offset_x=(char)((dwFlags>>16)&0xFF); int offset_y=(char)((dwFlags>>24)&0xFF); DWORD dwBold = (dwFlags&D3DFONT_BOLD) ? FW_BOLD : FW_NORMAL; DWORD dwItalic = (dwFlags&D3DFONT_ITALIC) ? TRUE : FALSE; DWORD dwAntiAlias= (dwFlags&D3DFONT_ANTIALIAS)?ANTIALIASED_QUALITY:NONANTIALIASED_QUALITY; HFONT hFont = CreateFont( dwHeight, 0, 0, 0, dwBold, dwItalic, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, dwAntiAlias, VARIABLE_PITCH, strFontName ); int shadowlevel=0; //no shadow--> shodow offset is ignored. if(dwFlags&D3DFONT_SHADOW_LEVEL1)shadowlevel=1; //blur 1 time. else if(dwFlags&D3DFONT_SHADOW_LEVEL2)shadowlevel=2;//blur 2 times. else if(dwFlags&D3DFONT_SHADOW_LEVEL3)shadowlevel=3;//blur 3 times. int margin_x=shadowlevel*2; int margin_y=shadowlevel*2; if(shadowlevel=50)m_dwTexWidth=512; else m_dwTexWidth=256; DWORD height=GetFontAreaHeight(m_dwTexWidth,hFont,margin_x,margin_y); if(height<=64)m_dwTexHeight=64; else if(height<=128)m_dwTexHeight=128; else if(height<=256)m_dwTexHeight=256; else if(height<=512)m_dwTexHeight=512; else if(height<=1024)m_dwTexHeight=1024; DWORD h=m_dwTexHeight; DWORD w=m_dwTexWidth; m_pTexture=CreateCustomSurface(pDD,SURFACETYPE_MANAGEDTEXTURE,&DDPF_RGBA16,w,h);//CreateRGBATexture(pDD,w,h); // Prepare to create a bitmap DWORD* pbit; BITMAPINFO bmi; ZeroMemory( &bmi.bmiHeader, sizeof(BITMAPINFOHEADER) ); bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bmi.bmiHeader.biWidth = (int)w; bmi.bmiHeader.biHeight = -(int)h; bmi.bmiHeader.biPlanes = 1; bmi.bmiHeader.biCompression = BI_RGB; bmi.bmiHeader.biBitCount = 32; // Create a DC and a bitmap for the font HDC hDC = CreateCompatibleDC( NULL ); HBITMAP hbmBitmap = CreateDIBSection( hDC, &bmi, DIB_RGB_COLORS,(VOID**)&pbit, NULL, 0 ); SetMapMode( hDC, MM_TEXT ); SelectObject( hDC, hbmBitmap ); SelectObject( hDC, hFont ); SetTextColor( hDC, RGB(255,255,255) ); SetBkColor( hDC, 0x00000000 ); SetTextAlign( hDC, TA_TOP ); //¸ÕÀú °ËÁ¤»öÀ¸·Î Ŭ¸®¾îÇÑ´Ù. ZeroMemory(pbit,w*h*4); DWORD x = 0; DWORD y = 0; SIZE size; for( char c=32; c<127; c++ ){ GetTextExtentPoint32( hDC, &c, 1, &size ); if( (DWORD)(x+size.cx+1+margin_x) > w ){ x = 0; y += size.cy+1+margin_y; } //j°¡ iÀÇ ¿µ¿ªÀ» ħ¹üÇÑ´Ù. ExtTextOut( hDC, x+1+shadowlevel, y+1+shadowlevel, ETO_OPAQUE, NULL, &c, 1, NULL ); m_fTexCoords[c-32][0] = ((float)(x+0))/w; m_fTexCoords[c-32][1] = ((float)(y+0))/h; m_fTexCoords[c-32][2] = ((float)(x+1+size.cx+margin_x))/w; m_fTexCoords[c-32][3] = ((float)(y+1+size.cy+margin_y))/h; x += size.cx+1+margin_x; } BYTE* blured=new BYTE[w*h]; for(DWORD i=0;i=(int)h)y2=h-1; for( x=0; x < w; x++ ){ int x1=x-1,x2=x+1; if(x1<0)x1=0;if(x2>=(int)w)x2=w-1; blured[ y*w+x]= ((blured[y1*w+x1]&0xFF) + (blured[y1*w+x]&0xFF) + (blured[y1*w+x2]&0xFF) + (blured[ y*w+x1]&0xFF) + (blured[ y*w+x]&0xFF) + (blured[ y*w+x2]&0xFF) + (blured[y2*w+x1]&0xFF) + (blured[y2*w+x]&0xFF) + (blured[y2*w+x2]&0xFF)+4) / 9; } } } // Lock the surface and write the alpha values for the set pixels WORD* pDst16 = (WORD*)GetSurfacePointer(m_pTexture); int bAlpha,bAlpha2; // 4-bit measure of pixel intensity int b; for( y=0; y < h; y++ ){ int y1=y-offset_y;if(y1<0)y1=0;if(y1>=(int)h)y1=h-1; for( x=0; x < w; x++ ){ int x1=x-offset_x;if(x1<0)x1=0;if(x1>=(int)w)x1=w-1; bAlpha = ((int)blured[w*y1 + x1]+7) >> 4; if(bAlpha>15)bAlpha=15; b = (BYTE)(pbit[w*y + x]&0xFF); // *pDst16++ = b == 0xFF? 0xFFFF: (WORD)((bAlpha << 12) | 0x0000); // *pDst16++ = b == 0xFF? 0xF000: (WORD)((bAlpha << 12) | 0x0FFF); int c=(b)>>4; c=c|(c<<4)|(c<<8); bAlpha2=(b)>>4; if(bAlpha2>bAlpha)bAlpha=bAlpha2; *pDst16++ = (WORD)((bAlpha << 12) | c); } } delete blured; ReleaseSurfacePointer(m_pTexture); g_tempTexture=m_pTexture; DeleteObject( hbmBitmap ); DeleteDC( hDC ); DeleteObject( hFont ); //__________________________________________________________________________________________ for( UINT which=0; which<2; which++ ){ m_pd3dDevice->BeginStateBlock(); m_pd3dDevice->SetTexture( 0, m_pTexture ); m_pd3dDevice->SetRenderState( D3DRENDERSTATE_ALPHABLENDENABLE, TRUE ); m_pd3dDevice->SetRenderState( D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA ); m_pd3dDevice->SetRenderState( D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCALPHA ); m_pd3dDevice->SetRenderState( D3DRENDERSTATE_ALPHATESTENABLE, TRUE ); m_pd3dDevice->SetRenderState( D3DRENDERSTATE_ALPHAREF, 0x08 ); m_pd3dDevice->SetRenderState( D3DRENDERSTATE_ALPHAFUNC, D3DCMP_GREATEREQUAL ); m_pd3dDevice->SetRenderState( D3DRENDERSTATE_FILLMODE, D3DFILL_SOLID ); m_pd3dDevice->SetRenderState( D3DRENDERSTATE_CULLMODE, D3DCULL_CCW ); m_pd3dDevice->SetRenderState( D3DRENDERSTATE_ZENABLE, TRUE ); // m_pd3dDevice->SetRenderState( D3DRENDERSTATE_ZENABLE, TRUE ); m_pd3dDevice->SetRenderState( D3DRENDERSTATE_STENCILENABLE, FALSE ); m_pd3dDevice->SetRenderState( D3DRENDERSTATE_CLIPPING, TRUE ); m_pd3dDevice->SetRenderState( D3DRENDERSTATE_EDGEANTIALIAS, FALSE ); m_pd3dDevice->SetRenderState( D3DRENDERSTATE_CLIPPLANEENABLE, FALSE ); m_pd3dDevice->SetRenderState( D3DRENDERSTATE_VERTEXBLEND, FALSE ); //ÀÌ ÆĶó¹ÌÅÍ´Â ¾ø´Â°Í °°´Ù. //m_pd3dDevice->SetRenderState( D3DRENDERSTATE_INDEXEDVERTEXBLENDENABLE, FALSE ); m_pd3dDevice->SetRenderState( D3DRENDERSTATE_FOGENABLE, FALSE ); m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE ); m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE ); m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE ); m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE ); m_pd3dDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE ); m_pd3dDevice->SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTFN_LINEAR ); m_pd3dDevice->SetTextureStageState( 0, D3DTSS_MAGFILTER, D3DTFG_LINEAR ); m_pd3dDevice->SetTextureStageState( 0, D3DTSS_MIPFILTER, D3DTFP_NONE); m_pd3dDevice->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, 0 ); m_pd3dDevice->SetTextureStageState( 0, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_DISABLE ); m_pd3dDevice->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_DISABLE ); m_pd3dDevice->SetTextureStageState( 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE ); if( which==0 ) m_pd3dDevice->EndStateBlock( &m_dwSavedStateBlock ); else m_pd3dDevice->EndStateBlock( &m_dwDrawTextStateBlock ); } m_State=1; return TRUE; } BOOL CD3DFont::Endup() { // Delete the state blocks if(m_State){ if( m_pd3dDevice ){ if( m_dwSavedStateBlock ) m_pd3dDevice->DeleteStateBlock( m_dwSavedStateBlock ); if( m_dwDrawTextStateBlock ) m_pd3dDevice->DeleteStateBlock( m_dwDrawTextStateBlock ); m_pd3dDevice->Release(); } m_dwSavedStateBlock = 0L; m_dwDrawTextStateBlock = 0L; SAFE_RELEASE( m_pTexture ); m_pd3dDevice = NULL; delete m_pVB; m_State=0; } return TRUE; } CD3DFont::CD3DFont():m_State(NULL) { } HRESULT CD3DFont::GetTextExtent(const char* strText, SIZE* pSize ) { if( NULL==strText || NULL==pSize ) return E_FAIL; float fRowWidth = 0.0f; float fRowHeight = (m_fTexCoords[0][3]-m_fTexCoords[0][1])*m_dwTexHeight; float fWidth = 0.0f; float fHeight = fRowHeight; while( *strText ) { char c = *strText++; if( c == '\n' ) { fRowWidth = 0.0f; fHeight += fRowHeight; } if( c < ' ' ) continue; float tx1 = m_fTexCoords[c-32][0]; float tx2 = m_fTexCoords[c-32][2]; fRowWidth += (tx2-tx1)*m_dwTexWidth; if( fRowWidth > fWidth ) fWidth = fRowWidth; } pSize->cx = (int)fWidth; pSize->cy = (int)fHeight; return S_OK; } HRESULT CD3DFont::DrawText( float sx, float sy,RECT rc, DWORD dwColor,const char* strText,int Space ) { if( m_pd3dDevice == NULL ) return E_FAIL; float sxOrg=sx; // Setup renderstate m_pd3dDevice->CaptureStateBlock( m_dwSavedStateBlock ); m_pd3dDevice->ApplyStateBlock( m_dwDrawTextStateBlock ); // Fill vertex buffer DWORD dwNumVtx = 0; D3DTLVERTEX * pVertices =m_pVB; while( *strText ){ char c = *strText++; if(c == '\n'){ sy+=(m_fTexCoords['A'-32][3]-m_fTexCoords['A'-32][1])*m_dwTexHeight; sx=sxOrg; continue; } if( c < ' ' ) continue; float *TexCoords=m_fTexCoords[c-32]; float tx1 = TexCoords[0]; float ty1 = TexCoords[1]; float tx2 = TexCoords[2];//+2.0f/m_dwTexWidth; float ty2 = TexCoords[3];//+2.0f/m_dwTexHeight ; float w = (tx2-tx1) * m_dwTexWidth ; float h = (ty2-ty1) * m_dwTexHeight ; //clip check... if(sx>=rc.left && sy>=rc.top && sx+w<=rc.right && sy+h <=rc.bottom){ *pVertices++ = InitFont2DVertex( D3DXVECTOR4(sx+0-0.5f,sy+h-0.5f,0.9f,1.0f), dwColor, tx1, ty2 ); *pVertices++ = InitFont2DVertex( D3DXVECTOR4(sx+0-0.5f,sy+0-0.5f,0.9f,1.0f), dwColor, tx1, ty1 ); *pVertices++ = InitFont2DVertex( D3DXVECTOR4(sx+w-0.5f,sy+h-0.5f,0.9f,1.0f), dwColor, tx2, ty2 ); *pVertices++ = InitFont2DVertex( D3DXVECTOR4(sx+w-0.5f,sy+0-0.5f,0.9f,1.0f), dwColor, tx2, ty1 ); *pVertices++ = InitFont2DVertex( D3DXVECTOR4(sx+w-0.5f,sy+h-0.5f,0.9f,1.0f), dwColor, tx2, ty2 ); *pVertices++ = InitFont2DVertex( D3DXVECTOR4(sx+0-0.5f,sy+0-0.5f,0.9f,1.0f), dwColor, tx1, ty1 ); dwNumVtx += 6; if( dwNumVtx > (MAX_NUM_VERTICES-6) ){ m_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, D3DFVF_TLVERTEX ,m_pVB,dwNumVtx,0 ); pVertices = m_pVB; dwNumVtx = 0L; } } sx += (w-m_def_hint+Space); } //³ª¸ÓÁö °ÍµéÀ» ±×¸°´Ù. if(dwNumVtx> 0 ){ m_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, D3DFVF_TLVERTEX ,m_pVB,dwNumVtx,0 ); } // Restore the modified renderstates m_pd3dDevice->ApplyStateBlock( m_dwSavedStateBlock ); return S_OK; }