static struct ureg get_eye_normal( struct tnl_program *p ) { if (is_undef(p->eye_normal)) { struct ureg normal = register_input(p, VERT_ATTRIB_NORMAL ); struct ureg mvinv[3]; register_matrix_param5( p, STATE_MODELVIEW_MATRIX, 0, 0, 2, STATE_MATRIX_INVTRANS, mvinv ); p->eye_normal = reserve_temp(p); /* Transform to eye space: */ emit_matrix_transform_vec3( p, p->eye_normal, mvinv, normal ); /* Normalize/Rescale: */ if (p->state->normalize) { emit_normalize_vec3( p, p->eye_normal, p->eye_normal ); } else if (p->state->rescale_normals) { struct ureg rescale = register_param2(p, STATE_INTERNAL, STATE_NORMAL_SCALE); emit_op2( p, OPCODE_MUL, p->eye_normal, 0, p->eye_normal, swizzle1(rescale, X)); } } return p->eye_normal; }
static void build_hpos( struct tnl_program *p ) { struct ureg pos = register_input( p, VERT_ATTRIB_POS ); struct ureg hpos = register_output( p, VERT_RESULT_HPOS ); struct ureg mvp[4]; if (p->mvp_with_dp4) { register_matrix_param5( p, STATE_MVP_MATRIX, 0, 0, 3, 0, mvp ); emit_matrix_transform_vec4( p, hpos, mvp, pos ); } else { register_matrix_param5( p, STATE_MVP_MATRIX, 0, 0, 3, STATE_MATRIX_TRANSPOSE, mvp ); emit_transpose_matrix_transform_vec4( p, hpos, mvp, pos ); } }
static struct ureg get_eye_position( struct tnl_program *p ) { if (is_undef(p->eye_position)) { struct ureg pos = register_input( p, VERT_ATTRIB_POS ); struct ureg modelview[4]; p->eye_position = reserve_temp(p); if (p->mvp_with_dp4) { register_matrix_param5( p, STATE_MODELVIEW_MATRIX, 0, 0, 3, 0, modelview ); emit_matrix_transform_vec4(p, p->eye_position, modelview, pos); } else { register_matrix_param5( p, STATE_MODELVIEW_MATRIX, 0, 0, 3, STATE_MATRIX_TRANSPOSE, modelview ); emit_transpose_matrix_transform_vec4(p, p->eye_position, modelview, pos); } } return p->eye_position; }
static struct ureg get_transformed_normal( struct tnl_program *p ) { if (is_undef(p->transformed_normal) && !p->state->need_eye_coords && !p->state->normalize && !(p->state->need_eye_coords == p->state->rescale_normals)) { p->transformed_normal = register_input(p, VERT_ATTRIB_NORMAL ); } else if (is_undef(p->transformed_normal)) { struct ureg normal = register_input(p, VERT_ATTRIB_NORMAL ); struct ureg mvinv[3]; struct ureg transformed_normal = reserve_temp(p); if (p->state->need_eye_coords) { register_matrix_param5( p, STATE_MODELVIEW_MATRIX, 0, 0, 2, STATE_MATRIX_INVTRANS, mvinv ); /* Transform to eye space: */ emit_matrix_transform_vec3( p, transformed_normal, mvinv, normal ); normal = transformed_normal; } /* Normalize/Rescale: */ if (p->state->normalize) { emit_normalize_vec3( p, transformed_normal, normal ); normal = transformed_normal; } else if (p->state->need_eye_coords == p->state->rescale_normals) { /* This is already adjusted for eye/non-eye rendering: */ struct ureg rescale = register_param2(p, STATE_INTERNAL, STATE_NORMAL_SCALE); emit_op2( p, OPCODE_MUL, transformed_normal, 0, normal, rescale ); normal = transformed_normal; } assert(normal.file == PROGRAM_TEMPORARY); p->transformed_normal = normal; } return p->transformed_normal; }
static struct ureg get_eye_position_z( struct tnl_program *p ) { if (!is_undef(p->eye_position)) return swizzle1(p->eye_position, Z); if (is_undef(p->eye_position_z)) { struct ureg pos = register_input( p, VERT_ATTRIB_POS ); struct ureg modelview[4]; p->eye_position_z = reserve_temp(p); register_matrix_param5( p, STATE_MODELVIEW_MATRIX, 0, 0, 3, 0, modelview ); emit_op2(p, OPCODE_DP4, p->eye_position_z, 0, pos, modelview[2]); } return p->eye_position_z; }
static void build_texture_transform( struct tnl_program *p ) { GLuint i, j; for (i = 0; i < MAX_TEXTURE_COORD_UNITS; i++) { if (!(p->state->fragprog_inputs_read & FRAG_BIT_TEX(i))) continue; if (p->state->unit[i].texgen_enabled || p->state->unit[i].texmat_enabled) { GLuint texmat_enabled = p->state->unit[i].texmat_enabled; struct ureg out = register_output(p, VERT_RESULT_TEX0 + i); struct ureg out_texgen = undef; if (p->state->unit[i].texgen_enabled) { GLuint copy_mask = 0; GLuint sphere_mask = 0; GLuint reflect_mask = 0; GLuint normal_mask = 0; GLuint modes[4]; if (texmat_enabled) out_texgen = get_temp(p); else out_texgen = out; modes[0] = p->state->unit[i].texgen_mode0; modes[1] = p->state->unit[i].texgen_mode1; modes[2] = p->state->unit[i].texgen_mode2; modes[3] = p->state->unit[i].texgen_mode3; for (j = 0; j < 4; j++) { switch (modes[j]) { case TXG_OBJ_LINEAR: { struct ureg obj = register_input(p, VERT_ATTRIB_POS); struct ureg plane = register_param3(p, STATE_TEXGEN, i, STATE_TEXGEN_OBJECT_S + j); emit_op2(p, OPCODE_DP4, out_texgen, WRITEMASK_X << j, obj, plane ); break; } case TXG_EYE_LINEAR: { struct ureg eye = get_eye_position(p); struct ureg plane = register_param3(p, STATE_TEXGEN, i, STATE_TEXGEN_EYE_S + j); emit_op2(p, OPCODE_DP4, out_texgen, WRITEMASK_X << j, eye, plane ); break; } case TXG_SPHERE_MAP: sphere_mask |= WRITEMASK_X << j; break; case TXG_REFLECTION_MAP: reflect_mask |= WRITEMASK_X << j; break; case TXG_NORMAL_MAP: normal_mask |= WRITEMASK_X << j; break; case TXG_NONE: copy_mask |= WRITEMASK_X << j; } } if (sphere_mask) { build_sphere_texgen(p, out_texgen, sphere_mask); } if (reflect_mask) { build_reflect_texgen(p, out_texgen, reflect_mask); } if (normal_mask) { struct ureg normal = get_transformed_normal(p); emit_op1(p, OPCODE_MOV, out_texgen, normal_mask, normal ); } if (copy_mask) { struct ureg in = register_input(p, VERT_ATTRIB_TEX0+i); emit_op1(p, OPCODE_MOV, out_texgen, copy_mask, in ); } } if (texmat_enabled) { struct ureg texmat[4]; struct ureg in = (!is_undef(out_texgen) ? out_texgen : register_input(p, VERT_ATTRIB_TEX0+i)); if (p->mvp_with_dp4) { register_matrix_param5( p, STATE_TEXTURE_MATRIX, i, 0, 3, 0, texmat ); emit_matrix_transform_vec4( p, out, texmat, in ); } else { register_matrix_param5( p, STATE_TEXTURE_MATRIX, i, 0, 3, STATE_MATRIX_TRANSPOSE, texmat ); emit_transpose_matrix_transform_vec4( p, out, texmat, in ); } } release_temps(p); } else { emit_passthrough(p, VERT_ATTRIB_TEX0+i, VERT_RESULT_TEX0+i); } } }