Archived

This topic is now archived and is closed to further replies.

Syntacs

Direct3D Texture Loading Question

Recommended Posts

Syntacs    122
How would I go about loading a texture manually, and then sending the image data to DirectX to create a texture with? (i.e. a Direct3D equivalent to glTexImage2D) I can''t use D3DXCreateTextureFromFile because my textures are stored in a archive file. Any help is greatly appreciated.

Share this post


Link to post
Share on other sites
Wreakon    121
Hey, try looking at the D3DX source code and see if it''s in there. So far in the documentation it doesnt look like they want you to know how to load a tesxture file manually.

-------
Happy Coding!
Homepage: www.pcwebvia.f2s.com

Share this post


Link to post
Share on other sites
Syntacs    122
Could you be more specific about what would be involved in "Creating the texture, locking the surface, and copying the bits into the buffer myself" please? The documentation is rather vague on this subject...

Thanks.

Share this post


Link to post
Share on other sites
Steveyboy    122
  
HRESULT CTexture::Init(DWORD dwWidth, DWORD dwHeight, D3DFORMAT fmtTex, BYTE* pBits, LPCSTR szName, LPDIRECT3DDEVICE8 pDevice)
{
HRESULT hResult;
DWORD y;

// Create Texture //

hResult = pDevice->CreateTexture(dwWidth, dwHeight, 1, 0, g_texMgr.m_fmtTexture, D3DPOOL_MANAGED, &m_pTexture);
if(FAILED(hResult))
{
OnFatalError("CTexture::Init() IDirect3DDevice8::CreateTexture() Failed.");
SetLastError(hResult);
return hResult;
}

// Lock texture //

D3DLOCKED_RECT theRect;
hResult = m_pTexture->LockRect(0,&theRect,NULL,0);
if(FAILED(hResult))
{
OnFatalError("CTexture::Init() IDirect3DDevice8::LockRect() Failed.");
SetLastError(hResult);
return hResult;
}

// Copy Data //

BYTE* pSurf = (BYTE*)theRect.pBits;
// 32-bpp, same as input, just copy scanline by scanline //

if(g_texMgr.m_dwTextureBytes == 4)
{
for(y=0; y<dwHeight; y++)
{
CopyMemory(pSurf,pBits,dwWidth*4);
pBits += dwWidth*4;
pSurf += theRect.Pitch;
}
}
// 24-bpp, need to convert from 32-bpp //

else if(g_texMgr.m_dwTextureBytes == 3)
{
for(y=0; y<dwHeight; y++)
{
for(DWORD x=0; x<dwWidth; x++)
{
CopyMemory(pSurf,pBits+x*4,3);
pSurf += 3;
}
pBits += dwWidth*4;
pSurf = ((BYTE*)theRect.pBits)+y*theRect.Pitch;
}
}
// 16-bpp, need to convert from 32-bpp :- Fun... //

else
{
WORD wTarg;
DWORD dwSource;
switch(g_texMgr.m_fmtTexture)
{
case D3DFMT_R5G6B5:
for(y=0; y<dwHeight; y++)
{
pSurf = ((BYTE*)theRect.pBits)+y*theRect.Pitch;
for(DWORD x=0; x<dwWidth; x++)
{
dwSource = *(((DWORD*)pBits)+x);
wTarg = (((dwSource & 0xFF0000) >> 8) & 0xF800)| // Red

(((dwSource & 0x00FF00) >> 5) & 0x7E0)| // Green

(((dwSource & 0x0000FF) >> 3) & 0x1F); // Blue

*pSurf++ = wTarg&0xFF;
*pSurf++ = (wTarg&0xFF00)>>8;
}
pBits += dwWidth*4;
}
break;

case D3DFMT_X4R4G4B4:
for(y=0; y<dwHeight; y++)
{
pSurf = ((BYTE*)theRect.pBits)+y*theRect.Pitch;
for(DWORD x=0; x<dwWidth; x++)
{
dwSource = *(((DWORD*)pBits)+x);
wTarg = (((dwSource & 0xFF0000) >> 12) & 0xF00)| // Red

(((dwSource & 0x00FF00) >> 8) & 0xF0)| // Green

(((dwSource & 0x0000FF) >> 4) & 0xF); // Blue

*pSurf++ = wTarg&0xFF;
*pSurf++ = (wTarg&0xFF00)>>8;
}
pBits += dwWidth*4;
}
break;

case D3DFMT_A4R4G4B4:
for(y=0; y<dwHeight; y++)
{
pSurf = ((BYTE*)theRect.pBits)+y*theRect.Pitch;
for(DWORD x=0; x<dwWidth; x++)
{
dwSource = *(((DWORD*)pBits)+x);
wTarg = (((dwSource & 0xFF000000) >> 16) & 0xF000)| // Alpha

(((dwSource & 0x00FF0000) >> 12) & 0xF00)| // Red

(((dwSource & 0x0000FF00) >> 8) & 0xF0)| // Green

(((dwSource & 0x000000FF) >> 4) & 0xF); // Blue

*pSurf++ = wTarg&0xFF;
*pSurf++ = (wTarg&0xFF00)>>8;
}
pBits += dwWidth*4;
}
break;

case D3DFMT_X1R5G5B5:
for(y=0; y<dwHeight; y++)
{
pSurf = ((BYTE*)theRect.pBits)+y*theRect.Pitch;
for(DWORD x=0; x<dwWidth; x++)
{
dwSource = *(((DWORD*)pBits)+x);
wTarg = (((dwSource & 0xFF0000) >> 9) & 0x7C00)| // Red

(((dwSource & 0x00FF00) >> 5) & 0x3E0)| // Green

(((dwSource & 0x0000FF) >> 3) & 0x1F); // Blue

*pSurf++ = wTarg&0xFF;
*pSurf++ = (wTarg&0xFF00)>>8;
}
pBits += dwWidth*4;
}
break;

case D3DFMT_A1R5G5B5:
for(y=0; y<dwHeight; y++)
{
pSurf = ((BYTE*)theRect.pBits)+y*theRect.Pitch;
for(DWORD x=0; x<dwWidth; x++)
{
dwSource = *(((DWORD*)pBits)+x);
wTarg = (((dwSource & 0xFF000000) >> 16) & 0x8000)| // Alpha

(((dwSource & 0x00FF0000) >> 9) & 0x7C00)| // Red

(((dwSource & 0x0000FF00) >> 5) & 0x3E0)| // Green

(((dwSource & 0x000000FF) >> 3) & 0x1F); // Blue

*pSurf++ = wTarg&0xFF;
*pSurf++ = (wTarg&0xFF00)>>8;
}
pBits += dwWidth*4;
}
break;

case D3DFMT_A8R3G3B2:
for(y=0; y<dwHeight; y++)
{
pSurf = ((BYTE*)theRect.pBits)+y*theRect.Pitch;
for(DWORD x=0; x<dwWidth; x++)
{
dwSource = *(((DWORD*)pBits)+x);
wTarg = (((dwSource & 0xFF000000) >> 16) & 0xFF00)| // Alpha

(((dwSource & 0x00FF0000) >> 16) & 0xE0)| // Red

(((dwSource & 0x0000FF00) >> 11) & 0x1C)| // Green

(((dwSource & 0x000000FF) >> 6) & 0x3); // Blue

*pSurf++ = wTarg&0xFF;
*pSurf++ = (wTarg&0xFF00)>>8;
}
pBits += dwWidth*4;
}
break;

default:
assert(false); // Error, should never rech here

}
}

// Unlock Texture //

m_pTexture->UnlockRect(0);

// Copy other data and return success //

return S_OK;
}

*phew* All the bit shifting and masking copies the bits into the surface correctly. Play about with it on paper if you don''t understand.

That code assumes the input is 32-bit BGRA data.
"g_texMgr.m_dwTextureBytes" is the number of bytes-per-pixel the texture format is in (often D3DFMT_A8R8G8B8, but my code determines the best possible format to use that is compatible with the render target and device.)

HTH, Steve

Share this post


Link to post
Share on other sites