【问题标题】:RGBA pixel data into D3DLOCKED_RECTRGBA 像素数据转换为 D3DLOCKED_RECT
【发布时间】:2017-05-30 06:44:46
【问题描述】:

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

输出的样子:

输出应该是什么样子:

【问题讨论】:

  • 在您的编辑中,检查第三行srcdata[0],应该是[2]。此外,如果dstdataint*,那么stdata[ ( y * lockrect.Pitch / dstbytes + x ) + 1] 可能是下一个像素。这意味着赋值只是设置int的下半部分,也就是ARGBBLUE通道

标签: c++ pixels rgba direct3d9


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    感谢您的帮助:),最后以下代码起作用了:

    可以做得更快吗?

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

    【讨论】:

    • 当然,但你最好为此提出一个新问题。
    猜你喜欢
    • 2012-05-03
    • 1970-01-01
    • 1970-01-01
    • 2012-07-08
    • 2021-12-17
    • 1970-01-01
    • 1970-01-01
    • 2017-07-19
    • 2020-08-22
    相关资源
    最近更新 更多