Skip to content

Commit 0d65548

Browse files
Add and Subtract blend modes for image tint
1 parent 4e415d7 commit 0d65548

3 files changed

Lines changed: 58 additions & 0 deletions

File tree

include/c2d/base.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ typedef enum
3737
C2D_TintSolid, ///< Plain solid tint color
3838
C2D_TintMult, ///< Tint color multiplied by texture color
3939
C2D_TintLuma, ///< Tint color multiplied by grayscale converted texture color
40+
C2D_TintAdd, ///< Tint color added to the texture color
41+
C2D_TintSub, ///< Tint color subtracted from the texture color
4042
} C2D_TintMode;
4143

4244
typedef struct

source/base.c

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,12 @@ bool C2D_SetTintMode(C2D_TintMode mode)
329329
case C2D_TintLuma:
330330
new_mode = C2DiF_Mode_ImageLuma;
331331
break;
332+
case C2D_TintAdd:
333+
new_mode = C2DiF_Mode_ImageAdd;
334+
break;
335+
case C2D_TintSub:
336+
new_mode = C2DiF_Mode_ImageSub;
337+
break;
332338
}
333339

334340
ctx->flags = (ctx->flags &~ C2DiF_TintMode_Mask) | (new_mode << (C2DiF_TintMode_Shift - C2DiF_Mode_Shift));
@@ -714,6 +720,54 @@ void C2Di_Update(void)
714720
C3D_TexEnvFunc(env, C3D_RGB, GPU_INTERPOLATE);
715721
break;
716722
}
723+
case C2DiF_Mode_ImageAdd:
724+
{
725+
// Use texenv to blend the color source with the addition-tinted version of it,
726+
// according to a parameter that is passed through with the help of proctex.
727+
proctex = C2DiF_ProcTex_Blend;
728+
729+
// texenv0 = texclr + vtxcolor
730+
env = C3D_GetTexEnv(0);
731+
C3D_TexEnvInit(env);
732+
C3D_TexEnvSrc(env, C3D_Both, GPU_TEXTURE0, GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR);
733+
C3D_TexEnvFunc(env, C3D_RGB, GPU_ADD);
734+
735+
// texenv1.rgb = mix(texclr.rgb, texenv0.rgb, vtx.blend.y);
736+
env = C3D_GetTexEnv(1);
737+
C3D_TexEnvInit(env);
738+
C3D_TexEnvSrc(env, C3D_RGB, GPU_TEXTURE0, GPU_PREVIOUS, GPU_TEXTURE3);
739+
C3D_TexEnvOpRgb(env, GPU_TEVOP_RGB_SRC_COLOR, GPU_TEVOP_RGB_SRC_COLOR, GPU_TEVOP_RGB_ONE_MINUS_SRC_ALPHA);
740+
C3D_TexEnvFunc(env, C3D_RGB, GPU_INTERPOLATE);
741+
742+
// Reset unused texenv stages
743+
C3D_TexEnvInit(C3D_GetTexEnv(2));
744+
C3D_TexEnvInit(C3D_GetTexEnv(3));
745+
break;
746+
}
747+
case C2DiF_Mode_ImageSub:
748+
{
749+
// Use texenv to blend the color source with the subtraction-tinted version of it,
750+
// according to a parameter that is passed through with the help of proctex.
751+
proctex = C2DiF_ProcTex_Blend;
752+
753+
// texenv0 = texclr - vtxcolor
754+
env = C3D_GetTexEnv(0);
755+
C3D_TexEnvInit(env);
756+
C3D_TexEnvSrc(env, C3D_Both, GPU_TEXTURE0, GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR);
757+
C3D_TexEnvFunc(env, C3D_RGB, GPU_SUBTRACT);
758+
759+
// texenv1.rgb = mix(texclr.rgb, texenv0.rgb, vtx.blend.y);
760+
env = C3D_GetTexEnv(1);
761+
C3D_TexEnvInit(env);
762+
C3D_TexEnvSrc(env, C3D_RGB, GPU_TEXTURE0, GPU_PREVIOUS, GPU_TEXTURE3);
763+
C3D_TexEnvOpRgb(env, GPU_TEVOP_RGB_SRC_COLOR, GPU_TEVOP_RGB_SRC_COLOR, GPU_TEVOP_RGB_ONE_MINUS_SRC_ALPHA);
764+
C3D_TexEnvFunc(env, C3D_RGB, GPU_INTERPOLATE);
765+
766+
// Reset unused texenv stages
767+
C3D_TexEnvInit(C3D_GetTexEnv(2));
768+
C3D_TexEnvInit(C3D_GetTexEnv(3));
769+
break;
770+
}
717771
}
718772

719773
if (proctex && proctex != (ctx->flags & C2DiF_ProcTex_Mask))

source/internal.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ enum
5555
C2DiF_Mode_ImageSolid = 3 << C2DiF_Mode_Shift,
5656
C2DiF_Mode_ImageMult = 4 << C2DiF_Mode_Shift,
5757
C2DiF_Mode_ImageLuma = 5 << C2DiF_Mode_Shift,
58+
C2DiF_Mode_ImageAdd = 6 << C2DiF_Mode_Shift,
59+
C2DiF_Mode_ImageSub = 7 << C2DiF_Mode_Shift,
5860

5961
C2DiF_ProcTex_Shift = 12,
6062
C2DiF_ProcTex_Mask = 0xf << C2DiF_ProcTex_Shift,

0 commit comments

Comments
 (0)