|
本帖最后由 ancientcc 于 2017-3-8 09:25 编辑
- int SDL_SetTextureAlphaMod(SDL_Texture * texture, Uint8 alpha);
- int SDL_SetTextureColorMod(SDL_Texture * texture, Uint8 r, Uint8 g, Uint8 b);
复制代码
SDL_SetTextureAlphaMod设置rgba四分量中a分量的调制(乘法)值。SDL_SetTextureColorMod设置rgba四分量中r、g、b分量的调制值。把它们一块使用实现了让下一次渲染(SDL_RenderCopy/SDL_RenderCopyEx)时可使用这里设置的调制值,从而实现修改颜色。
但是,由于r、g、b、a类型是uint8_t(见SDL_Texture),意味着最大只能是255!这函数只能把分量变小,不能变大。
SDL对这两函数的处理流程。
- SDL_SetTextureAlpha/ColorMod时,a、r、g、b赋给texture的a、r、g、b。
- GLES2_SetupCopy时,发现texture的a、r、g、b和片断着色器正使用的program->modulation_r/g/b/a不一致,用以下代码修改统一变量。
- static const float inv255f = 1.0f / 255.0f;
- u_modulation = (r * inv255f, g * inv255f, b * inv255f, a * inv255f),会设置到统一变量“u_modulation”。
复制代码 - 片断着色器会用这统一变量执行以下操作。
- gl_FragColor *= u_modulation;
复制代码
当r、g、b、a都是255时,不会改变片断着色器的输出颜色。但是,由于r、g、b、a类型是uint8_t(见SDL_Texture),意味着最大只能是255!这函数只能把分量变小,不能变大
那如何实现变大?我当前借用的是SDL_BLENDMODE_ADD,同时要用SDL_SetTextureColorMod。
- SDL_SetTextureBlendMode(texture.get(), SDL_BLENDMODE_ADD);
- 把SDL_BLENDMODE_ADD翻译成公式是以下样子。
- Cr = As*Cs + 1*Cd
- Ar = 0*As + 1*Ad
复制代码 于是以一张纯白图片(ARGB(0xffffffff))作为贴图。
gl_FragColor = 255 * u_modulation = 255 * (m / 255.0f),m即SDL_SetTextureColorMod时设的值。
brighten_texture是封装了上面操作的函数。
- void brighten_texture(const texture& tex, const uint8_t r, const uint8_t g, const uint8_t b)
复制代码 修改tex纹理,每像素的颜色加上参数指定的r、b、b值,结果就地写在tex。参数r、g、b不能是负值,即这参数不能变暗。
这种方法需要新建一个纹理,而且这个纹理是SDL_TEXTUREACCESS_TARGET类型,这无疑增大了开销。
对SDL修改建议
1、“gl_FragColor *= u_modulation”是相乘,增加加法。毕竟不少使用场合是加法。
2、u_modulation能突破255限制,以便让变大r、g、b、a。
3、支持灰度化纹理。
|
|