SDF & MONOSPACE FONT RENDERING
This commit is contained in:
@@ -84,7 +84,7 @@ struct GfxCitro3D::Impl {
|
||||
}
|
||||
}
|
||||
|
||||
void SetupPixelStage() {
|
||||
void SetupPixelStage(bool sdf) {
|
||||
shaderProgramUse(&pShader);
|
||||
C3D_BindProgram(&pShader);
|
||||
C3D_SetAttrInfo(&pAttr);
|
||||
@@ -92,25 +92,46 @@ struct GfxCitro3D::Impl {
|
||||
if (!CurrentTex) return;
|
||||
C3D_TexEnv* env = C3D_GetTexEnv(0);
|
||||
C3D_TexEnvInit(env);
|
||||
switch (CurrentTex->fmt) {
|
||||
case GPU_A4:
|
||||
case GPU_A8:
|
||||
case GPU_L4:
|
||||
case GPU_L8:
|
||||
C3D_TexEnvSrc(env, C3D_Alpha, GPU_TEXTURE0);
|
||||
C3D_TexEnvFunc(env, C3D_RGB, GPU_REPLACE);
|
||||
C3D_TexEnvFunc(env, C3D_Alpha, GPU_MODULATE);
|
||||
break;
|
||||
case GPU_RGB565:
|
||||
C3D_TexEnvSrc(env, C3D_Alpha, GPU_TEXTURE0);
|
||||
C3D_TexEnvFunc(env, C3D_RGB, GPU_MODULATE);
|
||||
C3D_TexEnvFunc(env, C3D_Alpha, GPU_REPLACE);
|
||||
break;
|
||||
C3D_TexEnv* env1 = C3D_GetTexEnv(1);
|
||||
C3D_TexEnvInit(env1);
|
||||
|
||||
default:
|
||||
C3D_TexEnvSrc(env, C3D_Both, GPU_TEXTURE0);
|
||||
C3D_TexEnvFunc(env, C3D_Both, GPU_MODULATE);
|
||||
break;
|
||||
if (sdf) {
|
||||
C3D_TexEnvSrc(env, C3D_RGB, GPU_PRIMARY_COLOR);
|
||||
C3D_TexEnvFunc(env, C3D_RGB, GPU_REPLACE);
|
||||
|
||||
C3D_TexEnvColor(env, 0x60606060);
|
||||
C3D_TexEnvSrc(env, C3D_Alpha, GPU_TEXTURE0, GPU_CONSTANT);
|
||||
C3D_TexEnvOpAlpha(env, GPU_TEVOP_A_SRC_ALPHA, GPU_TEVOP_A_SRC_ALPHA);
|
||||
C3D_TexEnvFunc(env, C3D_Alpha, GPU_SUBTRACT);
|
||||
C3D_TexEnvScale(env, C3D_Alpha, GPU_TEVSCALE_4);
|
||||
|
||||
C3D_TexEnvSrc(env1, C3D_RGB, GPU_PREVIOUS);
|
||||
C3D_TexEnvFunc(env1, C3D_RGB, GPU_REPLACE);
|
||||
|
||||
C3D_TexEnvSrc(env1, C3D_Alpha, GPU_PREVIOUS, GPU_PRIMARY_COLOR);
|
||||
C3D_TexEnvOpAlpha(env, GPU_TEVOP_A_SRC_ALPHA, GPU_TEVOP_A_SRC_ALPHA);
|
||||
C3D_TexEnvFunc(env1, C3D_Alpha, GPU_MODULATE);
|
||||
} else {
|
||||
switch (CurrentTex->fmt) {
|
||||
case GPU_A4:
|
||||
case GPU_A8:
|
||||
case GPU_L4:
|
||||
case GPU_L8:
|
||||
C3D_TexEnvSrc(env, C3D_Alpha, GPU_TEXTURE0);
|
||||
C3D_TexEnvFunc(env, C3D_RGB, GPU_REPLACE);
|
||||
C3D_TexEnvFunc(env, C3D_Alpha, GPU_MODULATE);
|
||||
break;
|
||||
case GPU_RGB565:
|
||||
C3D_TexEnvSrc(env, C3D_Alpha, GPU_TEXTURE0);
|
||||
C3D_TexEnvFunc(env, C3D_RGB, GPU_MODULATE);
|
||||
C3D_TexEnvFunc(env, C3D_Alpha, GPU_REPLACE);
|
||||
break;
|
||||
|
||||
default:
|
||||
C3D_TexEnvSrc(env, C3D_Both, GPU_TEXTURE0);
|
||||
C3D_TexEnvFunc(env, C3D_Both, GPU_MODULATE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -146,7 +167,7 @@ void GfxCitro3D::SysDeinit() {
|
||||
void GfxCitro3D::Submit(size_t count, size_t start) {
|
||||
if (!impl) return;
|
||||
BindTexture(CurrentTex);
|
||||
impl->SetupPixelStage(); // needs to be called after
|
||||
impl->SetupPixelStage(CurrentTexIsSDF); // needs to be called after
|
||||
C3D_Mtx proj;
|
||||
Mtx_OrthoTilt(&proj, 0.f, ViewPort.x, ViewPort.y, 0.f, 1.f, -1.f, false);
|
||||
C3D_FVUnifMtx4x4(GPU_VERTEX_SHADER, impl->uLocProjection, &proj);
|
||||
|
||||
@@ -15,41 +15,45 @@ static const char* g_vsCode = R"(
|
||||
float4x4 projection;
|
||||
|
||||
struct VS_IN {
|
||||
float2 pos : POSITION0;
|
||||
float2 uv : TEXCOORD0;
|
||||
float4 col : COLOR0;
|
||||
float2 pos : POSITION0;
|
||||
float2 uv : TEXCOORD0;
|
||||
float4 col : COLOR0;
|
||||
};
|
||||
|
||||
struct VS_OUT {
|
||||
float4 pos : POSITION0;
|
||||
float2 uv : TEXCOORD0;
|
||||
float4 col : COLOR0;
|
||||
float4 pos : POSITION0;
|
||||
float2 uv : TEXCOORD0;
|
||||
float4 col : COLOR0;
|
||||
};
|
||||
|
||||
VS_OUT main(VS_IN input) {
|
||||
VS_OUT o;
|
||||
o.pos = mul(projection, float4(input.pos, 0.0, 1.0));
|
||||
o.uv = input.uv;
|
||||
o.col = input.col.bgra;
|
||||
return o;
|
||||
VS_OUT o;
|
||||
o.pos = mul(projection, float4(input.pos, 0.0, 1.0));
|
||||
o.uv = input.uv;
|
||||
o.col = input.col.bgra;
|
||||
return o;
|
||||
}
|
||||
)";
|
||||
|
||||
static const char* g_psCode = R"(
|
||||
sampler2D tex : register(s0);
|
||||
float alfa;
|
||||
float alfa : register(c1);
|
||||
float is_sdf : register(c2);
|
||||
|
||||
struct PS_IN {
|
||||
float2 uv : TEXCOORD0;
|
||||
float4 col : COLOR0;
|
||||
float2 uv : TEXCOORD0;
|
||||
float4 col : COLOR0;
|
||||
};
|
||||
|
||||
float4 main(PS_IN input) : COLOR0 {
|
||||
float4 tc = tex2D(tex, input.uv);
|
||||
if (alfa > 0.5)
|
||||
return float4(input.col.rgb, tc.a * input.col.a);
|
||||
else
|
||||
return tc * input.col;
|
||||
float4 tc = tex2D(tex, input.uv);
|
||||
if (is_sdf > 0.5) {
|
||||
float alpha = smoothstep(0.45, 0.55, tc.a);
|
||||
return float4(input.col.rgb, alpha * input.col.a);
|
||||
} else if (alfa > 0.5)
|
||||
return float4(input.col.rgb, tc.a * input.col.a);
|
||||
else
|
||||
return tc * input.col;
|
||||
}
|
||||
)";
|
||||
|
||||
@@ -159,6 +163,9 @@ void GfxDirectX9::BindTexture(TextureID id) {
|
||||
|
||||
float v = a8 ? 1.0f : 0.0f;
|
||||
impl->Device->SetPixelShaderConstantF(0, &v, 1);
|
||||
|
||||
float sdf = CurrentTexIsSDF ? 1.0f : 0.0f;
|
||||
impl->Device->SetPixelShaderConstantF(1, &sdf, 1);
|
||||
}
|
||||
|
||||
void GfxDirectX9::SysReset() {
|
||||
|
||||
@@ -38,10 +38,15 @@ const char* GfxOpenGL2::pFragCode = R"(
|
||||
|
||||
uniform sampler2D tex;
|
||||
uniform bool alfa;
|
||||
uniform bool is_sdf;
|
||||
|
||||
void main() {
|
||||
vec4 tc = texture2D(tex, oUV);
|
||||
if (alfa) {
|
||||
if (is_sdf) {
|
||||
float dist = tc.a;
|
||||
float alpha = smoothstep(0.45, 0.55, dist);
|
||||
gl_FragColor = vec4(oColor.rgb, alpha * oColor.a);
|
||||
} else if (alfa) {
|
||||
gl_FragColor = vec4(oColor.rgb, tc.a * oColor.a);
|
||||
} else {
|
||||
gl_FragColor = tc * oColor;
|
||||
@@ -78,6 +83,7 @@ void GfxOpenGL2::SysInit() {
|
||||
pSetupShaderAttribs(pShader);
|
||||
pLocTex = glGetUniformLocation(pShader, "tex");
|
||||
pLocAlfa = glGetUniformLocation(pShader, "alfa");
|
||||
pLocIsSDF = glGetUniformLocation(pShader, "is_sdf");
|
||||
pLocProjection = glGetUniformLocation(pShader, "projection");
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
@@ -114,6 +120,7 @@ void GfxOpenGL2::BindTexture(TextureID id) {
|
||||
GLint fmt = 0;
|
||||
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, &fmt);
|
||||
glUniform1i(pLocAlfa, fmt == GL_ALPHA);
|
||||
glUniform1i(pLocIsSDF, CurrentTexIsSDF);
|
||||
}
|
||||
|
||||
void GfxOpenGL2::SysReset() {
|
||||
|
||||
@@ -47,6 +47,7 @@ void GfxOpenGL3::SysInit() {
|
||||
|
||||
pLocTex = glGetUniformLocation(pShader, "tex");
|
||||
pLocAlfa = glGetUniformLocation(pShader, "push.alfa");
|
||||
pLocIsSDF = glGetUniformLocation(pShader, "push.is_sdf");
|
||||
pLocProjection = glGetUniformLocation(pShader, "ubo.projection");
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
@@ -81,6 +82,7 @@ void GfxOpenGL3::BindTexture(TextureID id) {
|
||||
GLint fmt = 0;
|
||||
glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, &fmt);
|
||||
glUniform1i(pLocAlfa, fmt == GL_R8);
|
||||
glUniform1i(pLocIsSDF, CurrentTexIsSDF);
|
||||
}
|
||||
|
||||
void GfxOpenGL3::SysReset() {
|
||||
|
||||
Reference in New Issue
Block a user