RGBA像素数据转化为D3DLOCKED_RECT

RGBA pixel data into D3DLOCKED_RECT

我正在尝试使用以下代码更新带有子图像的 128x128 D3DLOCKED_RECT,但它似乎将它们沿着顶部压扁,X 偏移量被忽略并且 y 偏移量减少了 60% .

我也尝试过使纹理大小正确,并使用 RECT 将其复制到正确位置的 128x128 纹理中,但是这非常慢,而且在我尝试时似乎无法正常工作。一定有办法使用原始像素数据来做到这一点吗?

任何帮助将不胜感激:)

编辑:我使用下面的代码让它半工作,现在位置和大小都是正确的。但它只使用蓝色通道,而且一切都是灰度(蓝度?)

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;
    }
}'

编辑结束

创建 128x128 纹理后的测试调用:

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 )

更新函数:

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);
}

输出结果如下:

输出应该是这样的:

您假设可通过 lockrect.pBits 访问的数据在内存中是线性的。通常情况并非如此。相反,您的行之间有一个恒定的偏移量,由 lockrect.Pitch 值定义。

要获取目标中像素的地址,请使用:

byte * destAddr = (lockrect.pBits + y * lockrect.Pitch + 4 * x); 
// for 32 bit images. For other formats adjust the hard-coded 4.

感谢您的帮助:),最终以下代码有效:

可以让它更快吗?

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;
    }
}