mirror of https://github.com/xemu-project/xemu.git
nv2a: Partial implementation of SET_SPECULAR_PARAMS
This commit is contained in:
parent
7a34eedd6f
commit
69c8df2a3e
|
@ -1056,6 +1056,7 @@
|
||||||
# define NV097_SET_TEXGEN_VIEW_MODEL_LOCAL_VIEWER 0
|
# define NV097_SET_TEXGEN_VIEW_MODEL_LOCAL_VIEWER 0
|
||||||
# define NV097_SET_TEXGEN_VIEW_MODEL_INFINITE_VIEWER 1
|
# define NV097_SET_TEXGEN_VIEW_MODEL_INFINITE_VIEWER 1
|
||||||
# define NV097_SET_FOG_PLANE 0x000009D0
|
# define NV097_SET_FOG_PLANE 0x000009D0
|
||||||
|
# define NV097_SET_SPECULAR_PARAMS 0x000009E0
|
||||||
# define NV097_SET_SCENE_AMBIENT_COLOR 0x00000A10
|
# define NV097_SET_SCENE_AMBIENT_COLOR 0x00000A10
|
||||||
# define NV097_SET_VIEWPORT_OFFSET 0x00000A20
|
# define NV097_SET_VIEWPORT_OFFSET 0x00000A20
|
||||||
# define NV097_SET_POINT_PARAMS 0x00000A30
|
# define NV097_SET_POINT_PARAMS 0x00000A30
|
||||||
|
@ -1264,6 +1265,7 @@
|
||||||
# define NV097_SET_CLEAR_RECT_HORIZONTAL 0x00001D98
|
# define NV097_SET_CLEAR_RECT_HORIZONTAL 0x00001D98
|
||||||
# define NV097_SET_CLEAR_RECT_VERTICAL 0x00001D9C
|
# define NV097_SET_CLEAR_RECT_VERTICAL 0x00001D9C
|
||||||
# define NV097_SET_SPECULAR_FOG_FACTOR 0x00001E20
|
# define NV097_SET_SPECULAR_FOG_FACTOR 0x00001E20
|
||||||
|
# define NV097_SET_SPECULAR_PARAMS_BACK 0x00001E28
|
||||||
# define NV097_SET_COMBINER_COLOR_OCW 0x00001E40
|
# define NV097_SET_COMBINER_COLOR_OCW 0x00001E40
|
||||||
# define NV097_SET_COMBINER_CONTROL 0x00001E60
|
# define NV097_SET_COMBINER_CONTROL 0x00001E60
|
||||||
# define NV097_SET_SHADOW_ZSLOPE_THRESHOLD 0x00001E68
|
# define NV097_SET_SHADOW_ZSLOPE_THRESHOLD 0x00001E68
|
||||||
|
|
|
@ -122,6 +122,7 @@ typedef struct ShaderBinding {
|
||||||
GLint light_infinite_direction_loc[NV2A_MAX_LIGHTS];
|
GLint light_infinite_direction_loc[NV2A_MAX_LIGHTS];
|
||||||
GLint light_local_position_loc[NV2A_MAX_LIGHTS];
|
GLint light_local_position_loc[NV2A_MAX_LIGHTS];
|
||||||
GLint light_local_attenuation_loc[NV2A_MAX_LIGHTS];
|
GLint light_local_attenuation_loc[NV2A_MAX_LIGHTS];
|
||||||
|
int specular_power_loc;
|
||||||
|
|
||||||
GLint clip_region_loc[8];
|
GLint clip_region_loc[8];
|
||||||
|
|
||||||
|
|
|
@ -193,8 +193,11 @@ static void update_shader_constant_locations(ShaderBinding *binding)
|
||||||
if (binding->state.fixed_function) {
|
if (binding->state.fixed_function) {
|
||||||
binding->material_alpha_loc =
|
binding->material_alpha_loc =
|
||||||
glGetUniformLocation(binding->gl_program, "material_alpha");
|
glGetUniformLocation(binding->gl_program, "material_alpha");
|
||||||
|
binding->specular_power_loc =
|
||||||
|
glGetUniformLocation(binding->gl_program, "specularPower");
|
||||||
} else {
|
} else {
|
||||||
binding->material_alpha_loc = -1;
|
binding->material_alpha_loc = -1;
|
||||||
|
binding->specular_power_loc = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -836,6 +839,10 @@ static void shader_update_constants(PGRAPHState *pg, ShaderBinding *binding,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (binding->specular_power_loc != -1) {
|
||||||
|
glUniform1f(binding->specular_power_loc, pg->specular_power);
|
||||||
|
}
|
||||||
|
|
||||||
/* estimate the viewport by assuming it matches the surface ... */
|
/* estimate the viewport by assuming it matches the surface ... */
|
||||||
unsigned int aa_width = 1, aa_height = 1;
|
unsigned int aa_width = 1, aa_height = 1;
|
||||||
pgraph_apply_anti_aliasing_factor(pg, &aa_width, &aa_height);
|
pgraph_apply_anti_aliasing_factor(pg, &aa_width, &aa_height);
|
||||||
|
|
|
@ -230,10 +230,16 @@ GLSL_DEFINE(materialEmissionColor, GLSL_LTCTXA(NV_IGRAPH_XF_LTCTXA_CM_COL) ".xyz
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Lighting */
|
/* Lighting */
|
||||||
if (state->lighting) {
|
if (!state->lighting) {
|
||||||
|
mstring_append(body, " oD0 = diffuse;\n");
|
||||||
|
mstring_append(body, " oD1 = specular;\n");
|
||||||
|
mstring_append(body, " oB0 = backDiffuse;\n");
|
||||||
|
mstring_append(body, " oB1 = backSpecular;\n");
|
||||||
|
} else {
|
||||||
//FIXME: Do 2 passes if we want 2 sided-lighting?
|
//FIXME: Do 2 passes if we want 2 sided-lighting?
|
||||||
|
|
||||||
|
mstring_append_fmt(uniforms, "%sfloat specularPower;\n", u);
|
||||||
|
|
||||||
static char alpha_source_diffuse[] = "diffuse.a";
|
static char alpha_source_diffuse[] = "diffuse.a";
|
||||||
static char alpha_source_specular[] = "specular.a";
|
static char alpha_source_specular[] = "specular.a";
|
||||||
static char alpha_source_material[] = "material_alpha";
|
static char alpha_source_material[] = "material_alpha";
|
||||||
|
@ -269,12 +275,6 @@ GLSL_DEFINE(materialEmissionColor, GLSL_LTCTXA(NV_IGRAPH_XF_LTCTXA_CM_COL) ".xyz
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME: It seems that we only have to handle the surface colors if
|
|
||||||
* they are not part of the material [= vertex colors].
|
|
||||||
* If they are material the cpu will premultiply light
|
|
||||||
* colors
|
|
||||||
*/
|
|
||||||
|
|
||||||
mstring_append_fmt(body, "/* Light %d */ {\n", i);
|
mstring_append_fmt(body, "/* Light %d */ {\n", i);
|
||||||
|
|
||||||
if (state->light[i] == LIGHT_LOCAL
|
if (state->light[i] == LIGHT_LOCAL
|
||||||
|
@ -310,14 +310,10 @@ GLSL_DEFINE(materialEmissionColor, GLSL_LTCTXA(NV_IGRAPH_XF_LTCTXA_CM_COL) ".xyz
|
||||||
u, i, u, i);
|
u, i, u, i);
|
||||||
mstring_append_fmt(body,
|
mstring_append_fmt(body,
|
||||||
" float attenuation = 1.0;\n"
|
" float attenuation = 1.0;\n"
|
||||||
" float nDotVP = max(0.0, dot(tNormal, normalize(vec3(lightInfiniteDirection%d))));\n"
|
" float nDotVP = max(0.0, dot(tNormal, normalize(lightInfiniteDirection%d)));\n"
|
||||||
" float nDotHV = max(0.0, dot(tNormal, vec3(lightInfiniteHalfVector%d)));\n",
|
" float nDotHV = max(0.0, dot(tNormal, lightInfiniteHalfVector%d));\n",
|
||||||
i, i);
|
i, i);
|
||||||
|
|
||||||
/* FIXME: Do specular */
|
|
||||||
|
|
||||||
/* FIXME: tBackDiffuse */
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case LIGHT_LOCAL:
|
case LIGHT_LOCAL:
|
||||||
/* Everything done already */
|
/* Everything done already */
|
||||||
|
@ -349,11 +345,11 @@ GLSL_DEFINE(materialEmissionColor, GLSL_LTCTXA(NV_IGRAPH_XF_LTCTXA_CM_COL) ".xyz
|
||||||
" if (nDotVP == 0.0) {\n"
|
" if (nDotVP == 0.0) {\n"
|
||||||
" pf = 0.0;\n"
|
" pf = 0.0;\n"
|
||||||
" } else {\n"
|
" } else {\n"
|
||||||
" pf = pow(nDotHV, /* specular(l, m, n, l1, m1, n1) */ 0.001);\n"
|
" pf = pow(nDotHV, specularPower);\n"
|
||||||
" }\n"
|
" }\n"
|
||||||
" vec3 lightAmbient = lightAmbientColor(%d) * attenuation;\n"
|
" vec3 lightAmbient = lightAmbientColor(%d) * attenuation;\n"
|
||||||
" vec3 lightDiffuse = lightDiffuseColor(%d) * attenuation * nDotVP;\n"
|
" vec3 lightDiffuse = lightDiffuseColor(%d) * attenuation * nDotVP;\n"
|
||||||
" vec3 lightSpecular = lightSpecularColor(%d) * pf;\n",
|
" vec3 lightSpecular = lightSpecularColor(%d) * attenuation * pf;\n",
|
||||||
i, i, i);
|
i, i, i);
|
||||||
|
|
||||||
mstring_append(body,
|
mstring_append(body,
|
||||||
|
@ -374,26 +370,44 @@ GLSL_DEFINE(materialEmissionColor, GLSL_LTCTXA(NV_IGRAPH_XF_LTCTXA_CM_COL) ".xyz
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
mstring_append(body,
|
switch (state->specular_src) {
|
||||||
" oD1.xyz += specular.xyz * lightSpecular;\n");
|
case MATERIAL_COLOR_SRC_MATERIAL:
|
||||||
|
mstring_append(body,
|
||||||
|
" oD1.xyz += lightSpecular;\n");
|
||||||
|
break;
|
||||||
|
case MATERIAL_COLOR_SRC_DIFFUSE:
|
||||||
|
mstring_append(body,
|
||||||
|
" oD1.xyz += diffuse.xyz * lightSpecular;\n");
|
||||||
|
break;
|
||||||
|
case MATERIAL_COLOR_SRC_SPECULAR:
|
||||||
|
mstring_append(body,
|
||||||
|
" oD1.xyz += specular.xyz * lightSpecular;\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
mstring_append(body, "}\n");
|
mstring_append(body, "}\n");
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
mstring_append(body, " oD0 = diffuse;\n");
|
|
||||||
mstring_append(body, " oD1 = specular;\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
mstring_append(body, " oB0 = backDiffuse;\n");
|
/* TODO: Implement two-sided lighting */
|
||||||
mstring_append(body, " oB1 = backSpecular;\n");
|
mstring_append(body, " oB0 = backDiffuse;\n");
|
||||||
|
mstring_append(body, " oB1 = backSpecular;\n");
|
||||||
|
}
|
||||||
|
|
||||||
if (!state->specular_enable) {
|
if (!state->specular_enable) {
|
||||||
mstring_append(body, " oD1 = vec4(0.0, 0.0, 0.0, 1.0);\n");
|
mstring_append(body, " oD1 = vec4(0.0, 0.0, 0.0, 1.0);\n");
|
||||||
mstring_append(body, " oB1 = vec4(0.0, 0.0, 0.0, 1.0);\n");
|
mstring_append(body, " oB1 = vec4(0.0, 0.0, 0.0, 1.0);\n");
|
||||||
} else {
|
} else {
|
||||||
if (!state->separate_specular) {
|
if (!state->separate_specular) {
|
||||||
mstring_append(body, " oD1 = specular;\n");
|
if (state->lighting) {
|
||||||
mstring_append(body, " oB1 = backSpecular;\n");
|
mstring_append(body,
|
||||||
|
" oD0.xyz += oD1.xyz;\n"
|
||||||
|
" oB0.xyz += oB1.xyz;\n"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
mstring_append(body,
|
||||||
|
" oD1 = specular;\n"
|
||||||
|
" oB1 = backSpecular;\n"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
if (state->ignore_specular_alpha) {
|
if (state->ignore_specular_alpha) {
|
||||||
mstring_append(body,
|
mstring_append(body,
|
||||||
|
|
|
@ -96,6 +96,7 @@ DEF_METHOD_RANGE(NV097, SET_FOG_PARAMS, 3)
|
||||||
DEF_METHOD_RANGE(NV097, SET_TEXGEN_PLANE_S, 4*4*4)
|
DEF_METHOD_RANGE(NV097, SET_TEXGEN_PLANE_S, 4*4*4)
|
||||||
DEF_METHOD(NV097, SET_TEXGEN_VIEW_MODEL)
|
DEF_METHOD(NV097, SET_TEXGEN_VIEW_MODEL)
|
||||||
DEF_METHOD_RANGE(NV097, SET_FOG_PLANE, 4)
|
DEF_METHOD_RANGE(NV097, SET_FOG_PLANE, 4)
|
||||||
|
DEF_METHOD_RANGE(NV097, SET_SPECULAR_PARAMS, 6)
|
||||||
DEF_METHOD_RANGE(NV097, SET_SCENE_AMBIENT_COLOR, 3)
|
DEF_METHOD_RANGE(NV097, SET_SCENE_AMBIENT_COLOR, 3)
|
||||||
DEF_METHOD_RANGE(NV097, SET_VIEWPORT_OFFSET, 4)
|
DEF_METHOD_RANGE(NV097, SET_VIEWPORT_OFFSET, 4)
|
||||||
DEF_METHOD_RANGE(NV097, SET_POINT_PARAMS, 8)
|
DEF_METHOD_RANGE(NV097, SET_POINT_PARAMS, 8)
|
||||||
|
@ -183,6 +184,7 @@ DEF_METHOD(NV097, CLEAR_SURFACE)
|
||||||
DEF_METHOD(NV097, SET_CLEAR_RECT_HORIZONTAL)
|
DEF_METHOD(NV097, SET_CLEAR_RECT_HORIZONTAL)
|
||||||
DEF_METHOD(NV097, SET_CLEAR_RECT_VERTICAL)
|
DEF_METHOD(NV097, SET_CLEAR_RECT_VERTICAL)
|
||||||
DEF_METHOD_RANGE(NV097, SET_SPECULAR_FOG_FACTOR, 2)
|
DEF_METHOD_RANGE(NV097, SET_SPECULAR_FOG_FACTOR, 2)
|
||||||
|
DEF_METHOD_RANGE(NV097, SET_SPECULAR_PARAMS_BACK, 6)
|
||||||
DEF_METHOD(NV097, SET_SHADER_CLIP_PLANE_MODE)
|
DEF_METHOD(NV097, SET_SHADER_CLIP_PLANE_MODE)
|
||||||
DEF_METHOD_RANGE(NV097, SET_COMBINER_COLOR_OCW, 8)
|
DEF_METHOD_RANGE(NV097, SET_COMBINER_COLOR_OCW, 8)
|
||||||
DEF_METHOD(NV097, SET_COMBINER_CONTROL)
|
DEF_METHOD(NV097, SET_COMBINER_CONTROL)
|
||||||
|
|
|
@ -19,6 +19,8 @@
|
||||||
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
#include "hw/xbox/nv2a/nv2a_int.h"
|
#include "hw/xbox/nv2a/nv2a_int.h"
|
||||||
#include "ui/xemu-notifications.h"
|
#include "ui/xemu-notifications.h"
|
||||||
#include "ui/xemu-settings.h"
|
#include "ui/xemu-settings.h"
|
||||||
|
@ -1803,6 +1805,113 @@ DEF_METHOD_INC(NV097, SET_FOG_PLANE)
|
||||||
pg->vsh_constants_dirty[NV_IGRAPH_XF_XFCTX_FOG] = true;
|
pg->vsh_constants_dirty[NV_IGRAPH_XF_XFCTX_FOG] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct CurveCoefficients {
|
||||||
|
float a;
|
||||||
|
float b;
|
||||||
|
float c;
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct CurveCoefficients curve_coefficients[] = {
|
||||||
|
{1.000108475163, -9.838607076280, 54.829089549713},
|
||||||
|
{1.199164441703, -3.292603784852, 7.799987995214},
|
||||||
|
{8.653441252033, 29.189473787191, 43.586027561823},
|
||||||
|
{-531.307758450301, 117.398468683934, 113.155490738338},
|
||||||
|
{-4.662713151292, 1.221108944572, 1.217360986939},
|
||||||
|
{-124.435242105211, 35.401219563514, 35.408114377045},
|
||||||
|
{10672560.259502287954, 21565843.555823743343, 10894794.336297152564},
|
||||||
|
{-51973801.463933646679, -104199997.554352939129, -52225454.356278456748},
|
||||||
|
{972270.324080004124, 2025882.096547174733, 1054898.052467488218},
|
||||||
|
};
|
||||||
|
|
||||||
|
static const float kCoefficient0StepPoints[] = {
|
||||||
|
-0.022553957999, // power = 1.25
|
||||||
|
-0.421539008617, // power = 4.00
|
||||||
|
-0.678715527058, // power = 9.00
|
||||||
|
-0.838916420937, // power = 20.00
|
||||||
|
-0.961754500866, // power = 90.00
|
||||||
|
-0.990773200989, // power = 375.00
|
||||||
|
-0.994858562946, // power = 650.00
|
||||||
|
-0.996561050415, // power = 1000.00
|
||||||
|
-0.999547004700, // power = 1250.00
|
||||||
|
};
|
||||||
|
|
||||||
|
static float reconstruct_quadratic(float c0, const struct CurveCoefficients *coefficients) {
|
||||||
|
return coefficients->a + coefficients->b * c0 + coefficients->c * c0 * c0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static float reconstruct_saturation_growth_rate(float c0, const struct CurveCoefficients *coefficients) {
|
||||||
|
return (coefficients->a * c0) / (coefficients->b + coefficients->c * c0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static float (* const reconstruct_func_map[])(float, const struct CurveCoefficients *) = {
|
||||||
|
reconstruct_quadratic, // 1.0..1.25 max error 0.01 %
|
||||||
|
reconstruct_quadratic, // 1.25..4.0 max error 2.2 %
|
||||||
|
reconstruct_quadratic, // 4.0..9.0 max error 2.3 %
|
||||||
|
reconstruct_saturation_growth_rate, // 9.0..20.0 max error 1.4 %
|
||||||
|
reconstruct_saturation_growth_rate, // 20.0..90.0 max error 2.1 %
|
||||||
|
reconstruct_saturation_growth_rate, // 90.0..375.0 max error 2.8%
|
||||||
|
reconstruct_quadratic, // 375..650 max error 1.0 %
|
||||||
|
reconstruct_quadratic, // 650..1000 max error 1.7%
|
||||||
|
reconstruct_quadratic, // 1000..1250 max error 1.0%
|
||||||
|
};
|
||||||
|
|
||||||
|
static float reconstruct_specular_power(const float *params) {
|
||||||
|
// See https://github.com/dracc/xgu/blob/db3172d8c983629f0dc971092981846da22438ae/xgux.h#L279
|
||||||
|
|
||||||
|
// Values < 1.0 will result in a positive c1 and (c2 - c0 * 2) will be very
|
||||||
|
// close to the original value.
|
||||||
|
if (params[1] > 0.0f && params[2] < 1.0f) {
|
||||||
|
return params[2] - (params[0] * 2.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
float c0 = params[0];
|
||||||
|
float c3 = params[3];
|
||||||
|
// FIXME: This handling is not correct, but is distinct without crashing.
|
||||||
|
// It does not appear possible for a DirectX-generated value to be positive,
|
||||||
|
// so while this differs from hardware behavior, it may be irrelevant in
|
||||||
|
// practice.
|
||||||
|
if (c0 > 0.0f || c3 > 0.0f) {
|
||||||
|
return 0.0001f;
|
||||||
|
}
|
||||||
|
|
||||||
|
float reconstructed_power = 0.f;
|
||||||
|
for (uint32_t i = 0; i < sizeof(kCoefficient0StepPoints) / sizeof(kCoefficient0StepPoints[0]); ++i) {
|
||||||
|
if (c0 > kCoefficient0StepPoints[i]) {
|
||||||
|
reconstructed_power = reconstruct_func_map[i](c0, &curve_coefficients[i]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float reconstructed_half_power = 0.f;
|
||||||
|
for (uint32_t i = 0; i < sizeof(kCoefficient0StepPoints) / sizeof(kCoefficient0StepPoints[0]); ++i) {
|
||||||
|
if (c3 > kCoefficient0StepPoints[i]) {
|
||||||
|
reconstructed_half_power = reconstruct_func_map[i](c3, &curve_coefficients[i]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// The range can be extended beyond 1250 by using the half power params. This
|
||||||
|
// will only work for DirectX generated values, arbitrary params could
|
||||||
|
// erroneously trigger this.
|
||||||
|
//
|
||||||
|
// There are some very low power (~1) values that have inverted powers, but
|
||||||
|
// they are easily identified by comparatively high c0 parameters.
|
||||||
|
if (reconstructed_power == 0.f || (reconstructed_half_power > reconstructed_power && c0 < -0.1f)) {
|
||||||
|
return reconstructed_half_power * 2.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
return reconstructed_power;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEF_METHOD_INC(NV097, SET_SPECULAR_PARAMS)
|
||||||
|
{
|
||||||
|
int slot = (method - NV097_SET_SPECULAR_PARAMS) / 4;
|
||||||
|
pg->specular_params[slot] = *(float *)¶meter;
|
||||||
|
if (slot == 5) {
|
||||||
|
pg->specular_power = reconstruct_specular_power(pg->specular_params);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
DEF_METHOD_INC(NV097, SET_SCENE_AMBIENT_COLOR)
|
DEF_METHOD_INC(NV097, SET_SCENE_AMBIENT_COLOR)
|
||||||
{
|
{
|
||||||
int slot = (method - NV097_SET_SCENE_AMBIENT_COLOR) / 4;
|
int slot = (method - NV097_SET_SCENE_AMBIENT_COLOR) / 4;
|
||||||
|
@ -2785,6 +2894,15 @@ DEF_METHOD_INC(NV097, SET_SPECULAR_FOG_FACTOR)
|
||||||
pgraph_reg_w(pg, NV_PGRAPH_SPECFOGFACTOR0 + slot*4, parameter);
|
pgraph_reg_w(pg, NV_PGRAPH_SPECFOGFACTOR0 + slot*4, parameter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DEF_METHOD_INC(NV097, SET_SPECULAR_PARAMS_BACK)
|
||||||
|
{
|
||||||
|
int slot = (method - NV097_SET_SPECULAR_PARAMS_BACK) / 4;
|
||||||
|
pg->specular_params_back[slot] = *(float *)¶meter;
|
||||||
|
if (slot == 5) {
|
||||||
|
pg->specular_power_back = reconstruct_specular_power(pg->specular_params_back);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
DEF_METHOD(NV097, SET_SHADER_CLIP_PLANE_MODE)
|
DEF_METHOD(NV097, SET_SHADER_CLIP_PLANE_MODE)
|
||||||
{
|
{
|
||||||
pgraph_reg_w(pg, NV_PGRAPH_SHADERCLIPMODE, parameter);
|
pgraph_reg_w(pg, NV_PGRAPH_SHADERCLIPMODE, parameter);
|
||||||
|
|
|
@ -197,6 +197,11 @@ typedef struct PGRAPHState {
|
||||||
float light_local_position[NV2A_MAX_LIGHTS][3];
|
float light_local_position[NV2A_MAX_LIGHTS][3];
|
||||||
float light_local_attenuation[NV2A_MAX_LIGHTS][3];
|
float light_local_attenuation[NV2A_MAX_LIGHTS][3];
|
||||||
|
|
||||||
|
float specular_params[6];
|
||||||
|
float specular_power;
|
||||||
|
float specular_params_back[6];
|
||||||
|
float specular_power_back;
|
||||||
|
|
||||||
float point_params[8];
|
float point_params[8];
|
||||||
|
|
||||||
VertexAttribute vertex_attributes[NV2A_VERTEXSHADER_ATTRIBUTES];
|
VertexAttribute vertex_attributes[NV2A_VERTEXSHADER_ATTRIBUTES];
|
||||||
|
|
|
@ -97,6 +97,9 @@ ShaderState pgraph_get_shader_state(PGRAPHState *pg)
|
||||||
state.ignore_specular_alpha = !GET_MASK(
|
state.ignore_specular_alpha = !GET_MASK(
|
||||||
pgraph_reg_r(pg, NV_PGRAPH_CSV0_C), NV_PGRAPH_CSV0_C_ALPHA_FROM_MATERIAL_SPECULAR);
|
pgraph_reg_r(pg, NV_PGRAPH_CSV0_C), NV_PGRAPH_CSV0_C_ALPHA_FROM_MATERIAL_SPECULAR);
|
||||||
|
|
||||||
|
state.specular_power = pg->specular_power;
|
||||||
|
state.specular_power_back = pg->specular_power_back;
|
||||||
|
|
||||||
/* vertex program stuff */
|
/* vertex program stuff */
|
||||||
state.vertex_program = vertex_program,
|
state.vertex_program = vertex_program,
|
||||||
state.z_perspective = pgraph_reg_r(pg, NV_PGRAPH_CONTROL_0) &
|
state.z_perspective = pgraph_reg_r(pg, NV_PGRAPH_CONTROL_0) &
|
||||||
|
|
|
@ -81,6 +81,8 @@ typedef struct ShaderState {
|
||||||
|
|
||||||
bool separate_specular;
|
bool separate_specular;
|
||||||
bool ignore_specular_alpha;
|
bool ignore_specular_alpha;
|
||||||
|
float specular_power;
|
||||||
|
float specular_power_back;
|
||||||
|
|
||||||
bool lighting;
|
bool lighting;
|
||||||
enum VshLight light[NV2A_MAX_LIGHTS];
|
enum VshLight light[NV2A_MAX_LIGHTS];
|
||||||
|
|
|
@ -190,6 +190,7 @@ typedef struct ShaderBinding {
|
||||||
int light_infinite_direction_loc[NV2A_MAX_LIGHTS];
|
int light_infinite_direction_loc[NV2A_MAX_LIGHTS];
|
||||||
int light_local_position_loc[NV2A_MAX_LIGHTS];
|
int light_local_position_loc[NV2A_MAX_LIGHTS];
|
||||||
int light_local_attenuation_loc[NV2A_MAX_LIGHTS];
|
int light_local_attenuation_loc[NV2A_MAX_LIGHTS];
|
||||||
|
int specular_power_loc;
|
||||||
|
|
||||||
int clip_region_loc;
|
int clip_region_loc;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue