mirror of https://github.com/xemu-project/xemu.git
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:
parent
758e36d398
commit
517e4b3414
|
@ -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];
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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*)¶meter;
|
||||
}
|
||||
|
||||
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 */
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue