Lockable render target textures
  • kijanek6kijanek6 April 2011
    http://blog.kijedi.tk/2011/04/hge-lockable-render-target-textures/
    Written for DirectX9 version, tested with transparent RT's (should work without problems with default too).
  • evilsquareevilsquare April 2011
    wrong link :/
  • ProfEclipseProfEclipse April 2011
    Worked fine for me.
  • kijanek6kijanek6 April 2011
    For me also. Here's the code if someone still has problems:

    Headers:
    1
    2
    3
    4
    5
    6
    typedef DWORD HSURFACE;
    (...)
    virtual HSURFACE CALL Target_GetSurface(HTARGET target);
    virtual void CALL Surface_Free(HSURFACE surf);
    virtual DWORD* CALL Surface_Lock(HSURFACE surf, bool bReadOnly=true, int left=0, int top=0, int width=0, int height=0);
    virtual void CALL Surface_Unlock(HSURFACE surf);


    Implementation:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    HSURFACE CALL HGE_Impl::Target_GetSurface(HTARGET target)
    {
    HTEXTURE src = Target_GetTexture(target);
    IDirect3DSurface9 * srcsurf, * destsurf;
    ((LPDIRECT3DTEXTURE9)src)->GetSurfaceLevel(0, &srcsurf);
    pD3DDevice->CreateOffscreenPlainSurface(Texture_GetWidth(src), Texture_GetHeight(src), D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &destsurf, NULL);
    HRESULT res = pD3DDevice->GetRenderTargetData(srcsurf, destsurf);
    if( res == D3D_OK )
    return (HSURFACE)((LPDIRECT3DSURFACE9)destsurf);
    return 0;
    }
     
    void CALL HGE_Impl::Surface_Free(HSURFACE surf)
    {
    ((LPDIRECT3DSURFACE9)surf)->Release();
    }
     
    DWORD * CALL HGE_Impl::Surface_Lock(HSURFACE surf, bool bReadOnly, int left, int top, int width, int height)
    {
    LPDIRECT3DSURFACE9 pSurf=(LPDIRECT3DSURFACE9)surf;
    D3DLOCKED_RECT TRect;
    RECT region, *prec;
    int flags;
     
    if(width && height)
    {
    region.left=left;
    region.top=top;
    region.right=left+width;
    region.bottom=top+height;
    prec=&ion;
    }
    else prec=0;
     
    if(bReadOnly) flags=D3DLOCK_READONLY;
    else flags=0;
     
    if(FAILED(pSurf->LockRect(&TRect, prec, flags)))
    {
    _PostError("Can't lock surface");
    return 0;
    }
     
    return (DWORD *)TRect.pBits;
    }
     
    void CALL HGE_Impl::Surface_Unlock(HSURFACE surf)
    {
    LPDIRECT3DSURFACE9 pSurf=(LPDIRECT3DSURFACE9)surf;
    pSurf->UnlockRect();
    }


    Usage example:
    1
    2
    3
    4
    5
    6
    //targTemp is a HTARGET
    HSURFACE surf = hge->Target_GetSurface(targTemp);
    DWORD * data = hge->Surface_Lock(surf);
    //'data' here is normal locked texture data
    hge->Surface_Unlock(surf);
    hge->Surface_Free(surf);


    Surface_Lock syntax is identical to Texture_Lock, however making changes to it is useless, because you can’t copy surface to texture in my version (but this is possible and you can write it on your own). HSURFACE can be only used to read data from render target. Remember, that Target_GetSurface creates new surface, which you have to deallocate every time you use it.

    Note that my code is for DirectX9 version of HGE.

    Code provided on do-whatever-you-want-but-notice-author licence. ;)

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Sign In Apply for Membership

In this Discussion

Who's Online (1)