ПрограммированиеФорум2D графика и изометрия

И снова о рендер таргетах в HGE

#0
13:07, 3 апр 2009

Как известно в HGE таргеты не поддерживают альфу, по-этому все вносят изменения в двиг меняя формат
таргетов с d3dpp->BackBufferFormat на D3DFMT_A8R8G8B8.

Таргеты начинают поддерживать альфу, но всплывает следующая проблема:
при отрисовки в них полупрозрачных спрайтов сам таргет в этих местах становится полупрозрачным!

Скриншот:
Bug of Render Target to HGE | И снова о рендер таргетах в HGE

создание таргета с измененным форматом:

D3DXCreateTexture(pD3DDevice, width, height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &pTarget->pTex);

Знает ли кто-нибудь как это решить?

Пример с исходным кодом можно загрузить от сюда:
http://www.gamedev.ru/download/?id=8682

#1
13:09, 3 апр 2009

Код примера:

#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;
}
#2
13:45, 3 апр 2009

гы. старая добрая проблема.
ее еще на dtf обсасывали.

лажа в том что при выводе РТ на экран с альфаканалом и с RGB надо проводить РАЗНЫЕ операции блендинга ( почему - это долго объяснять и можно найти объяснение тут или на dtf )

как я победил это:
просто - рендерил в РТ без альфы. но ... отдельно рендерил альфу в текстуру, которую использовал как маску для выводе спрайта.
а потом увидел что мне это слишком шикарно и мест где такое надо всего два и вообще маску в фотошопе отрисовал и использовал готовую..

#3
13:47, 3 апр 2009

ЗЫ DirectX9 уже позволяет проводить разные операции над альфой и цветом и там нет такой проблемы

#4
13:50, 3 апр 2009

вот код юзания масоки ( вырвал по живому из проекта, так что не спрашивайте шо за цЫфрыы волшебные)

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 );
}
#5
13:51, 3 апр 2009

вот для 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);

}
#6
13:57, 3 апр 2009

bishop_spb
Спасибо большое, буду ковыряться :)

ПрограммированиеФорум2D графика и изометрия

Тема в архиве.