Project1
标题: 关于RM的色调算法 [打印本页]
作者: 2719358 时间: 2012-2-9 17:23
标题: 关于RM的色调算法
本帖最后由 2719358 于 2012-2-9 17:28 编辑
由于我目前正在开发引擎的缘故,请问RM里的色调(更改画面色调)的原理是什么.
我自己用C+嵌入汇编写了一个但不完美,
1.在任意值为0xff时并不会变成这种颜色,这是预想内的,因为我现在的算法是:最终颜色=颜色一/2+颜色2/2
需要手动判断每个分量是否为0xff吗
2.我这个只能使一张图片变色,而不能对整个画面变色,RM是每帧都执行一遍函数为画面变色吗?那样的话效率会不会很低?
3.无法变回原色
翻译成Ruby:
def tcolor(c1,c2)
r1=(c1>>16)&0xff
g1=(c1>>8 )&0xff
b1=(c1)&0xff
r2=(c2>>16)&0xff
g2=(c2>>8 )&0xff
b2=(c2)&0xff
return ((r1/2+r2/2)<<16)+((g1/2+g2/2)<<8)+(b1/2+b2/2)
end
def set_color(r,g,b)
c=(r<<16)+(g<<8)+b
LockSurface(pScreen);
Width.times{|i|
Height.times{|j|
putpixel(i,j,Tcolor(c,getpixel(i,j)))
}
}
UnlockSurface(pScreen);
end
def tcolor(c1,c2)
r1=(c1>>16)&0xff
g1=(c1>>8 )&0xff
b1=(c1)&0xff
r2=(c2>>16)&0xff
g2=(c2>>8 )&0xff
b2=(c2)&0xff
return ((r1/2+r2/2)<<16)+((g1/2+g2/2)<<8)+(b1/2+b2/2)
end
def set_color(r,g,b)
c=(r<<16)+(g<<8)+b
LockSurface(pScreen);
Width.times{|i|
Height.times{|j|
putpixel(i,j,Tcolor(c,getpixel(i,j)))
}
}
UnlockSurface(pScreen);
end
C+内嵌汇编:
Uint32 Tcolor(Uint32 c1,Uint32 c2)
{
Uint8 r1;
Uint8 g1;
Uint8 b1;
Uint8 r2;
Uint8 g2;
Uint8 b2;
Uint32 rgb;
_asm
{
;取得各个RGB分量
;********
mov eax,c1
mov cl,16
shr eax,cl
mov r1,al
;********
mov eax,c1
mov cl,8
shr eax,cl
mov g1,al
;********
mov eax,c1
mov b1,al
;********
mov eax,c2
mov cl,16
shr eax,cl
mov r2,al
;*********
mov eax,c2
mov cl,8
shr eax,cl
mov g2,al
;*********
mov eax,c2
mov b2,al
;*****************************************
;开始处理 R
mov ax,0
mov al,r1
mov cl,2
div cl
mov bl,al
mov al,r2
mov cl,8
div cl
add al,bl
mov ah,0
mov cl,16
shl al,cl
mov ebx,eax
;*****************************************
;开始处理 G
mov eax,0
mov al,g1
mov cl,2
div cl
mov ah,0
mov bh,al
mov al,g2
mov cl,2
div cl
mov ah,0
add bh,al
;*****************************************
;开始处理 B
mov al,b1
mov cl,2
div cl
mov ah,0
mov bl,al
mov al,b2
mov cl,2
div cl
add bl,al
;处理完毕
mov rgb,ebx
}
return rgb;
}
Uint32 Tcolor(Uint32 c1,Uint32 c2)
{
Uint8 r1;
Uint8 g1;
Uint8 b1;
Uint8 r2;
Uint8 g2;
Uint8 b2;
Uint32 rgb;
_asm
{
;取得各个RGB分量
;********
mov eax,c1
mov cl,16
shr eax,cl
mov r1,al
;********
mov eax,c1
mov cl,8
shr eax,cl
mov g1,al
;********
mov eax,c1
mov b1,al
;********
mov eax,c2
mov cl,16
shr eax,cl
mov r2,al
;*********
mov eax,c2
mov cl,8
shr eax,cl
mov g2,al
;*********
mov eax,c2
mov b2,al
;*****************************************
;开始处理 R
mov ax,0
mov al,r1
mov cl,2
div cl
mov bl,al
mov al,r2
mov cl,8
div cl
add al,bl
mov ah,0
mov cl,16
shl al,cl
mov ebx,eax
;*****************************************
;开始处理 G
mov eax,0
mov al,g1
mov cl,2
div cl
mov ah,0
mov bh,al
mov al,g2
mov cl,2
div cl
mov ah,0
add bh,al
;*****************************************
;开始处理 B
mov al,b1
mov cl,2
div cl
mov ah,0
mov bl,al
mov al,b2
mov cl,2
div cl
add bl,al
;处理完毕
mov rgb,ebx
}
return rgb;
}
void SetColor(Uint8 r,Uint8 g,Uint8 b)
{
Uint32 c = (r<<16)+(g<<8)+b;
LockSurface(pScreen);
for (int i=0;i<Width();i++)
{
for (int j=0;j<Height();j++)
{
putpixel(i,j,Tcolor(c,getpixel(i,j)));
}
}
UnlockSurface(pScreen);
}
void SetColor(Uint8 r,Uint8 g,Uint8 b)
{
Uint32 c = (r<<16)+(g<<8)+b;
LockSurface(pScreen);
for (int i=0;i<Width();i++)
{
for (int j=0;j<Height();j++)
{
putpixel(i,j,Tcolor(c,getpixel(i,j)));
}
}
UnlockSurface(pScreen);
}
作者: 灼眼的夏娜 时间: 2012-2-14 18:15
Tone.new(r, g, b, gray)
原像素颜色:r、g、b
经过Tone调整后颜色为:
grayfull = (r * 38 + g * 75 + b * 15) >> 7
r = tone.r + r + (grayfull - r) * tone.gray/ 256
g = tone.g+ g + (grayfull - g) * tone.gray/ 256
b = tone.b+ b + (grayfull - b) * tone.gray/ 256
作者: 2719358 时间: 2012-2-15 08:37
灼眼的夏娜 发表于 2012-2-14 18:15
Tone.new(r, g, b, gray)
原像素颜色:r、g、b
另外,这个需要每帧调用一次吗
作者: 灼眼的夏娜 时间: 2012-2-15 12:11
2719358 发表于 2012-2-15 08:37
另外,这个需要每帧调用一次吗
这个得看你引擎如何实现了,比如如果修改位图数据实现色调那么肯定不用每帧调用,如果你采用shader等实现(那么就每帧执行吧(:
作者: viktor 时间: 2012-2-28 16:14
本帖最后由 viktor 于 2012-2-28 16:16 编辑
其实不必自己实现这些基本运算吧……应该有合适的图形库的
如果一定要自己做基本运算的话 饱和运算可以尝试一下mmx指令。不好用但是很强力。
(以下代码和问题无关。)- __m64 ALIGN a, b, z=_mm_setzero_si64(); //pxor
- a=_mm_cvtsi32_si64(*src); b=_mm_cvtsi32_si64(*dest); //movd
- a=_mm_unpacklo_pi8(a, z); b=_mm_unpacklo_pi8(b, z); //punpcklbw
- b=_mm_mullo_pi16(a, b); //pmullw
- b=_mm_srli_pi16(b, 8); //psrlw
- b=_mm_packs_pu16(b, z); //packuswb
- *dest=_mm_cvtsi64_si32(b); //movd
- _mm_empty(); //emms
复制代码 ‘‘──viktor于2012-2-28 16:15补充以下内容
另外:求DX 2D渲染教程…………我有点想把RGSS的渲染改成用DX 不过完全不知道怎么做
’’
作者: 2719358 时间: 2012-3-25 15:28
灼眼的夏娜 发表于 2012-2-14 18:15
Tone.new(r, g, b, gray)
原像素颜色:r、g、b
貌似tone.r+r以后>255了= =
(grayfull - r) * tone.gray/ 256也没有让他比255小= =
tone.r r grafull tone.gray 都是uint8
作者: yangff 时间: 2012-3-29 19:28
其实Shadow是个好东西……反正速度够快,无所谓的。。
作者: 2719358 时间: 2012-4-7 19:32
@灼眼的夏娜
前辈好,我经过几次试验变换色调已经没有问题了,但是怎么才能变回来呢?
作者: 精灵使者 时间: 2012-4-9 09:53
本帖最后由 精灵使者 于 2012-4-9 09:54 编辑
更改色调为(0,0,0,0)
作者: 2719358 时间: 2012-4-9 11:07
精灵使者 发表于 2012-4-9 09:53
更改色调为(0,0,0,0)
啊,在Rm里就变回来了,但是在我的引擎里颜色不变= =
@灼眼的夏娜
难道要多存储一个Bitmap么,除了 Sprite.Bitmap外还需要在Sprite内多存储一个么,每次变换都按照多存的变换?
欢迎光临 Project1 (https://rpg.blue/) |
Powered by Discuz! X3.1 |