Direct Texture Manipulation

If you have any questions on programming, this is the place to ask them, whether you're a newbie or an experienced programmer. Discussion on programming in general is also welcome. We will help you with programming homework, but we will not do your work for you! Any porting requests must be made in Developmental Ideas.
Post Reply
Jae686
Insane DCEmu
Insane DCEmu
Posts: 112
https://www.artistsworkshop.eu/meble-kuchenne-na-wymiar-warszawa-gdzie-zamowic/
Joined: Sat Sep 22, 2007 9:43 pm
Location: Braga - Portugal
Has thanked: 0
Been thanked: 0

Direct Texture Manipulation

Post by Jae686 »

Good Evening.

I've been attempting to directly modify the texture returned glutCopyBufferToTexture(); function, but I've been unable to access and modify its contents via the pvr_ptr_t.

In this example I'm attempting to convert a a RGB 565 texture to gray scale (without changing the texture format of course)

Code: Select all

void pvr_to_grayscale(pvr_ptr_t texture_ptr, long unsigned int w, long unsigned int h)
{
    uint16 bytemask_r = 0xF800 ;
    uint16 bytemask_g = 0x7E0 ;
    uint16 bytemask_b = 0x1F ;

    uint16 r = 0 ;
    uint16 g = 0 ;
    uint16 b = 0 ;

    uint16 grey = 0 ;  

    unsigned int i, j = 0;

    unsigned int pixel_count = h * w ;

    for ( ; i < w ; i++)
    {
        for( ; j < h ; j++)
        {
            r =   ((uint16**) texture_ptr[i][j] & bytemask_r ) >> 11 ;
            g = ( ((uint16**) texture_ptr[i][j]) & bytemask_g ) >> 5 ;
            b = ( ((uint16**) texture_ptr[i][j]) & bytemask_b ) ;

            grey = (r+g+b)/3 ;

            (uint16**)texture_ptr[i][j] = (grey << 11) ;
            (uint16**)texture_ptr[i][j] = ((uint16**)texture_ptr[i][j] | (grey << 5)) ;
            (uint16**)texture_ptr[i][j] = (uint16**)texture_ptr[i][j] | grey ;
        }
    }

}


But I cant access it texture that way since i get the following error on compile :

Code: Select all

jaerder@jaerder-G50V ~/development/Projectos Software/vidfdc/dreamcast $ make
rm -f bin/main.elf romdisk.*
kos-cc  -c src/dc_render.c -o src/dc_render.o
src/dc_render.c: In function ‘pvr_to_grayscale’:
src/dc_render.c:63:42: warning: dereferencing ‘void *’ pointer [enabled by default]
src/dc_render.c:63:45: error: subscripted value is neither array nor pointer nor vector
src/dc_render.c:64:42: warning: dereferencing ‘void *’ pointer [enabled by default]
src/dc_render.c:64:45: error: subscripted value is neither array nor pointer nor vector
src/dc_render.c:65:42: warning: dereferencing ‘void *’ pointer [enabled by default]
src/dc_render.c:65:45: error: subscripted value is neither array nor pointer nor vector
src/dc_render.c:69:34: warning: dereferencing ‘void *’ pointer [enabled by default]
src/dc_render.c:69:37: error: subscripted value is neither array nor pointer nor vector
src/dc_render.c:70:34: warning: dereferencing ‘void *’ pointer [enabled by default]
src/dc_render.c:70:37: error: subscripted value is neither array nor pointer nor vector
src/dc_render.c:70:65: warning: dereferencing ‘void *’ pointer [enabled by default]
src/dc_render.c:70:68: error: subscripted value is neither array nor pointer nor vector
src/dc_render.c:71:34: warning: dereferencing ‘void *’ pointer [enabled by default]
src/dc_render.c:71:37: error: subscripted value is neither array nor pointer nor vector
src/dc_render.c:71:64: warning: dereferencing ‘void *’ pointer [enabled by default]
src/dc_render.c:71:67: error: subscripted value is neither array nor pointer nor vector
Any suggestions ?
User avatar
BlueCrab
The Crabby Overlord
The Crabby Overlord
Posts: 5664
Joined: Mon May 27, 2002 11:31 am
Location: Sailing the Skies of Arcadia
Has thanked: 9 times
Been thanked: 69 times
Contact:

Re: Direct Texture Manipulation

Post by BlueCrab »

You need to cast the pointer before you try to index it. Something like this should work:

Code: Select all

*(((uint16 *)texture_ptr) + (i * w) + j) = (grey << 11) | (grey << 5) | grey;
Jae686
Insane DCEmu
Insane DCEmu
Posts: 112
Joined: Sat Sep 22, 2007 9:43 pm
Location: Braga - Portugal
Has thanked: 0
Been thanked: 0

Re: Direct Texture Manipulation

Post by Jae686 »

Thank you BlueCrab!
It worked after this edit was suggested :

Code: Select all

void pvr_to_grayscale(pvr_ptr_t texture_ptr, long unsigned int w, long unsigned int h)
{
    uint16** txt_ptr = texture_ptr;

    uint16 bytemask_r = 0xF800 ;
    uint16 bytemask_g = 0x7E0 ;
    uint16 bytemask_b = 0x1F ;

    uint16 r = 0 ;
    uint16 g = 0 ;
    uint16 b = 0 ;

    uint16 grey = 0 ;  

    unsigned int i, j = 0;

  

    for ( ; i < w ; i++)
    {
        for( ; j < h ; j++)
        {
            r =   (txt_ptr[i][j] & bytemask_r ) >> 11 ;
            g =   (txt_ptr[i][j] & bytemask_g ) >> 5 ;
            b =   (txt_ptr[i][j] & bytemask_b ) ;

            grey = (r+g+b)/3 ;

            txt_ptr[i][j] = (grey << 11) ;
            txt_ptr[i][j] = ( txt_ptr[i][j] | (grey << 5)) ;
            txt_ptr[i][j] = txt_ptr[i][j] | grey ;
        }
    }

}
I wonder why the texture continues to be in color. Should I bind the texture again or create another texture ?
If I have to create another texture in run-time I suppose it would not be very efficient....
User avatar
BlueCrab
The Crabby Overlord
The Crabby Overlord
Posts: 5664
Joined: Mon May 27, 2002 11:31 am
Location: Sailing the Skies of Arcadia
Has thanked: 9 times
Been thanked: 69 times
Contact:

Re: Direct Texture Manipulation

Post by BlueCrab »

Short version:
I'm pretty sure that the way you're doing it (with a uint16 **) is not going to work. Try it the way I suggested and see if that works.

Longer version:
I believe that the C standard treats a double-pointer like what you have way differently than you'd be expecting. The compiler doesn't know the width of a row, so it can't treat things like it would a 2D array. With a double-pointer, you can think of it doing something like this:

Code: Select all

uint16 **ptr = /* SOMETHING */;

uint16 *ptr2 = ptr[i]; /* i.e, it's expecting to find another pointer here -- this will NOT be the case in your code. */
ptr2[j] = /* SOMETHING ELSE */;
I'm not entirely sure that really explains it well to anyone but me...
User avatar
Quzar
Dream Coder
Dream Coder
Posts: 7499
Joined: Wed Jul 31, 2002 12:14 am
Location: Miami, FL
Has thanked: 4 times
Been thanked: 10 times
Contact:

Re: Direct Texture Manipulation

Post by Quzar »

For sure double pointers do not work that way. A double pointer is a pointer to a pointer. You need to feed the row length*rows as an offset in order for it to know.
"When you post fewer lines of text than your signature, consider not posting at all." - A Wise Man
Post Reply