views:

58

answers:

1

Can anybody help with converting an SDL_Surface object, a texture loaded from a file, into an IDirect3DTexture9 object.

+1  A: 

I honestly don't know why you would ever want to do this. It sounds like a truly horrible idea for a variety of reasons, so please tell us why you want to do this so we can convince you not to ;).

In the meanwhile, a quick overview of how you'd go about it:

IDirect3DTexture9* pTex = NULL;
HRESULT            hr   = S_OK;
hr = m_d3dDevice->CreateTexture(
    surface->w,
    surface->h,
    1,
    usage,
    format,
    D3DPOOL_MANAGED,
    &pTex,
    NULL);

This creates the actual texture with the size and format of the SDL_Surface. You'll have to fill in the usage on your own, depending on how you want to use it (see D3DUSAGE). You'll also have to figure out the format on your own - you can't directly map a SDL_PixelFormat to a D3DFORMAT. This won't be easy, unless you know exactly what pixel format your SDL_Surface is.

Now, you need to write the data into the texture. You can't use straight memcpy here, since the SDL_Surface and the actual texture may have different strides. Here's some untested code that may do this for you:

HRESULT        hr;
D3DLOCKED_RECT lockedRect;

// lock the texture, so that we can write into it
// Note: if you used D3DUSAGE_DYNAMIC above, you should 
// use D3DLOCK_DISCARD as the flags parameter instead of 0.
hr = pTex->LockRect(0, &lockedRect, NULL, 0);
if(SUCCEEDED(hr))
{
    // use char pointers here for byte indexing
    char*  src     = (char*) surface->pixels;
    char*  dst     = (char*) lockedRect->pBits;
    size_t numRows = surface->h;
    size_t rowSize = surface->w * surface->format->BytesPerPixel;

    // for each row...
    while(numRows--)
    {
        // copy the row
        memcpy(dst, src, rowSize);

        // use the given pitch parameters to advance to the next
        // row (since these may not equal rowSize)
        src += surface->pitch;
        dst += lockedRect->Pitch;
    }

    // don't forget this, or D3D won't like you ;)
    hr = pTex->UnlockRect(0);
}
arke
Thanks for that.And the reason I am doing this is because the SDL_Image image loading library was the best I could find for loading textures from file.If it is really that horrible an idea, could you recommend another library?
Sam J
Take a look at devIL. It also has methods for loading an image directly into a IDirect3D8Texture (see ilutD3D8Texture), so you could use that as a reference point for a IDirect3D9Texture (and maybe submit your work to the devIL folk). The reason why using SDL_image isn't such a good idea is because it may or may not require SDL to be initialized, and it's not that unlikely that it'll interfere with your D3D9 setup in some way.
arke
thanks arke! :)
Sam J
Good answer with clear and helpful code. I'd vote it up twice as an example of how to answer a question if I could :)
John Burton