为了保留前景中的alpha值,请使用以下方法:
(color>>1)&0x7F7F7F | (color&0xFF000000)
(对Wimmel在评论中提供的建议进行微调。)
我认为这里的“学习曲线”是您使用Shift和Shift返回来屏蔽位。您应该使用
&
和掩码值。
对于更一般的解决方案(其中
0.0<=factor<=1.0
):
void PixelRenderer::applyLight(Uint32& color, double factor){
Uint32 alpha=color&0xFF000000;
Uint32 red= (color&0x00FF0000)*factor;
Uint32 green= (color&0x0000FF00)*factor;
Uint32 blue=(color&0x000000FF)*factor;
color=alpha|(red&0x00FF0000)|(green&0x0000FF00)|(blue&0x000000FF);
}
请注意,在执行乘法之前没有必要将组件移动到低位。
最终,您可能会发现瓶颈是浮点数转换和算术运算。
为了减少这种情况,您应该考虑以下两种方法之一:
将其减少到比例因子中,例如0-256范围内。
预计算factor*component
作为256个元素数组,并“选择”其中的组件。
我建议使用257个范围,因为您可以按如下方式获得因子:
对于更一般的解决方案(其中0<=factor<=256
):
void PixelRenderer::applyLight(Uint32& color, Uint32 factor){
Uint32 alpha=color&0xFF000000;
Uint32 red= ((color&0x00FF0000)*factor)>>8;
Uint32 green= ((color&0x0000FF00)*factor)>>8;
Uint32 blue=((color&0x000000FF)*factor)>>8;
color=alpha|(red&0x00FF0000)|(green&0x0000FF00)|(blue&0x000000FF);
}
这是一个可运行的程序,展示了第一个例子:
#include <stdio.h>
#include <inttypes.h>
typedef uint32_t Uint32;
Uint32 make(Uint32 alpha,Uint32 red,Uint32 green,Uint32 blue){
return (alpha<<24)|(red<<16)|(green<<8)|blue;
}
void output(Uint32 color){
printf("alpha=%"PRIu32" red=%"PRIu32" green=%"PRIu32" blue=%"PRIu32"\n",(color>>24),(color&0xFF0000)>>16,(color&0xFF00)>>8,color&0xFF);
}
Uint32 applyLight(Uint32 color, double factor){
Uint32 alpha=color&0xFF000000;
Uint32 red= (color&0x00FF0000)*factor;
Uint32 green= (color&0x0000FF00)*factor;
Uint32 blue=(color&0x000000FF)*factor;
return alpha|(red&0x00FF0000)|(green&0x0000FF00)|(blue&0x000000FF);
}
int main(void) {
Uint32 color1=make(156,100,50,20);
Uint32 result1=applyLight(color1,0.9);
output(result1);
Uint32 color2=make(255,255,255,255);
Uint32 result2=applyLight(color2,0.1);
output(result2);
Uint32 color3=make(78,220,200,100);
Uint32 result3=applyLight(color3,0.05);
output(result3);
return 0;
}
预期输出是:
alpha=156 red=90 green=45 blue=18
alpha=255 red=25 green=25 blue=25
alpha=78 red=11 green=10 blue=5
double
作为参数将整数除以二?难怪运行速度很慢。除了位掩码与移位操作之外的所有内容,都不及整型向双精度浮点型转换和双精度浮点型向整型转换所耗费的时间(特别是由于愚蠢的“朝零方向舍入”的语义要求在x87上进行大量操作)。 - Matteo Italia