diff --git a/hw/xbox/nv2a.c b/hw/xbox/nv2a.c index 58f20aa3bc..40d5d44219 100644 --- a/hw/xbox/nv2a.c +++ b/hw/xbox/nv2a.c @@ -866,6 +866,9 @@ static void gl_debug_label(GLenum target, GLuint name, const char *fmt, ...) # define NV097_SET_TEXGEN_T 0x009703C4 # define NV097_SET_TEXGEN_R 0x009703C8 # define NV097_SET_TEXGEN_Q 0x009703CC +# define NV097_SET_PROJECTION_MATRIX 0x00970440 +# define NV097_SET_MODEL_VIEW_MATRIX 0x00970480 +# define NV097_SET_INVERSE_MODEL_VIEW_MATRIX 0x00970580 # define NV097_SET_COMPOSITE_MATRIX 0x00970680 # define NV097_SET_TEXGEN_VIEW_MODEL 0x009709CC # define NV097_SET_TEXGEN_VIEW_MODEL_LOCAL_VIEWER 0 @@ -1493,6 +1496,11 @@ typedef struct PGRAPHState { float composite_matrix[16]; + /* FIXME: These are probably stored in the vshader consts */ + float projection_matrix[16]; + float inverse_model_view_matrix[4][16]; /* 4 weights with 4x4 matrix each */ + float model_view_matrix[4][16]; /* 4 weights with 4x4 matrix each */ + /* FIXME: Move to NV_PGRAPH_BUMPMAT... */ float bump_env_matrix[3][4]; /* 4 stages with 2x2 matrix each */ @@ -2630,6 +2638,15 @@ static ShaderBinding* generate_shaders(const ShaderState state) qstring_append(vertex_shader_code, "\n" "uniform mat4 composite;\n" +"uniform mat4 modelViewMat0;\n" +"uniform mat4 modelViewMat1;\n" +"uniform mat4 modelViewMat2;\n" +"uniform mat4 modelViewMat3;\n" +"uniform mat4 invModelViewMat0;\n" +"uniform mat4 invModelViewMat1;\n" +"uniform mat4 invModelViewMat2;\n" +"uniform mat4 invModelViewMat3;\n" +"uniform mat4 projectionMat;\n" "uniform mat4 invViewport;\n" "void main() {\n" " gl_Position = invViewport * (position * composite);\n" @@ -3034,6 +3051,33 @@ static void pgraph_bind_shaders(PGRAPHState *pg) } + /* For each vertex weight */ + for (i = 0; i < 4; i++) { + char name[16]; + GLint loc; + + sprintf(name, "modelViewMat%d", i); + loc = glGetUniformLocation(pg->shader_binding->gl_program, name); + if (loc != -1) { + glUniformMatrix4fv(loc, 1, GL_FALSE, + pg->model_view_matrix[i]); + } + + sprintf(name, "invModelViewMat%d", i); + loc = glGetUniformLocation(pg->shader_binding->gl_program, name); + if (loc != -1) { + glUniformMatrix4fv(loc, 1, GL_FALSE, + pg->inverse_model_view_matrix[i]); + } + + } + + GLint projLoc = glGetUniformLocation(pg->shader_binding->gl_program, + "projectionMat"); + if (projLoc != -1) { + glUniformMatrix4fv(projLoc, 1, GL_FALSE, pg->projection_matrix); + } + float zclip_max = *(float*)&pg->regs[NV_PGRAPH_ZCLIPMAX]; float zclip_min = *(float*)&pg->regs[NV_PGRAPH_ZCLIPMIN]; @@ -4255,6 +4299,24 @@ static void pgraph_method(NV2AState *d, break; } + case NV097_SET_PROJECTION_MATRIX ... + NV097_SET_PROJECTION_MATRIX + 0x3c: + slot = (class_method - NV097_SET_PROJECTION_MATRIX) / 4; + pg->projection_matrix[slot] = *(float*)¶meter; + break; + + case NV097_SET_MODEL_VIEW_MATRIX ... + NV097_SET_MODEL_VIEW_MATRIX + 0xfc: + slot = (class_method - NV097_SET_MODEL_VIEW_MATRIX) / 4; + pg->model_view_matrix[slot / 16][slot % 16] = *(float*)¶meter; + break; + + case NV097_SET_INVERSE_MODEL_VIEW_MATRIX ... + NV097_SET_INVERSE_MODEL_VIEW_MATRIX + 0xfc: + slot = (class_method - NV097_SET_INVERSE_MODEL_VIEW_MATRIX) / 4; + pg->inverse_model_view_matrix[slot / 16][slot % 16] = *(float*)¶meter; + break; + case NV097_SET_COMPOSITE_MATRIX ... NV097_SET_COMPOSITE_MATRIX + 0x3c: slot = (class_method - NV097_SET_COMPOSITE_MATRIX) / 4;