Page 1 of 2 12 LastLast
Results 1 to 10 of 14

Thread: [D3D] Converting TBitmap to Direct3dTexture8

  1. #1

    [D3D] Converting TBitmap to Direct3dTexture8

    Hi guys.

    What is the best/easiest way to convert a TBitmap to a Direct3dTexture8 object. I prefer to store the texture in D3DPOOL_DEFAULT.

    And is there a way to convert it back to a TBitmap.

    Thanx in advance.
    Coders rule nr 1: Face ur bugz.. dont cage them with code, kill'em with ur cursor.

  2. #2

    [D3D] Converting TBitmap to Direct3dTexture8

    Hi! I use this function in DX9 (maybe there is a version in DX:

    Code:
    D3DXCreateTextureFromFileInMemory
    Creates a texture from a file in memory.
    
    HRESULT D3DXCreateTextureFromFileInMemory(
      LPDIRECT3DDEVICE9 pDevice,
      LPCVOID pSrcData,
      UINT SrcDataSize,
      LPDIRECT3DTEXTURE9 * ppTexture
    );
    I have used it to load bitmap files, but I think you could save the bitmap to a memory stream instead of a file stream, and use this function.

    For me it's very useful since I can read bitmaps from disk and network... but I have found it's not thread safe. It seems that if the texture is too big it will be left for later conversion, and there is no way to know when the texture is ready :x The only way around is waiting some time.

  3. #3

    RE-

    You can create a empty dx texture and then get a pointer to the texture surface so you can read/write directly the pixels:

    //-------
    var
    texture:IDirect3DTexture8; //dx texture.
    B:tbitmap; //bitmap.
    rrect: tD3DLOCKED_RECT; //for lock a rectangular surface in the texture.
    .
    .
    //create a empty texture with the dimension and parameters we want:
    D3DDEV8.CreateTexture( b.width,b.height,1,0, D3DFMT_A1R5G5B5, D3DPOOL_MANAGED, texture)); //change D3DFMT_A1R5G5B5 for the pixel format you want.

    //Lock and get texture surface object

    Texture.LockRect(0, rrect, Nil, 0);

    //Now you can read/write texture pixels accesing the surface pointer found at "rrect.pBits".

    //put bitmap pixels, P is a pointer to the bitmap pixels.

    Move(p^, rrect.pBits^, blocksize);

    Texture.UnlockRect(0); //it is very important to unlock when we are done.

    //---------------------------------

    For get a TBitmap pixels in delphi I use Tbitmap.ScanLine[Row] which return a pointer to that row of pixels; i normally do a loop for get tbitmap pixels row by row.

    Be sure bitmap pixel format is the same as teh texture pixel format used when created;

    Note that in some olds videocards Dx textures width/height must have to be power of two; also is a god advice to querry the videocard maximun texture size allowed (old videocard acept max 512x512 texture sizes), using the CAPs from D3DDEV8.


    good luck.

    tp.

  4. #4

    [D3D] Converting TBitmap to Direct3dTexture8

    Having things on D3DPOOL_MANAGED is not recomended for optimization, since there are two copies that will be maintained, one in system memory and another in D3DPOOL_DEFAULT pool. This results in a redundant memory copy operation that consumes CPU time and wastes memory bandwidth.

  5. #5

    [D3D] Converting TBitmap to Direct3dTexture8

    Having things on D3DPOOL_MANAGED is not recomended for optimization, since there are two copies that will be maintained, one in system memory and another in D3DPOOL_DEFAULT pool. This results in a redundant memory copy operation that consumes CPU time and wastes memory bandwidth.
    Your post sound like D3DPOOL_MANAGED should not be used at all becouse it is a "waste" of memory and bandwidth.

    But actually i think that is the preffered way; check this webite about a explanation about dx resources:

    http://www.toymaker.info/Games/html/d3d_resources.html

    D3DPOOL_MANAGED has two great adventage:- You can get a pointer to acces directly the texture surfaces (so you can read/write on in which is the point of this original tread question.) and also you dont need to recreate the textures when the device got "lost"; not necesarry it is always that easy to load again the textures from disk, textures could have been stored in resources game data files where one have to parse the file to gent into the texture chunk, etc; so that is why not always people is using "LoadTextureFromFile" but they need a way to load texture from memory coze teh texture data got there in a different way.

    Of course, if for your app all your textures can be loaded using "LoadTextureFromFile" and you never need to get acces to it then D3DPOOL_DEFAULT is your best choice.


    tp.

  6. #6

    [D3D] Converting TBitmap to Direct3dTexture8

    No, I'm just taking that information from a document of ATI about optimizations in DX9:

    http://www.ati.com/developer/dx9/ATI...timization.pdf

    That's why it's *not recommended*, doesn't mean that it shouldn't be used at all. And as you pointed out that's the method to lock the texture.

    In my opinion if the texture is going to be updated in a single batch, it's better using D3DXCreateTextureFromFileInMemory. Working with .bmp files in memory is easy with Delphi's class TBitmap.

    Just take that in mind when doing optimizations.

  7. #7

    re-

    Hey, thank you for the link, very useful info there; hope those advices found there are not exclusivily for ATI cards.

    Just for the record, the part you quoted is from page 7 but it refer about index and vertex buffers creations:

    Buffers Creating efficient vertex and index buffers Dynamic vertex and index buffers always have to be created in D3DPOOL_DEFAULT memory pool. If they are allocated in D3DPOOL_MANAGED memory pool, two copies of the buffers will be maintained – one in the system memory and another in D3DPOOL_DEFAULT pool. Whenever a managed buffer is locked and written to, the application gets a pointer to system memory copy, which will be copied to D3DPOOL_DEFAULT pool buffer instance once the buffer is unlocked. This results in a redundant memory copy operation that consumes CPU time and wastes memory bandwidth.
    Wich i am agree, for a game your are rendering your scene several frames per second sending your triagles to your vertex/index buffers (writing), so if they where created in managed pool then two copies of your rendering scenes are happening one in system memory and another one in card memory; and i dont see the point to get able to edit the system memory scene buffer copy you just had rendered, people should send the already finished scene to the vertex/index buffer in first place.

    But that is not the case for managed pool created textures; when you render your scene the texture data used is the one already stored in card memory, the copy from system memory is not used just becouse your are rendering triangles, the texture system memory is copied to card memory only when you lock (edit the texture), for changing the pixels (if you are doing that every frame then that is another History); so if you use D3DPOOL_MANAGED for create your texture for load the data manually just one time when your application start then you will not get any perfomance penalty when rendering scenes and you will get the adventage of not having to recreate the texture when the device gets lost.

  8. #8

    [D3D] Converting TBitmap to Direct3dTexture8

    But, a second copy in system memory might not be necessary in all cases, specially if just loading the texture once. In such case, it would be better the method to load directly.

    Another case is when the texture is modified unfrequently, why having a backup copy all the time? Then it would be better to create a TBitmap just when needed and passing it with a memory stream to the method that loads files in memory.

    And textures and vertex buffer can be restored manually, instead of relying on DX... but, anyway, it's a matter of optimization that must be adjusted to every specific case.

  9. #9

    [D3D] Converting TBitmap to Direct3dTexture8

    Nice debate huh, :lol:

    But, a second copy in system memory might not be necessary in all cases, specially if just loading the texture once. In such case, it would be better the method to load directly.
    Ok, I just want to be clear that i am not saying the people should alway have to create textures in managed pool, using default pool or managed pool mostly depend on what you say "a second copy in system memory might not be necessary in all cases", if you never need a secound copy or if you preffer to have your own second copy in tbitmaps object, if you never need to make changes in the texture or if you dont have any problem re-loading the data from file or from stream when the device is lost then YES, you dont need a secound copy and dont use managed pool.

    But i am going to tell you why most the time I dont use loadtexturefromFile / loadtexturefromstream / loadtexturefromresource etc, myself, not becouse there is somthing wrong, it is just becouse it only works for the picture fileformat (with header) it is supported in the function; but how about when the texture is a format not supported?, there are several cases when you need to define and put manually the pixels into dx textures..if the texture is in some compressed way (ziped, zlib) or in format not supported by default.

    When I learned Directx was becouse i was needing to do a Mod tools for a popular game called Tomb Raider, where for every level/stage in the game there is one big file of about 6-10MB, where it is stored all models, animations, texures, triggers, characters sounds, lighting objects, world geometry, etc.etc, so every chunk have to be parsed to get to the next chunk, for the texture chunk you dont get several bmp files embeded, no, no,no, you get a big raw pixels data with not heading in the format of 5,5,5,1 bits per pixel (rgba in 16 bits); later in anothers chunk is found a special table of texture description where tells the fragments into that raw data. So the way I put those textures in dx is using a function where i can pass a memory pointer for the fragment raw data and defining manually the pixel format and block size for every texture;

    For some games and real projects (even yours) you dont always going to have different 4000 bmps (or whatever) textures files for been loaded one by one, and neither you are not going to have one big bmp of 512x2340480 size file in disk for been loaded in just one dx texture; neither your want to have all textures loaded in memory all at the same time, so in those cases you will want to be able to open your texture data resource, and gets able to define needed textures passing memory block chunks; heck even some people uses a texture memory manager that uses cached textures and release textures not used or not longer needed in that stage of the game etc;

    sorry for the rant.

    see ya

    tp.


    Ps.
    In case you are wondering about my Tomb raider Mod tool: www.dxtre3d.com

  10. #10

    [D3D] Converting TBitmap to Direct3dTexture8

    That's right, you have more control over the format of the texture (structure and color depth), but on the other hand that's something most people just escape from. In all the examples about locking textures I've seen people use only one format, usually the ARGB, which is faster to use, and so they don't have to mess with the bits. So is a power that is simply wasted because it is impractical to write the same image processing routine for several formats at the same time.

    And, TBitmap could be inherited to create any customized formats... unfortunately the ScanLine[] property of TBitmap isn't implemented in TGraphic, making it harder to read JPG, PNG, and other thrid party graphic format classes out there. But that doesn't stop anyone from working with other formats with TBitmap.

    Your editor is very cool! I'm creating one that is similar (based on box elements), but is simplier. I have to make a new version with the enhancements I'm doing in my game engine.



    I made an algorithm to create those box elements using only 12 parameters to define the shape of the box. The idea is to create those boxes from code too.

Page 1 of 2 12 LastLast

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •