From 9edbfd08bcfd3f05cc4079057d201736d4862b4a Mon Sep 17 00:00:00 2001 From: Jannik Vogel Date: Thu, 6 Aug 2015 16:22:03 +0200 Subject: [PATCH] Eye registers and smaller changes --- hw/xbox/nv2a.c | 50 ++++++++++++++++++++++++++++++++++++++++-- hw/xbox/nv2a_shaders.c | 6 +++-- 2 files changed, 52 insertions(+), 4 deletions(-) diff --git a/hw/xbox/nv2a.c b/hw/xbox/nv2a.c index b1b2636d1e..7809088c51 100644 --- a/hw/xbox/nv2a.c +++ b/hw/xbox/nv2a.c @@ -539,8 +539,11 @@ #define NV_PGRAPH_TEXPALETTE2 0x00001A3C #define NV_PGRAPH_TEXPALETTE3 0x00001A40 #define NV_PGRAPH_ZSTENCILCLEARVALUE 0x00001A88 -#define NV_PGRAPH_ZCLIPMAX 0x00001ABC #define NV_PGRAPH_ZCLIPMIN 0x00001A90 +#define NV_PGRAPH_EYEVEC0 0x00001AAC +#define NV_PGRAPH_EYEVEC1 0x00001AB0 +#define NV_PGRAPH_EYEVEC2 0x00001AB4 +#define NV_PGRAPH_ZCLIPMAX 0x00001ABC #define NV_PCRTC_INTR_0 0x00000100 @@ -894,6 +897,7 @@ # define NV097_SET_FOG_PLANE 0x009709D0 # define NV097_SET_SCENE_AMBIENT_COLOR 0x00970A10 # define NV097_SET_VIEWPORT_OFFSET 0x00970A20 +# define NV097_SET_EYE_POSITION 0x00970A50 # define NV097_SET_COMBINER_FACTOR0 0x00970A60 # define NV097_SET_COMBINER_FACTOR1 0x00970A80 # define NV097_SET_COMBINER_ALPHA_OCW 0x00970AA0 @@ -937,6 +941,7 @@ # define NV097_GET_REPORT_OFFSET 0x00FFFFFF # define NV097_GET_REPORT_TYPE 0xFF000000 # define NV097_GET_REPORT_TYPE_ZPASS_PIXEL_CNT 1 +# define NV097_SET_EYE_DIRECTION 0x009717E0 # define NV097_SET_SHADER_CLIP_PLANE_MODE 0x009717F8 # define NV097_SET_BEGIN_END 0x009717FC # define NV097_SET_BEGIN_END_OP_END 0x00 @@ -956,6 +961,7 @@ # define NV097_DRAW_ARRAYS_COUNT 0xFF000000 # define NV097_DRAW_ARRAYS_START_INDEX 0x00FFFFFF # define NV097_INLINE_ARRAY 0x00971818 +# define NV097_SET_EYE_VECTOR 0x0097181C # define NV097_SET_VERTEX_DATA2F_M 0x00971880 # define NV097_SET_VERTEX_DATA4F_M 0x00971A00 # define NV097_SET_VERTEX_DATA2S 0x00971900 @@ -1584,6 +1590,10 @@ typedef struct PGRAPHState { float light_local_position[NV2A_MAX_LIGHTS][3]; float light_local_attenuation[NV2A_MAX_LIGHTS][3]; + /* FIXME: These are probably stored in the vshader consts */ + float eye_position[4]; + float eye_direction[3]; + /* FIXME: Move to NV_PGRAPH_BUMPMAT... */ float bump_env_matrix[NV2A_MAX_TEXTURES-1][4]; /* 3 allowed stages with 2x2 matrix each */ @@ -3144,11 +3154,30 @@ static void pgraph_bind_shaders(PGRAPHState *pg) glUniformMatrix4fv(projLoc, 1, GL_FALSE, pg->projection_matrix); } + GLint eyeVecLoc = glGetUniformLocation(pg->shader_binding->gl_program, + "eyeVector"); + if (eyeVecLoc != -1) { + glUniform3f(eyeVecLoc, *(float*)&pg->regs[NV_PGRAPH_EYEVEC0], + *(float*)&pg->regs[NV_PGRAPH_EYEVEC1], + *(float*)&pg->regs[NV_PGRAPH_EYEVEC2]); + } + GLint eyePosLoc = glGetUniformLocation(pg->shader_binding->gl_program, + "eyePosition"); + if (eyePosLoc != -1) { + glUniform4fv(eyePosLoc, 1, pg->eye_position); + } + GLint eyeDirLoc = glGetUniformLocation(pg->shader_binding->gl_program, + "eyeDirection"); + if (eyeDirLoc != -1) { + glUniform3fv(eyeDirLoc, 1, pg->eye_direction); + } + /* FIXME: Only do this if lighting is allowed? I'd believe lighting works * with both FFP and VPs. */ + NV2A_GL_DGROUP_BEGIN("Lighting uniforms"); GLint ambLoc = glGetUniformLocation(pg->shader_binding->gl_program, - "sceneAmbientColor"); + "sceneAmbientColor"); if (ambLoc != -1) { glUniform3fv(ambLoc, 1, pg->scene_ambient_color); } @@ -3221,6 +3250,7 @@ static void pgraph_bind_shaders(PGRAPHState *pg) glUniform3fv(loc, 1, pg->light_local_attenuation[i]); } } + NV2A_GL_DGROUP_END(); float zclip_max = *(float*)&pg->regs[NV_PGRAPH_ZCLIPMAX]; float zclip_min = *(float*)&pg->regs[NV_PGRAPH_ZCLIPMIN]; @@ -4644,6 +4674,11 @@ static void pgraph_method(NV2AState *d, pg->constants[59].dirty = true; break; + case NV097_SET_EYE_POSITION ... + NV097_SET_EYE_POSITION + 12: + slot = (class_method - NV097_SET_EYE_POSITION) / 4; + pg->eye_position[slot] = *(float*)¶meter; + break; case NV097_SET_COMBINER_FACTOR0 ... NV097_SET_COMBINER_FACTOR0 + 28: slot = (class_method - NV097_SET_COMBINER_FACTOR0) / 4; @@ -5001,6 +5036,12 @@ static void pgraph_method(NV2AState *d, break; } + case NV097_SET_EYE_DIRECTION ... + NV097_SET_EYE_DIRECTION + 8: + slot = (class_method - NV097_SET_EYE_DIRECTION) / 4; + pg->eye_direction[slot] = *(float*)¶meter; + break; + case NV097_SET_BEGIN_END: { bool depth_test = pg->regs[NV_PGRAPH_CONTROL_0] & NV_PGRAPH_CONTROL_0_ZENABLE; @@ -5406,6 +5447,11 @@ static void pgraph_method(NV2AState *d, pg->inline_array[ pg->inline_array_length++] = parameter; break; + case NV097_SET_EYE_VECTOR ... + NV097_SET_EYE_VECTOR + 8: + slot = (class_method - NV097_SET_EYE_VECTOR) / 4; + pg->regs[NV_PGRAPH_EYEVEC0 + slot * 4] = parameter; + break; case NV097_SET_VERTEX_DATA2F_M ... NV097_SET_VERTEX_DATA2F_M + 0x7c: { diff --git a/hw/xbox/nv2a_shaders.c b/hw/xbox/nv2a_shaders.c index 82370fd42c..254678a6af 100644 --- a/hw/xbox/nv2a_shaders.c +++ b/hw/xbox/nv2a_shaders.c @@ -335,11 +335,13 @@ static QString* generate_fixed_function(const ShaderState state, if (state.light[i] == LIGHT_LOCAL || state.light[i] == LIGHT_SPOT) { + qstring_append(h, + "uniform vec4 eyePosition;\n"); + qstring_append_fmt(h, "uniform vec3 lightLocalPosition%d;\n" "uniform vec3 lightLocalAttenuation%d;\n", i, i); - qstring_append_fmt(s,"vec3 eye = vec3(0.0);\n"); /*FIXME: Uniform?! */ qstring_append_fmt(s, " vec3 VP = lightLocalPosition%d - tPosition.xyz/tPosition.w;\n" " float d = length(VP);\n" @@ -348,7 +350,7 @@ static QString* generate_fixed_function(const ShaderState state, " float attenuation = 1.0 / (lightLocalAttenuation%d.x\n" " + lightLocalAttenuation%d.y * d\n" " + lightLocalAttenuation%d.z * d * d);\n" - " vec3 halfVector = normalize(VP + eye);\n" + " vec3 halfVector = normalize(VP + eyePosition.xyz / eyePosition.w);\n" /* FIXME: Not sure if eyePosition is correct */ " float nDotVP = max(0.0, dot(tNormal, VP));\n" " float nDotHV = max(0.0, dot(tNormal, halfVector));\n", i, i, i, i);