nv2a: Implement SET_MATERIAL_ALPHA and diffuse color src

This adds support for the material alpha command and updates the fixed function
shader to respect the diffuse source parameter (which was already piped through
but not utilized).
This commit is contained in:
Erik Abair 2021-12-17 23:08:49 -08:00 committed by mborgerson
parent 758e36d398
commit 517e4b3414
6 changed files with 65 additions and 16 deletions

View File

@ -345,6 +345,8 @@ typedef struct PGRAPHState {
uint32_t ltc1[NV2A_LTC1_COUNT][4];
bool ltc1_dirty[NV2A_LTC1_COUNT];
float material_alpha;
// should figure out where these are in lighting context
float light_infinite_half_vector[NV2A_MAX_LIGHTS][3];
float light_infinite_direction[NV2A_MAX_LIGHTS][3];

View File

@ -982,6 +982,7 @@
# define NV097_SET_FRONT_FACE_V_CCW 0x901
# define NV097_SET_NORMALIZATION_ENABLE 0x000003A4
# define NV097_SET_MATERIAL_EMISSION 0x000003A8
# define NV097_SET_MATERIAL_ALPHA 0x000003B4
# define NV097_SET_LIGHT_ENABLE_MASK 0x000003BC
# define NV097_SET_LIGHT_ENABLE_MASK_LIGHT0_OFF 0
# define NV097_SET_LIGHT_ENABLE_MASK_LIGHT0_INFINITE 1

View File

@ -1894,6 +1894,11 @@ DEF_METHOD_INC(NV097, SET_MATERIAL_EMISSION)
pg->ltctxa_dirty[NV_IGRAPH_XF_LTCTXA_CM_COL] = true;
}
DEF_METHOD(NV097, SET_MATERIAL_ALPHA)
{
pg->material_alpha = *(float*)&parameter;
}
DEF_METHOD(NV097, SET_LIGHT_ENABLE_MASK)
{
SET_MASK(d->pgraph.regs[NV_PGRAPH_CSV0_D],
@ -3658,6 +3663,8 @@ void pgraph_init(NV2AState *d)
pg->shader_cache = g_hash_table_new(shader_hash, shader_equal);
pg->material_alpha = 0.0f;
for (i=0; i<NV2A_VERTEXSHADER_ATTRIBUTES; i++) {
VertexAttribute *attribute = &pg->vertex_attributes[i];
glGenBuffers(1, &attribute->gl_inline_buffer);
@ -3923,6 +3930,10 @@ static void pgraph_shader_update_constants(PGRAPHState *pg,
glUniform4i(pg->shader_binding->clip_region_loc[i],
x_min, y_min_xlat, x_max, y_max_xlat);
}
if (binding->material_alpha_loc != -1) {
glUniform1f(binding->material_alpha_loc, pg->material_alpha);
}
}
static bool pgraph_bind_shaders_test_dirty(PGRAPHState *pg)
@ -4052,18 +4063,19 @@ static void pgraph_bind_shaders(PGRAPHState *pg)
/* fixed function stuff */
if (fixed_function) {
state.skinning = (enum VshSkinning)GET_MASK(pg->regs[NV_PGRAPH_CSV0_D],
NV_PGRAPH_CSV0_D_SKIN);
state.lighting = GET_MASK(pg->regs[NV_PGRAPH_CSV0_C],
NV_PGRAPH_CSV0_C_LIGHTING);
state.normalization = pg->regs[NV_PGRAPH_CSV0_C]
& NV_PGRAPH_CSV0_C_NORMALIZATION_ENABLE;
state.skinning = (enum VshSkinning)GET_MASK(pg->regs[NV_PGRAPH_CSV0_D],
NV_PGRAPH_CSV0_D_SKIN);
state.lighting = GET_MASK(pg->regs[NV_PGRAPH_CSV0_C],
NV_PGRAPH_CSV0_C_LIGHTING);
state.normalization = pg->regs[NV_PGRAPH_CSV0_C]
& NV_PGRAPH_CSV0_C_NORMALIZATION_ENABLE;
/* color material */
state.emission_src = (enum MaterialColorSource)GET_MASK(pg->regs[NV_PGRAPH_CSV0_C], NV_PGRAPH_CSV0_C_EMISSION);
state.ambient_src = (enum MaterialColorSource)GET_MASK(pg->regs[NV_PGRAPH_CSV0_C], NV_PGRAPH_CSV0_C_AMBIENT);
state.diffuse_src = (enum MaterialColorSource)GET_MASK(pg->regs[NV_PGRAPH_CSV0_C], NV_PGRAPH_CSV0_C_DIFFUSE);
state.specular_src = (enum MaterialColorSource)GET_MASK(pg->regs[NV_PGRAPH_CSV0_C], NV_PGRAPH_CSV0_C_SPECULAR);
/* color material */
state.emission_src = (enum MaterialColorSource)GET_MASK(pg->regs[NV_PGRAPH_CSV0_C], NV_PGRAPH_CSV0_C_EMISSION);
state.ambient_src = (enum MaterialColorSource)GET_MASK(pg->regs[NV_PGRAPH_CSV0_C], NV_PGRAPH_CSV0_C_AMBIENT);
state.diffuse_src = (enum MaterialColorSource)GET_MASK(pg->regs[NV_PGRAPH_CSV0_C], NV_PGRAPH_CSV0_C_DIFFUSE);
state.specular_src = (enum MaterialColorSource)GET_MASK(pg->regs[NV_PGRAPH_CSV0_C], NV_PGRAPH_CSV0_C_SPECULAR);
state.material_alpha = pg->material_alpha;
}
/* vertex program stuff */

View File

@ -76,6 +76,7 @@ DEF_METHOD(NV097, SET_CULL_FACE)
DEF_METHOD(NV097, SET_FRONT_FACE)
DEF_METHOD(NV097, SET_NORMALIZATION_ENABLE)
DEF_METHOD_RANGE(NV097, SET_MATERIAL_EMISSION, 3)
DEF_METHOD(NV097, SET_MATERIAL_ALPHA)
DEF_METHOD(NV097, SET_LIGHT_ENABLE_MASK)
DEF_METHOD_CASE_4(NV097, SET_TEXGEN_S, 16)
DEF_METHOD_CASE_4(NV097, SET_TEXGEN_T, 16)

View File

@ -488,12 +488,23 @@ GLSL_DEFINE(materialEmissionColor, GLSL_LTCTXA(NV_IGRAPH_XF_LTCTXA_CM_COL) ".xyz
//FIXME: Do 2 passes if we want 2 sided-lighting?
static char alpha_source_diffuse[] = "diffuse.a";
static char alpha_source_specular[] = "specular.a";
static char alpha_source_material[] = "material_alpha";
const char *alpha_source = alpha_source_diffuse;
if (state.diffuse_src == MATERIAL_COLOR_SRC_MATERIAL) {
mstring_append(header, "uniform float material_alpha;\n");
alpha_source = alpha_source_material;
} else if (state.diffuse_src == MATERIAL_COLOR_SRC_SPECULAR) {
alpha_source = alpha_source_specular;
}
if (state.ambient_src == MATERIAL_COLOR_SRC_MATERIAL) {
mstring_append(body, "oD0 = vec4(sceneAmbientColor, diffuse.a);\n");
mstring_append_fmt(body, "oD0 = vec4(sceneAmbientColor, %s);\n", alpha_source);
} else if (state.ambient_src == MATERIAL_COLOR_SRC_DIFFUSE) {
mstring_append(body, "oD0 = vec4(diffuse.rgb, diffuse.a);\n");
mstring_append_fmt(body, "oD0 = vec4(diffuse.rgb, %s);\n", alpha_source);
} else if (state.ambient_src == MATERIAL_COLOR_SRC_SPECULAR) {
mstring_append(body, "oD0 = vec4(specular.rgb, diffuse.a);\n");
mstring_append_fmt(body, "oD0 = vec4(specular.rgb, %s);\n", alpha_source);
}
mstring_append(body, "oD0.rgb *= materialEmissionColor.rgb;\n");
@ -602,8 +613,20 @@ GLSL_DEFINE(materialEmissionColor, GLSL_LTCTXA(NV_IGRAPH_XF_LTCTXA_CM_COL) ".xyz
mstring_append(body,
" oD0.xyz += lightAmbient;\n");
mstring_append(body,
" oD0.xyz += diffuse.xyz * lightDiffuse;\n");
switch (state.diffuse_src) {
case MATERIAL_COLOR_SRC_MATERIAL:
mstring_append(body,
" oD0.xyz += lightDiffuse;\n");
break;
case MATERIAL_COLOR_SRC_DIFFUSE:
mstring_append(body,
" oD0.xyz += diffuse.xyz * lightDiffuse;\n");
break;
case MATERIAL_COLOR_SRC_SPECULAR:
mstring_append(body,
" oD0.xyz += specular.xyz * lightDiffuse;\n");
break;
}
mstring_append(body,
" oD1.xyz += specular.xyz * lightSpecular;\n");
@ -1059,5 +1082,11 @@ ShaderBinding* generate_shaders(const ShaderState state)
ret->clip_region_loc[i] = glGetUniformLocation(program, tmp);
}
if (state.fixed_function) {
ret->material_alpha_loc = glGetUniformLocation(program, "material_alpha");
} else {
ret->material_alpha_loc = -1;
}
return ret;
}

View File

@ -76,6 +76,8 @@ typedef struct ShaderState {
enum MaterialColorSource diffuse_src;
enum MaterialColorSource specular_src;
float material_alpha;
bool lighting;
enum VshLight light[NV2A_MAX_LIGHTS];
@ -128,6 +130,8 @@ typedef struct ShaderBinding {
GLint light_local_attenuation_loc[NV2A_MAX_LIGHTS];
GLint clip_region_loc[8];
GLint material_alpha_loc;
} ShaderBinding;
ShaderBinding* generate_shaders(const ShaderState state);