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

Thread: [D3D] problems with transparency...

  1. #1

    [D3D] problems with transparency...

    Hi PGD people

    I bumped into a Transperancy problem.
    I am currently using a 24 bit texture in my game with $000000ff (bleu) as transparent color.
    The backbuffer format is D3DFMT_A8R8G8B8 and
    i always use the backbuffer format for Texture initalisation (Just thought its the best way ).

    This works fine, but i want my engine to also use 16bit graphics. I think that is D3DFMT_R5G6B5.
    But when i Initalize a 16 bit Texture,i have to pass a different transparent color because it has to be 16bit
    (I though of $001F but it doesn't work ).
    Maybe the actual data of the texture is changed, since its a 24 bit Bitmap loaded on a D3DFMT_R5G6B5 texture, so some color data might be lost. :?
    I have not been able to find the correct value, so far. :cry:

    Does anyone have a solution or a good color conversion routine?
    Coders rule nr 1: Face ur bugz.. dont cage them with code, kill'em with ur cursor.

  2. #2

    re-

    This works fine, but i want my engine to also use 16bit graphics. I think that is D3DFMT_R5G6B5.
    I guess it should be D3DFMT_A1R5G5B5, so 1 bit for alpha, and 5 bits for each color component.

    - with 8 bits you get values from 0 to 255 for each component.
    - with 5 bits you get values from 0 to 31 for each component.

    If you need to convert manually 8 bit color to 5 bit color you should do interpolation, somthing like 256/32=8

    color5b = color8b/8;



    tp.

  3. #3

    [D3D] problems with transparency...

    Thanx..

    After a little research i found out that it is better to not always use the backbuffer format for textures.
    Since the backbuffer doesnt need an alpha channel, you shouldn't give it one.

    Okay this is how i've done it (so far):

    In 32bit mode:

    Initalize the device using D3DFMT_A8R8G8B8.
    Textures also use D3DFMT_A8R8G8B8.

    In 16 Bit mod:

    Initalize the device using D3DFMT_R5G6B5.
    Textures can be initalized using D3DFMT_A1R5G5B5 Or D3DFMT_A4R4G4B4. This depends on whether the user/gamedeveloper wants an alpha-channel in the texture.

    If anyone has some tips ore suggestions, please tell me.

    I didn't wrote a conversion routine yet. Its late (in holland 9:45 PM) so i won't write it today.
    But i will try tomorrow.

    If any of you guys has one, please post it :razz:
    Coders rule nr 1: Face ur bugz.. dont cage them with code, kill'em with ur cursor.

  4. #4

    [D3D] problems with transparency...

    Advice: Forget about 16bit color.

    Why make an additional effort on something that will not be used widely. Except some special cases you will not get much performance increase, but quality degradation is usually clearly visible.
    There are only 10 types of people in this world; those who understand binary and those who don't.

  5. #5

    [D3D] problems with transparency...

    Why make an additional effort on something that will not be used widely. Except some special cases you will not get much performance increase, but quality degradation is usually clearly visible.
    yeah i get your point, but i think its better te let the user decide.

    I wrote a routine wich converts colors from A8R8G8B8 format to A4R4G4B4:

    [pascal]
    function Convert8888To4444(Color: Cardinal): Word;
    var R,G,B,A: byte;
    begin
    B := Byte(Color);
    G := Byte(Color shr ;
    R := Byte(Color shr 16);
    A := Byte(Color shr 24);

    B := B div 16;
    G := G div 16;
    R := R div 16;
    A := A div 16;

    Result := (A shl 12) or (R shl or (G shl 4) or B;
    end;
    [/pascal]

    For some reason it still doesn't work. I have made some very basic bitmaps for testing, with easy-to-use colors (like pure red and pure green) and calculated the colors with my routine.
    but transparency still doesn't work.

    Can someone help me?? :cry:
    Coders rule nr 1: Face ur bugz.. dont cage them with code, kill'em with ur cursor.

  6. #6

    re-

    I have tried your function and seem it work great, i tried diferent components values from 0 to 255 and the function correctly return the value converted to 4 bit values. (255 become 15, 128 becom 8, 64 become 4, etc).

    So i am sure your bitmap pixels are correct converted, so when you say alpha is not working i guess you mean when rendering alpha textures it dosent appear background transparent; if so then the problem could be somthing else like the way you are setuping alpha blending in your d3d app.



    Why make an additional effort on something that will not be used widely. Except some special cases you will not get much performance increase, but quality degradation is usually clearly visible
    maybe in USA or most European countries people currently have todays ATI or Nvidia videocards in theirs system, but if the app is going to be internet downloaded then a lot others countrys will have also access to the app and they not necesary are equiped with lastest videocards.

    I live in Latin America (central america) and most office or home computer are equiped with average videocards; in my computer playing my dx8 app in 32bit color cuts down the frame rate to the half.

    However...i think the 16 bit mode D3DFMT_A4R4G4B4 is too low, it just give 16 values components color and it is not faster than other 16 bit color modes, you should use D3DFMT_A1R5G5B5 wich gives 32 values components, in my experience for enabling background alpha transparency in sprites or textures you just need store 1 bit for opaque/transparent state.


    good luck.

    tp

  7. #7

    [D3D] problems with transparency...

    chronozphere you should declare your "var R,G,B,A: byte;" variables as cardinals. Or better cast them to cardinals right before shl.

    Another (should be faster) way:
    [pascal]
    function Convert8888To4444(Color: Cardinal): Word;
    begin
    Result :=
    ((Color and ($F shl 4)) shr 4) or // B
    ((Color and ($F shl 12)) shr or // G
    ((Color and ($F shl 20)) shr 12) or // R
    ((Color and ($F shl 2) shr 16); // A
    end;
    [/pascal]
    There are only 10 types of people in this world; those who understand binary and those who don't.

  8. #8

    [D3D] problems with transparency...

    Hi and thanx for your replies.

    So i am sure your bitmap pixels are correct converted, .....
    owh i didn't wrote a routine that converts bitmap pixels yet. I simply dont know how to convert a TBitmap to A1R5G5B5 and then convert it to a texture

    I thought it would be good to load a texture and modify the alpha/transperacy bits for each pixel afterwards
    Just walk through the pixels and make a pixel transparent when its color is equal to the transparent color (e.g black).

    I wrote this method, but it doesn't work yet:
    [pascal]
    procedure TBF_Texture.ProcessTransparency(Transcol: Word);
    var surf: IDirect3dSurface8;
    HR : HResult;
    D3DRect: _D3DLOCKED_RECT;
    P: PWord; //pointer to the chunk of memory
    x,y: integer; //loop counters
    begin
    HR := fTexture.GetSurfaceLevel(0,surf);
    if Failed(HR) then
    begin
    ReportError(True,Self,E_TEXTURE_CANNOTGETLVL,HR);
    Exit;
    end;

    HR := Surf.LockRect(D3DRect,nil,D3DLOCk_NOSYSLOCK);
    if Failed(HR) then
    begin
    ReportError(True,Self,E_CANNOT_LOCK_SURFACE,HR);
    Exit;
    end else
    try
    for y:=0 to fHeight-1 do
    begin
    P := PWord(Dword(D3DRect.pBits) + D3DRect.Pitch * y);
    for x:=0 to fWidth-1 do
    begin
    //if color is the transparent color (exclude alpha bit)
    if ((P^ and $7FFF) = TransCol) then
    P^ := (P^ and $7FFF) //set the first bit to zero (transparent)
    else
    P^ := (P^ or $8000); //set the first bit to one (non-transperant)

    //select next color
    P := PWord(Dword(P) + 1);
    end;
    end;
    finally
    Surf.UnlockRect;
    end;
    end
    [/pascal]

    This method should set the first (alpha) pixel of a A1R5G5B5 texture to transparent, when its color is equal to the specified transparent color. But surface locking is a problem, it alwasy returns D3DERR_INVALIDCALL.

    I know.. I know... The pointer stuff in the above routine aint very good. I'am no pointer guru. :roll:

    When this method works i could modify it, so it can read the upperleft pixel and set all the pixels of the same color to transparent. Then the whole problem would be fixed .

    So if someone could help me with my code, or with converting the bitmap, i would be very happy.


    P.S. I also wrote a conversion routine for A1R5G5B5 colors. :lol: Here it is:

    [pascal]
    function Convert8888To1555(Color: Cardinal): Word;
    var R,G,B,A: word;
    begin
    B := Word(Color) and $01ff;
    G := Word(Color shr and $01ff;
    R := Word(Color shr 16) and $01ff;
    A := Word(Color shr 24) and $0001;

    B := B div 8;
    G := G div 8;
    R := R div 8;

    Result := (A shl 15) or (R shl 10) or (G shl 5) or B;
    end;
    [/pascal]

    @Clootie: I know this method could be optimized, like you showed me, but i'am not a bitshifting pro yet. BTW I looked at your code and it's a brilliant piece of bitshifting, if it works (wich i assume)
    I looked at
    Coders rule nr 1: Face ur bugz.. dont cage them with code, kill'em with ur cursor.

  9. #9

    [D3D] problems with transparency...

    Quote Originally Posted by chronozphere
    [pascal] HR := Surf.LockRect(D3DRect, nil, D3DLOCk_NOSYSLOCK);
    [/pascal]
    But surface locking is a problem, it alwasy returns D3DERR_INVALIDCALL.
    Textures created with D3DPOOL_DEFAULT or with D3DUSAGE_RENDERTARGET are not lockable. Verify your creation flags. Additionally you should install DirectX debug runtime and look at it's error messages

    @Clootie: I know this method could be optimized, like you showed me, but i'am not a bitshifting pro yet. BTW I looked at your code and it's a brilliant piece of bitshifting, if it works (wich i assume)
    I looked at
    I hope it works, but have not verified
    There are only 10 types of people in this world; those who understand binary and those who don't.

  10. #10

    [D3D] problems with transparency...

    Textures created with D3DPOOL_DEFAULT or with D3DUSAGE_RENDERTARGET are not lockable.
    Thanx for the hint.. I used D3DPOOL_DEFAULT.
    I changed it to D3DPOOL_MANAGED, but i think this is a bit inefficient because its now also stored in system memory. Are there any good alternatives??

    Oke.. The locking and unlocking works now, but transparency doesn't work OK yet. I am now able to do some pixel-processing, and i noticed that i was only processing the left half of my texture.

    I retrieved the width using:

    [pascal]
    fTexture.GetLevelDesc(0,Desc);
    fWidth := Desc.Width;
    fHeight := Desc.Height;
    [/pascal]

    And i used it in my loop.
    I tried this:

    [pascal]
    for x:=0 to fWidth*2-1 do
    begin
    [/pascal]

    And it worked... without any AV or other error.
    So it looks like the texture is still using 32 bits per pixel because the routine uses WORD's.
    Its very weird because i created it using A1R5G5B5.

    How is this possible?? :scratch: :lol:

    P.S i will continue, playing with this code. I will keep you informed.
    Coders rule nr 1: Face ur bugz.. dont cage them with code, kill'em with ur cursor.

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
  •