Sign in to follow this  
arc4nis

Swapping texture (or surface) Alpha channel with RGB channel

Recommended Posts

arc4nis    129
I'm creating a font rendering engine (with DirectX9 and C++), while this summer update upgraded the ID3DXFont functionality I'm still not happy with the performance, since I'll use lots of text in my game. However I want the quality that the ID3DXFont bring. So... My Game engine creates an array of 256 textures (LPDIRECT3DTEXTURE9 g_tFont[255]), in each of that texture I render one character from the ASCII code, so I have 256 textures filled with all the charactes of the ASCII code. Now, I want to swap the RGB channel of the texture with the alpha channel (the textures are actually black bacground with white characters on them), so I can render them with alpha trasparency. So the question is... Is there any way to swap the Alpha channel with the RGB channel of a texture (or a surface) and possibly without using pixel shaders please :D. Or maybe any other idea how can I get it working?

Share this post


Link to post
Share on other sites
Evil Steve    2017
Quote:
Original post by arc4nis
I'm creating a font rendering engine (with DirectX9 and C++), while this summer update upgraded the ID3DXFont functionality I'm still not happy with the performance, since I'll use lots of text in my game. However I want the quality that the ID3DXFont bring.

So... My Game engine creates an array of 256 textures (LPDIRECT3DTEXTURE9 g_tFont[255]), in each of that texture I render one character from the ASCII code, so I have 256 textures filled with all the charactes of the ASCII code.
Firstly, don't use 256 textures. That's a great way to utterly murder your frame rate. If you do that, you can only render one letter in one call to DrawPrimitive(), and that's an extremely expensive thing to do. If you're rendering "a lot of text", I'm willing to bet that where ID3DXFont would get 100 FPS, you'll get less than 10 FPS using this method.

Quote:
Original post by arc4nis
Now, I want to swap the RGB channel of the texture with the alpha channel (the textures are actually black bacground with white characters on them), so I can render them with alpha trasparency.

So the question is... Is there any way to swap the Alpha channel with the RGB channel of a texture (or a surface) and possibly without using pixel shaders please :D.
Or maybe any other idea how can I get it working?

Remember that RGB is not a channel, it's 3 channels. You can:
  • Lock the texture and copy the bits over manually
  • Use a source format that includes alpha like PNG or DDS
  • Use a colour key when you load the texture, and let D3DX do the hard work for you

    Share this post


    Link to post
    Share on other sites
    arc4nis    129
    Thanks Evil Steve.

    I'm using Sprites to render the text, and this gives me a good performance boost, I just did 500 Sprite->Draw calls per frame and the FPS dropped from 587 to 558.
    All those calls where made in the same Sprite->Begin / Sprite->End structure.
    IMHO it'll give me better performance than using ID3DXFont.

    I cant use a format like PNG or DDS, becouse I create the textures with my game engine (I use ID3DXFont to render the text on a surface, then I trasform the surface in the texture, that goes for all the 256 textures, this is done only one time when the font is being initialized).
    I cant use color keys since they dont give partial trasparency, I need to alphablend the sprite.

    Then I'm left with only one option, to lock the texture and copy the bits manually, but how to do that, I know how to lock/unlock, but what to do in between? (google doesnt give the answers I'm searching for)

    Any help is appreciated :)

    Share this post


    Link to post
    Share on other sites
    arc4nis    129
    In the tutorials of Drunken Hyena I found this piece of code that is supposed to take the red channel and write it on the alpha channel, I have implemented it in my game, it compiles fine, however it makes the game crash.

    LINK to Drunken Hyena tutorial: http://www.drunkenhyena.com/pages/projects/d3d8/dhGrayScale.php

    CODE:


    D3DLOCKED_RECT d3d_rect;
    g_tFont[80]->LockRect(0, &d3d_rect, NULL, D3DLOCK_DISCARD);

    D3DSURFACE_DESC g_dSurface;
    g_tFont[80]->GetLevelDesc(0,&g_dSurface);

    DWORD x,y;
    DWORD pitch_diff;
    DWORD p_width = g_dSurface.Width;
    DWORD p_height = g_dSurface.Height;

    //When we lock our texture, we will get a pointer to our 32-bit ARGB data. Note that
    //because of the byte ordering on Intel we would specify a 32-bit value as 0xAARRGGBB
    //But our structure is laid out in reverse order BGRA. Those wacky Intel-ians.
    struct my_colour{
    unsigned char blue;
    unsigned char green;
    unsigned char red;
    unsigned char alpha;
    } *col;


    //Sometimes extra space needs to be allocated for each 'row' of texture data.
    //The width is how wide the data is per row, the pitch is how much is actually allocated.
    //The pitch will always be at least as big as the width, but may be larger if the driver
    //reqires data to be on a specific memory alignment boundary.
    //
    //pitch_diff is the amount we have to add to skip the non-data space to reach the next line
    pitch_diff=(d3d_rect.Pitch/4) - p_width;

    //Using a pointer to 'my_colour' simplifies our dealings with the various colour components
    col=(my_colour *)d3d_rect.pBits;

    //Now we loop through the whole texture setting the alpha component equal to the red component.
    //Since our image was grayscale, we could have used the blue or green instead of red and it
    //would have made no difference.
    for(y=0;y < p_height;y++){
    for(x=0;x < p_width; x++){
    col->alpha=col->red;
    col++;
    }
    //Add pitch_diff to skip to the next line.
    col+=pitch_diff;
    }

    g_tFont[80]->UnlockRect(0);



    Share this post


    Link to post
    Share on other sites

    Create an account or sign in to comment

    You need to be a member in order to leave a comment

    Create an account

    Sign up for a new account in our community. It's easy!

    Register a new account

    Sign in

    Already have an account? Sign in here.

    Sign In Now

    Sign in to follow this