为纹理设置SDL_BLENDMODE_BLEND导致渲染质量异常问题求解
问题根源
混合模式设置时机完全错了。SDL_SetTextureBlendMode只对「当前被SDL_RenderCopy绘制到其他目标的纹理」生效,当你把texA通过SDL_SetRenderTarget设为当前渲染画布时,给它设置SDL_BLENDMODE_BLEND会直接干扰画布上所有绘制操作的颜色混合计算,导致texB的alpha通道、RGB值被错误运算,才会出现文本发灰、透明度异常的问题。
你之前测试把清屏色改成(255,255,255,0)时白色文本显示正常,只是刚好凑对了白色的混合计算逻辑,换黑色文本立刻出问题,本质是碰运气没解决核心错误。
修复方案
调整混合模式的设置顺序,严格区分纹理作为「渲染画布」和「被渲染素材」两个阶段的属性设置:
- 往texA上绘制内容时,texA是渲染画布,不需要开启自身混合模式,保证所有写入内容的颜色、alpha值计算正确
- 所有内容绘制完成,texA要作为素材贴到屏幕/其他纹理上时,再开启它的
SDL_BLENDMODE_BLEND实现透明效果
修正后的可运行代码如下:
// 创建RGBA格式的可渲染目标纹理texA texA = SDL_CreateTexture(r, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, mWidth, mHeight); // 切换渲染目标到texA,此时不要给texA设置任何混合模式 SDL_SetRenderTarget(r, texA); // 关闭绘制混合,将texA整个清为全透明 SDL_SetRenderDrawBlendMode(r, SDL_BLENDMODE_NONE); SDL_SetRenderDrawColor(r, 0, 0, 0, 0); SDL_RenderFillRect(r, NULL); // 依次往texA上渲染所有需要的内容,包括texB和其他后续纹理 // 各子纹理可单独设置自身需要的混合模式,不会被干扰 SDL_RenderCopy(r, texB, NULL, NULL); // 所有内容绘制完成,切回默认渲染目标(一般是屏幕) SDL_SetRenderTarget(r, nullptr); // 最后再给texA开启混合模式,此时它作为被渲染的素材,透明效果会正常生效 SDL_SetTextureBlendMode(texA, SDL_BLENDMODE_BLEND);
额外注意事项
- 如果后续需要往texA上追加绘制内容,先临时把texA的混合模式改回
SDL_BLENDMODE_NONE,设为渲染目标画完内容、切走渲染目标后,再改回SDL_BLENDMODE_BLEND即可,不会破坏已经绘制好的内容。 - 多纹理往texA上叠加渲染时,只需要给每个作为素材的子纹理设置对应的混合模式,不需要修改texA作为画布阶段的属性。
效果参考
- 直接渲染纹理B的正确效果:

- 未给texA设置BLEND模式时的不透明异常效果:

- 错误时机开启BLEND模式的颜色异常效果:

内容的提问来源于stack exchange,提问作者Ailuropoda
相关产品推荐
相关产品推荐

