RGBA像素数据转换为D3DLOCKED_RECT

时间:2017-05-30 06:44:46

标签: c++ pixels rgba direct3d9

我正在尝试使用以下代码使用子图像更新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);
}

输出结果如何:

enter image description here

输出应该是什么样的: enter image description here

2 个答案:

答案 0 :(得分:2)

您假设通过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.

答案 1 :(得分:0)

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

可以加快速度吗?

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