Search code examples
c++pixelrgbadirect3d9

RGBA pixel data into D3DLOCKED_RECT


I'm trying to update a 128x128 D3DLOCKED_RECT with sub images using the following code, but it seems to squish them down along the top, the X offset is ignored and the y offset is 60 percent off.

I've also tried to make the texture the correct size and copy it into a 128x128 texture at the correct location using RECT, however this is very slow and didn't seem to work correctly when I attempted it. There must be way to do it using the raw pixel data?

Any help would be much appreciated :)

EDIT: I got it semi working using the below code, the locations are now correct and the sizes. But it's only using the blue channel and everything is grey scale (blue scale?)

srcdata = (byte *) pixels;

dstdata = (unsigned int *)lockrect.pBits;

for (y = yoffset; y < (yoffset + height); y++)
{
    for (x = xoffset; x < (xoffset + width); x++)
    {
        dstdata[ ( y * lockrect.Pitch / dstbytes + x ) + 0] = (unsigned int)srcdata[0];
        dstdata[ ( y * lockrect.Pitch / dstbytes + x ) + 1] = (unsigned int)srcdata[1];
        dstdata[ ( y * lockrect.Pitch / dstbytes + x ) + 2] = (unsigned int)srcdata[0];
        dstdata[ ( y * lockrect.Pitch / dstbytes + x ) + 3] = (unsigned int)srcdata[3];

        srcdata += srcbytes;
    }
}'

END Edit

Test call after creating the 128x128 texture:

int x, y;
byte    temp[132*132*4];

// Test texture (pink and black checker)
for( y = 0; y < 16; y++ )
{
    for( x = 0; x < 16; x++ )
    {
        if(( y < 8 ) ^ ( x < 8 ))
            ((uint *)&temp)[y*16+x] = 0xFFFF00FF;
        else ((uint *)&temp)[y*16+x] = 0xFF000000;
    }
}

UpdateSubImage (0, 0, 16, 16, temp )

The update Fuction:

void UpdateSubImage (int xoffset, int yoffset, int width, int height, const 
GLvoid *pixels)
{
int x, y;
int srcbytes = 4; //Hard coded for now, as all tests are RGBA
int dstbytes = 4; // ^
byte *srcdata;
byte *dstdata;

D3DLOCKED_RECT lockrect;

pTexture->LockRect( 0, &lockrect, NULL, 0);

srcdata = (byte *) pixels;
dstdata = (byte *) lockrect.pBits;
dstdata += (yoffset * width + xoffset) * dstbytes;

for (y = yoffset; y < (yoffset + height); y++)
{
    for (x = xoffset; x < (xoffset + width); x++)
    {
        if (srcbytes == 1)
        {
            if (dstbytes == 1)
                dstdata[0] = srcdata[0];
            else if (dstbytes == 4)
            {
                dstdata[0] = srcdata[0];
                dstdata[1] = srcdata[0];
                dstdata[2] = srcdata[0];
                dstdata[3] = srcdata[0];
            }
        }
        else if (srcbytes == 3)
        {
            if (dstbytes == 1)
                dstdata[0] = ((int) srcdata[0] + (int) srcdata[1] + (int) srcdata[2]) / 3;
            else if (dstbytes == 4)
            {
                dstdata[0] = srcdata[2];
                dstdata[1] = srcdata[1];
                dstdata[2] = srcdata[0];
                dstdata[3] = 255;
            }
        }
        else if (srcbytes == 4)
        {
            if (dstbytes == 1)
                dstdata[0] = ((int) srcdata[0] + (int) srcdata[1] + (int) srcdata[2]) / 3;
            else if (dstbytes == 4)
            {
                dstdata[0] = srcdata[2];
                dstdata[1] = srcdata[1];
                dstdata[2] = srcdata[0];
                dstdata[3] = srcdata[3];
            }
        }

        // advance
        srcdata += srcbytes;
        dstdata += dstbytes;
    }
}

pTexture->UnlockRect(0);
}

What the output looks like:

enter image description here

What the output should look like: enter image description here


Solution

  • Thanks for the help :), in the end the following code worked:

    Can it be made faster?

    for (y = yoffset; y < (yoffset + height); y++)
    {
        for (x = xoffset; x < (xoffset + width); x++)
        {
            ARGB pixel;
            pixel.r = srcdata[0];
            pixel.g = srcdata[1];
            pixel.b = srcdata[2];
            pixel.a = srcdata[3];
            memcpy( &dstdata[lockrect.Pitch * y + dstbytes * x], &pixel, dstbytes );
    
            srcdata += srcbytes;
        }
    }