Как известно в HGE таргеты не поддерживают альфу, по-этому все вносят изменения в двиг меняя формат
таргетов с d3dpp->BackBufferFormat на D3DFMT_A8R8G8B8.
Таргеты начинают поддерживать альфу, но всплывает следующая проблема:
при отрисовки в них полупрозрачных спрайтов сам таргет в этих местах становится полупрозрачным!
Скриншот:
создание таргета с измененным форматом:
D3DXCreateTexture(pD3DDevice, width, height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &pTarget->pTex);
Знает ли кто-нибудь как это решить?
Пример с исходным кодом можно загрузить от сюда:
http://www.gamedev.ru/download/?id=8682
Код примера:
#include "..\..\include\hge.h" #include "..\..\include\hgesprite.h" HGE *hge=0; HTEXTURE texBackground; hgeSprite* sprBackground; HTEXTURE texBrush; hgeSprite* sprBrush; HTEXTURE texBlank; hgeSprite* sprBlank; HTARGET tarBlank; hgeSprite* sprTarBlank; bool GfxRestoreFunc() { if ( sprTarBlank && tarBlank ) sprTarBlank->SetTexture( hge->Target_GetTexture( tarBlank)); return false; } bool FrameFunc( ) { float dt=hge->Timer_GetDelta( ); return false; } bool RenderFunc( ) { // ------------------------------------------ hge->Gfx_BeginScene( tarBlank); hge->Gfx_Clear( 0); sprBlank->Render( 0, 0 ); for ( int i = 0; i < 4; i++ ) for ( int j = 0; j < 4; j++ ) sprBrush->Render( 15.f + 50*j, 15.f + 50*i ); hge->Gfx_EndScene( ); // ------------------------------------------ hge->Gfx_BeginScene( ); sprBackground->Render( 0, 0 ); sprBlank->Render( 50, 70 ); for ( int i = 0; i < 4; i++ ) for ( int j = 0; j < 4; j++ ) sprBrush->Render( 15.f + 50.f + 50*j, 15.f + 70.f + 50*i ); sprTarBlank->Render( 340, 70 ); hge->Gfx_EndScene( ); // ------------------------------------------ return false; } int WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR, int) { hge = hgeCreate( HGE_VERSION); hge->System_SetState( HGE_LOGFILE, "hge_tut04.log"); hge->System_SetState( HGE_FRAMEFUNC, FrameFunc); hge->System_SetState( HGE_RENDERFUNC, RenderFunc); hge->System_SetState( HGE_GFXRESTOREFUNC, GfxRestoreFunc); hge->System_SetState( HGE_TITLE, "HGE Tutorial 04 - Using render targets"); hge->System_SetState( HGE_FPS, 100); hge->System_SetState( HGE_WINDOWED, true); hge->System_SetState( HGE_SCREENWIDTH, 640); hge->System_SetState( HGE_SCREENHEIGHT, 480); hge->System_SetState( HGE_SCREENBPP, 32); hge->System_SetState( HGE_USESOUND, false); if( hge->System_Initiate( )) { texBackground = hge->Texture_Load( "background.jpg"); texBlank = hge->Texture_Load( "blank.png"); texBrush = hge->Texture_Load( "Brush.png"); if ( !texBackground || !texBlank || !texBrush ) { MessageBox( NULL, "Can't load files", "Error", MB_OK | MB_ICONERROR | MB_APPLMODAL); hge->System_Shutdown( ); hge->Release( ); return 0; } sprBackground = new hgeSprite( texBackground, 0, 0, 640, 480 ); sprBlank = new hgeSprite( texBlank, 0, 0, 250, 300 ); sprBrush = new hgeSprite( texBrush, 0, 0, 70, 70 ); tarBlank = hge->Target_Create( 250, 300, false ); sprTarBlank = new hgeSprite( hge->Target_GetTexture( tarBlank), 0, 0, 250, 300 ); // Let's rock now! hge->System_Start( ); // Delete created objects and free loaded resources delete sprBlank; delete sprBackground; delete sprBrush; delete sprTarBlank; hge->Texture_Free( texBrush); hge->Texture_Free( texBlank ); hge->Texture_Free( texBackground ); hge->Target_Free( tarBlank); } // Clean up and shutdown hge->System_Shutdown( ); hge->Release( ); return 0; }
гы. старая добрая проблема.
ее еще на dtf обсасывали.
лажа в том что при выводе РТ на экран с альфаканалом и с RGB надо проводить РАЗНЫЕ операции блендинга ( почему - это долго объяснять и можно найти объяснение тут или на dtf )
как я победил это:
просто - рендерил в РТ без альфы. но ... отдельно рендерил альфу в текстуру, которую использовал как маску для выводе спрайта.
а потом увидел что мне это слишком шикарно и мест где такое надо всего два и вообще маску в фотошопе отрисовал и использовал готовую..
ЗЫ DirectX9 уже позволяет проводить разные операции над альфой и цветом и там нет такой проблемы
вот код юзания масоки ( вырвал по живому из проекта, так что не спрашивайте шо за цЫфрыы волшебные)
void C3dPlane::render() { D3DXMATRIX tmp, matWord; m_hge->Gfx_GetDevice( )->GetTransform( D3DTS_WORLD, &matWord); D3DXMatrixMultiply( &matWord, &matWord, &m_matWord ); core::pgQuad* q = m_sprite->getQuad( ); m_hge->Gfx_GetDevice( )->SetTextureStageState( 0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR ); m_hge->Gfx_GetDevice( )->SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTEXF_LINEAR ); m_hge->Gfx_GetDevice( )->SetTexture( 0, ( IDirect3DBaseTexture8*)m_sprite->getMaterial( )->getHTexture( ) ); if( m_sprite ) { m_hge->Gfx_GetDevice( )->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE ); m_hge->Gfx_GetDevice( )->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); m_hge->Gfx_GetDevice( )->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE ); m_hge->Gfx_GetDevice( )->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE ); m_hge->Gfx_GetDevice( )->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE ); m_hge->Gfx_GetDevice( )->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE ); } float tu20, tu21, tv20, tv21; if( m_masksprite ) { tu20 = q->v[0].tx; tu21 = q->v[2].tx; tv20 = q->v[0].ty; tv21 = q->v[2].ty; q->v[0].tu2 = 0.0f; q->v[1].tu2 = 494.0f/512.0f; q->v[2].tu2 = 494.0f/512.0f; q->v[3].tu2 = 0.0f; q->v[0].tv2 = 0.0f; q->v[1].tv2 = 0.0f; q->v[2].tv2 = 638.0f/1024.0f; q->v[3].tv2 = 638.0f/1024.0f; m_hge->Gfx_GetDevice( )->SetTexture( 1, ( IDirect3DBaseTexture8*)m_masksprite->getMaterial( )->getHTexture( ) ); m_hge->Gfx_GetDevice( )->SetTextureStageState( 1, D3DTSS_TEXCOORDINDEX, 1); m_hge->Gfx_GetDevice( )->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1); m_hge->Gfx_GetDevice( )->SetTextureStageState( 1, D3DTSS_COLORARG1, D3DTA_CURRENT); m_hge->Gfx_GetDevice( )->SetTextureStageState( 1, D3DTSS_ALPHAOP, D3DTOP_MODULATE ); m_hge->Gfx_GetDevice( )->SetTextureStageState( 1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); m_hge->Gfx_GetDevice( )->SetTextureStageState( 1, D3DTSS_ALPHAARG2, D3DTA_CURRENT); m_hge->Gfx_GetDevice( )->SetTextureStageState( 2, D3DTSS_ALPHAOP, D3DTOP_DISABLE); m_hge->Gfx_GetDevice( )->SetTextureStageState( 2, D3DTSS_ALPHAOP, D3DTOP_DISABLE); m_hge->Gfx_GetDevice( )->SetTextureStageState( 2, D3DTSS_COLOROP, D3DTOP_DISABLE); m_hge->Gfx_GetDevice( )->SetTextureStageState( 2, D3DTSS_ALPHAOP, D3DTOP_DISABLE); } static unsigned short indices[6] = { 0, 1, 2, 2, 3, 0 }; m_hge->Gfx_DrawVertexPrimitiveList( q->v, 4, ( const unsigned short*)indices, 2, matWord, true ); m_hge->Gfx_GetDevice( )->SetTexture( 0, NULL ); m_hge->Gfx_GetDevice( )->SetTexture( 1, NULL ); }
вот для 2Д случая
void GfxCore::Gfx_RenderMask(HTEXTURE texMask, HTEXTURE texture, int MinVertexIndex, int NumVertices, int startIndex, int primCount ) { Gfx_GetDevice( )->SetTextureStageState( 0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR); Gfx_GetDevice( )->SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTEXF_LINEAR); // Texture Stage 1: Gfx_GetDevice( )->SetTexture( 0, ( IDirect3DBaseTexture8*)texture); Gfx_GetDevice( )->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE ); Gfx_GetDevice( )->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); Gfx_GetDevice( )->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE ); Gfx_GetDevice( )->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE ); Gfx_GetDevice( )->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE ); Gfx_GetDevice( )->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE ); // Texture Stage 0: Gfx_GetDevice( )->SetTexture( 1, ( IDirect3DBaseTexture8*)texMask ); Gfx_GetDevice( )->SetTextureStageState( 1, D3DTSS_TEXCOORDINDEX, 1); Gfx_GetDevice( )->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_SELECTARG1); Gfx_GetDevice( )->SetTextureStageState( 1, D3DTSS_COLORARG1, D3DTA_CURRENT); Gfx_GetDevice( )->SetTextureStageState( 1, D3DTSS_ALPHAOP, D3DTOP_MODULATE ); Gfx_GetDevice( )->SetTextureStageState( 1, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); Gfx_GetDevice( )->SetTextureStageState( 1, D3DTSS_ALPHAARG2, D3DTA_CURRENT); Gfx_GetDevice( )->SetTextureStageState( 2, D3DTSS_ALPHAOP, D3DTOP_DISABLE); Gfx_GetDevice( )->SetTextureStageState( 2, D3DTSS_ALPHAOP, D3DTOP_DISABLE); Gfx_GetDevice( )->SetTextureStageState( 2, D3DTSS_COLOROP, D3DTOP_DISABLE); Gfx_GetDevice( )->SetTextureStageState( 2, D3DTSS_ALPHAOP, D3DTOP_DISABLE); Gfx_GetDevice( )->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, MinVertexIndex, NumVertices, startIndex, primCount); /************************************************************************/ /* */ /************************************************************************/ // Reset render states... Gfx_GetDevice( )->SetTexture( 0, NULL ); Gfx_GetDevice( )->SetTexture( 1, NULL ); Gfx_GetDevice( )->SetTexture( 2, NULL ); Gfx_GetDevice( )->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_DISABLE ); Gfx_GetDevice( )->SetTextureStageState( 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE ); Gfx_GetDevice( )->SetTextureStageState( 2, D3DTSS_COLOROP, D3DTOP_DISABLE ); Gfx_GetDevice( )->SetTextureStageState( 2, D3DTSS_ALPHAOP, D3DTOP_DISABLE ); Gfx_GetDevice( )->SetTextureStageState( 0, D3DTSS_TEXCOORDINDEX, 0 ); Gfx_GetDevice( )->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE ); Gfx_GetDevice( )->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); Gfx_GetDevice( )->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE ); Gfx_GetDevice( )->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE ); Gfx_GetDevice( )->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE ); Gfx_GetDevice( )->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE ); Gfx_GetDevice( )->SetTextureStageState( 1, D3DTSS_COLOROP, D3DTOP_DISABLE ); Gfx_GetDevice( )->SetTextureStageState( 2, D3DTSS_COLOROP, D3DTOP_DISABLE ); Gfx_GetDevice( )->SetTextureStageState( 3, D3DTSS_COLOROP, D3DTOP_DISABLE ); Gfx_GetDevice( )->SetTextureStageState( 1, D3DTSS_ALPHAOP, D3DTOP_DISABLE ); Gfx_GetDevice( )->SetTextureStageState( 2, D3DTSS_ALPHAOP, D3DTOP_DISABLE ); Gfx_GetDevice( )->SetTextureStageState( 0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR); Gfx_GetDevice( )->SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTEXF_LINEAR); }
bishop_spb
Спасибо большое, буду ковыряться :)
Тема в архиве.