Skip to main content
Added a comment about the use of ID3DXSprite.
Source Link

PS: I have read about the IDirect3DTexture9 and ID3DXSprite interfaces which could be helpful, but I haven't used them yet as I did not find any information on how to rebuild a map with tiles like I did here with usual surfaces. If anyone has suggestions about this, I would be glad to here them!

PS: I have read about the IDirect3DTexture9 and ID3DXSprite interfaces which could be helpful, but I haven't used them yet as I did not find any information on how to rebuild a map with tiles like I did here with usual surfaces. If anyone has suggestions about this, I would be glad to here them!

Source Link

Tile-based game with DirectX - issues with transparency and StretchRect

In my current project I have a class which loads a map file and then it should load all associated tilesets (no transparent tiles - I used to work with magenta as a colorkey) and precreate a surface for each static layer of the map so I only have to display one bigger image per frame rather then iterating over all of my tiles. For each tileset I have a loop which loads them successfully like this

 IDirect3DSurface9 *pTilesetSurface = nullptr;
 // Create surface
 HRESULT hResult = Engine::GetInstance()->GraphicsDevice->CreateOffscreenPlainSurface(
      pTileset->GetImage()->GetWidth(),
      pTileset->GetImage()->GetHeight(),
      D3DFMT_A8R8G8B8,
      D3DPOOL_DEFAULT,
      &pTilesetSurface,
      nullptr);
 if(!SUCCEEDED(hResult))
      return FALSE;

 // Load tileset
 std::wstring strTilesetSource(
      pTileset->GetImage()->GetSource().begin(),
      pTileset->GetImage()->GetSource().end());
 strTilesetSource = strPathToMap + strTilesetSource;
 hResult = ::D3DXLoadSurfaceFromFile(
      pTilesetSurface,
      nullptr,
      nullptr,
      strTilesetSource.c_str(),
      nullptr,
      D3DX_FILTER_LINEAR,
      D3DCOLOR_ARGB(255, 255, 0, 255),
      nullptr);
 if(!SUCCEEDED(hResult))
      return FALSE;

 this->m_vTilesets.push_back(pTilesetSurface);

After this loop I am iterating over every layer of the map and trying to build a surface for each layer with the associated tiles like this.

IDirect3DSurface9 *pLayerSurface = nullptr;
HRESULT hResult = Engine::GetInstance()->GraphicsDevice->CreateOffscreenPlainSurface(
    pLayer->GetWidth() * 16,
    pLayer->GetHeight() * 16,
    D3DFMT_A8R8G8B8,
    D3DPOOL_DEFAULT,
    &pLayerSurface,
    nullptr);
if(!SUCCEEDED(hResult))
    return FALSE;
Engine::GetInstance()->GraphicsDevice->ColorFill(
    pLayerSurface,
    nullptr,
    D3DCOLOR_ARGB(0, 0, 0, 0));
for(int x = 0; x < pLayer->GetWidth(); ++x) {
    for(int y = 0; y < pLayer->GetHeight(); ++y) {
        const Tmx::MapTile tile = pLayer->GetTile(x, y);
        if(tile.tilesetId != -1) {
            int dwTilesetWidth =
            this->m_pTmxFile->GetTileset(tile.tilesetId)->GetImage()->GetWidth() / 16;
            std::div_t tileCoords = std::div(tile.id, dwTilesetWidth);
            RECT srcRect = { tileCoords.rem * 16, tileCoords.quot * 16,
                tileCoords.rem * 16 + 16, tileCoords.quot * 16 + 16 };
            RECT destRect = { x * 16, y * 16, x * 16 + 16, y * 16 + 16 };
            Engine::GetInstance()->GraphicsDevice->StretchRect(
                this->m_vTilesets[tile.tilesetId],
                &srcRect,
                pLayerSurface,
                &destRect,
                D3DTEXF_NONE);
        }
    }
}

A call to D3DXSaveSurfaceToFile for debugging purposes creates transparent png files which can be layered correctly in Photoshop etc. but when I render these surfaces with this loop

for(auto iter = this->m_vLayers.begin(); iter != this->m_vLayers.end(); ++iter) {
    Engine::GetInstance()->GraphicsDevice->StretchRect(
        *iter,
        nullptr,
        Engine::GetInstance()->Backbuffer,
        nullptr,
        D3DTEXF_NONE);
}

then I have some wrong output which you can see here: Wrong output.

All the blacks areas should be transparent such that one can see the layer below. Has anyone an idea what I might be doing wrong?