SDL中文论坛

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 5261|回复: 0
打印 上一主题 下一主题

[SDL] 修改纹理颜色

[复制链接]

149

主题

331

帖子

2445

积分

版主

Rank: 7Rank: 7Rank: 7

积分
2445
跳转到指定楼层
楼主
发表于 2017-3-8 09:15:36 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 ancientcc 于 2017-3-8 09:25 编辑
  1. int SDL_SetTextureAlphaMod(SDL_Texture * texture, Uint8 alpha);
  2. 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不一致,用以下代码修改统一变量。
    1. static const float inv255f = 1.0f / 255.0f;
    2. u_modulation = (r * inv255f, g * inv255f, b * inv255f, a * inv255f),会设置到统一变量“u_modulation”。
    复制代码
  • 片断着色器会用这统一变量执行以下操作。
    1. gl_FragColor *= u_modulation;
    复制代码


当r、g、b、a都是255时,不会改变片断着色器的输出颜色。但是,由于r、g、b、a类型是uint8_t(见SDL_Texture),意味着最大只能是255!这函数只能把分量变小,不能变大

那如何实现变大?我当前借用的是SDL_BLENDMODE_ADD,同时要用SDL_SetTextureColorMod。
  1. SDL_SetTextureBlendMode(texture.get(), SDL_BLENDMODE_ADD);
  2. 把SDL_BLENDMODE_ADD翻译成公式是以下样子。
  3. Cr = As*Cs + 1*Cd
  4. Ar = 0*As + 1*Ad
复制代码
于是以一张纯白图片(ARGB(0xffffffff))作为贴图。
gl_FragColor = 255 * u_modulation = 255 * (m / 255.0f),m即SDL_SetTextureColorMod时设的值。

brighten_texture是封装了上面操作的函数。
  1. 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、支持灰度化纹理。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|丽谷软件|libsdl.cn

GMT+8, 2025-5-1 22:52 , Processed in 0.048219 second(s), 19 queries .

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表