如何移位u16 *的数据?

时间:2012-01-01 09:28:46

标签: c++ opengl bit-manipulation

对不起,如果这没有任何意义,但我正在尽我所能去了解它。

所以我基本上有一个指向openGL中纹理数据的指针,它是16 bpp(pcx.image.data16),我需要打开每个像素的alpha位。所以我想出了这个,但你可以说它真的很糟糕。

for(int i = 0; i < (TEXTURE_SIZE_128 * TEXTURE_SIZE_128); i++){
        pcx.image.data16 |=  1 << ((16 * i) + 15);
    }

我收到了这些错误:

c:/Users/me/Desktop/neronds/source/neroedge.cpp:40:43: error: invalid operands of types 'u16* {aka short unsigned int*}' and 'int' to binary 'operator|'
c:/Users/me/Desktop/neronds/source/neroedge.cpp:40:43: error:   in evaluation of 'operator|=(u16* {aka short unsigned int*}, int)'

如何修复这些错误,我是否正在改变每个像素的alpha位?

2 个答案:

答案 0 :(得分:5)

试试这个:

for(unsigned i = 0; i < (TEXTURE_SIZE_128 * TEXTURE_SIZE_128); i++)
    {
        constexpr u16 ALPHA_BIT = 1 << 15;
        pcx.image.data16[i] |= ALPHA_BIT;
    }

如果您的编译器尚不支持constexpr(c ++ 11功能),请改用const

答案 1 :(得分:0)

您已经获得了如何修复它的答案,但没有解释为什么您的代码错误。我们来看看这段代码:

pcx.image.data16 |=  1 << ((16 * i) + 15);

显然,你想到这个想法,编译器将数组看作一个长串的单个位。你也误以为你可以任意长时间地移位。然而,这不是C和C ++的工作方式。 bitshift仅适用于所应用类型的宽度。根据参与类型,编译器使用某些类型的规则。所以让我们分解类型:

(int) << (((int) * (int)) + (int));

好的,那里只有int,因此操作的类型将是int。根据平台,只有有限的位数。但为方便起见,int有64位。这意味着任何超过65位的1的左移都会将该位移出可用位,并且您将获得零位设置。但是我们还没有完成。

之后,您将int分配给uint16_t。现在这是下一个误解。指定了uint16_t类型以提供至少16位(C在这些方面不是很精确,因为它可以在平台上运行,其中字大小不是8位的倍数)。但是为了这个解释,让我们假设它正好是16位。作业

(uint16_t) = (int)

强制,即它丢弃了这些位,不符合L值。

最后但并非最不重要:表达式pcx.image.data16是一个指针。该指针指向数据数组的第一个元素。通过指定此指针,您只需更改此指针,而不是它指向的数据。所以你必须取消引用指针。您可以通过在指针前添加*或附加索引运算符[…]来取消引用指针。 请注意*[0]相同!所以,如果你做了

 *pcx.image.data16;

这只会取消引用第一个数组元素(可能有16位,但可能更多)。无论如何:你不能为它分配一个更大的位向量,它“包装”到下一个元素中(这是一件好事!)。

因此,解决方案是迭代数组的所有元素,并为每个元素集添加额外的位:

for(int i = 0; i < (TEXTURE_SIZE_128 * TEXTURE_SIZE_128); i++){
    pcx.image.data16[i] |=  1 << 15;
}