mirror of https://github.com/xemu-project/xemu.git
nv2a: Implement SET_SHADE_MODEL
This commit is contained in:
parent
0d84befb82
commit
4132845336
|
@ -348,6 +348,8 @@ typedef struct PGRAPHState {
|
|||
bool ltc1_dirty[NV2A_LTC1_COUNT];
|
||||
|
||||
float material_alpha;
|
||||
// FIXME: Find the correct register for this.
|
||||
uint32_t shade_model;
|
||||
|
||||
// should figure out where these are in lighting context
|
||||
float light_infinite_half_vector[NV2A_MAX_LIGHTS][3];
|
||||
|
|
|
@ -974,6 +974,9 @@
|
|||
# define NV097_SET_STENCIL_OP_V_INVERT 0x150A
|
||||
# define NV097_SET_STENCIL_OP_V_INCR 0x8507
|
||||
# define NV097_SET_STENCIL_OP_V_DECR 0x8508
|
||||
# define NV097_SET_SHADE_MODEL 0x0000037C
|
||||
# define NV097_SET_SHADE_MODEL_FLAT 0x1D00
|
||||
# define NV097_SET_SHADE_MODEL_SMOOTH 0x1D01
|
||||
# define NV097_SET_POLYGON_OFFSET_SCALE_FACTOR 0x00000384
|
||||
# define NV097_SET_POLYGON_OFFSET_BIAS 0x00000388
|
||||
# define NV097_SET_FRONT_POLYGON_MODE 0x0000038C
|
||||
|
|
|
@ -1840,6 +1840,12 @@ DEF_METHOD(NV097, SET_STENCIL_OP_ZPASS)
|
|||
kelvin_map_stencil_op(parameter));
|
||||
}
|
||||
|
||||
DEF_METHOD(NV097, SET_SHADE_MODEL)
|
||||
{
|
||||
// FIXME: Find the correct register for this.
|
||||
pg->shade_model = parameter;
|
||||
}
|
||||
|
||||
DEF_METHOD(NV097, SET_POLYGON_OFFSET_SCALE_FACTOR)
|
||||
{
|
||||
pg->regs[NV_PGRAPH_ZOFFSETFACTOR] = parameter;
|
||||
|
@ -2973,6 +2979,10 @@ DEF_METHOD(NV097, SET_BEGIN_END)
|
|||
glDisable(GL_DEPTH_CLAMP);
|
||||
}
|
||||
|
||||
if (pg->shade_model == NV097_SET_SHADE_MODEL_FLAT) {
|
||||
glProvokingVertex(GL_FIRST_VERTEX_CONVENTION);
|
||||
}
|
||||
|
||||
if (stencil_test) {
|
||||
glEnable(GL_STENCIL_TEST);
|
||||
|
||||
|
@ -3996,6 +4006,7 @@ void pgraph_init(NV2AState *d)
|
|||
pg->shader_cache = g_hash_table_new(shader_hash, shader_equal);
|
||||
|
||||
pg->material_alpha = 0.0f;
|
||||
pg->shade_model = NV097_SET_SHADE_MODEL_SMOOTH;
|
||||
pg->primitive_mode = PRIM_TYPE_INVALID;
|
||||
|
||||
for (i=0; i<NV2A_VERTEXSHADER_ATTRIBUTES; i++) {
|
||||
|
@ -4320,6 +4331,7 @@ static bool pgraph_bind_shaders_test_dirty(PGRAPHState *pg)
|
|||
CR_8(NV_PGRAPH_WINDOWCLIPX0) \
|
||||
CR_8(NV_PGRAPH_WINDOWCLIPY0) \
|
||||
CF(pg->primitive_mode, primitive_mode) \
|
||||
CF(pg->shade_model, shade_model) \
|
||||
CF(pg->surface_scale_factor, surface_scale_factor) \
|
||||
CF(pg->compressed_attrs, compressed_attrs) \
|
||||
CFA(pg->texture_matrix_enable, texture_matrix_enable)
|
||||
|
@ -4441,6 +4453,9 @@ static void pgraph_bind_shaders(PGRAPHState *pg)
|
|||
state.polygon_back_mode = (enum ShaderPolygonMode)GET_MASK(pg->regs[NV_PGRAPH_SETUPRASTER],
|
||||
NV_PGRAPH_SETUPRASTER_BACKFACEMODE);
|
||||
|
||||
state.shade_model_flat = pg->shade_model == NV097_SET_SHADE_MODEL_FLAT;
|
||||
state.psh.shade_model_flat = pg->shade_model == NV097_SET_SHADE_MODEL_FLAT;
|
||||
|
||||
state.program_length = 0;
|
||||
|
||||
if (vertex_program) {
|
||||
|
|
|
@ -66,6 +66,7 @@ DEF_METHOD(NV097, SET_STENCIL_FUNC_MASK)
|
|||
DEF_METHOD(NV097, SET_STENCIL_OP_FAIL)
|
||||
DEF_METHOD(NV097, SET_STENCIL_OP_ZFAIL)
|
||||
DEF_METHOD(NV097, SET_STENCIL_OP_ZPASS)
|
||||
DEF_METHOD(NV097, SET_SHADE_MODEL)
|
||||
DEF_METHOD(NV097, SET_POLYGON_OFFSET_SCALE_FACTOR)
|
||||
DEF_METHOD(NV097, SET_POLYGON_OFFSET_BIAS)
|
||||
DEF_METHOD(NV097, SET_FRONT_POLYGON_MODE)
|
||||
|
|
|
@ -690,9 +690,8 @@ static MString* psh_convert(struct PixelShader *ps)
|
|||
int i;
|
||||
|
||||
MString *preflight = mstring_new();
|
||||
mstring_append(preflight, STRUCT_VERTEX_DATA);
|
||||
mstring_append(preflight, "noperspective in VertexData g_vtx;\n");
|
||||
mstring_append(preflight, "#define vtx g_vtx\n");
|
||||
mstring_append(preflight,
|
||||
ps->state.shade_model_flat ? STRUCT_VERTEX_DATA_IN_FLAT : STRUCT_VERTEX_DATA_IN_SMOOTH);
|
||||
mstring_append(preflight, "\n");
|
||||
mstring_append(preflight, "out vec4 fragColor;\n");
|
||||
mstring_append(preflight, "\n");
|
||||
|
@ -801,19 +800,19 @@ static MString* psh_convert(struct PixelShader *ps)
|
|||
|
||||
/* calculate perspective-correct inputs */
|
||||
MString *vars = mstring_new();
|
||||
mstring_append(vars, "vec4 pD0 = vtx.D0 / vtx.inv_w;\n");
|
||||
mstring_append(vars, "vec4 pD1 = vtx.D1 / vtx.inv_w;\n");
|
||||
mstring_append(vars, "vec4 pB0 = vtx.B0 / vtx.inv_w;\n");
|
||||
mstring_append(vars, "vec4 pB1 = vtx.B1 / vtx.inv_w;\n");
|
||||
mstring_append(vars, "vec4 pFog = vec4(fogColor.rgb, clamp(vtx.Fog / vtx.inv_w, 0.0, 1.0));\n");
|
||||
mstring_append(vars, "vec4 pT0 = vtx.T0 / vtx.inv_w;\n");
|
||||
mstring_append(vars, "vec4 pT1 = vtx.T1 / vtx.inv_w;\n");
|
||||
mstring_append(vars, "vec4 pT2 = vtx.T2 / vtx.inv_w;\n");
|
||||
mstring_append(vars, "vec4 pD0 = vtxD0 / vtx_inv_w;\n");
|
||||
mstring_append(vars, "vec4 pD1 = vtxD1 / vtx_inv_w;\n");
|
||||
mstring_append(vars, "vec4 pB0 = vtxB0 / vtx_inv_w;\n");
|
||||
mstring_append(vars, "vec4 pB1 = vtxB1 / vtx_inv_w;\n");
|
||||
mstring_append(vars, "vec4 pFog = vec4(fogColor.rgb, clamp(vtxFog / vtx_inv_w, 0.0, 1.0));\n");
|
||||
mstring_append(vars, "vec4 pT0 = vtxT0 / vtx_inv_w;\n");
|
||||
mstring_append(vars, "vec4 pT1 = vtxT1 / vtx_inv_w;\n");
|
||||
mstring_append(vars, "vec4 pT2 = vtxT2 / vtx_inv_w;\n");
|
||||
if (ps->state.point_sprite) {
|
||||
assert(!ps->state.rect_tex[3]);
|
||||
mstring_append(vars, "vec4 pT3 = vec4(gl_PointCoord, 1.0, 1.0);\n");
|
||||
} else {
|
||||
mstring_append(vars, "vec4 pT3 = vtx.T3 / vtx.inv_w;\n");
|
||||
mstring_append(vars, "vec4 pT3 = vtxT3 / vtx_inv_w;\n");
|
||||
}
|
||||
mstring_append(vars, "\n");
|
||||
mstring_append(vars, "vec4 v0 = pD0;\n");
|
||||
|
|
|
@ -78,6 +78,8 @@ typedef struct PshState {
|
|||
enum PshAlphaFunc alpha_func;
|
||||
|
||||
bool window_clip_exclusive;
|
||||
|
||||
bool shade_model_flat;
|
||||
} PshState;
|
||||
|
||||
MString *psh_translate(const PshState state);
|
||||
|
|
|
@ -75,7 +75,8 @@ static MString* generate_geometry_shader(
|
|||
enum ShaderPolygonMode polygon_front_mode,
|
||||
enum ShaderPolygonMode polygon_back_mode,
|
||||
enum ShaderPrimitiveMode primitive_mode,
|
||||
GLenum *gl_primitive_mode)
|
||||
GLenum *gl_primitive_mode,
|
||||
bool shade_model_flat)
|
||||
{
|
||||
|
||||
/* FIXME: Missing support for 2-sided-poly mode */
|
||||
|
@ -103,10 +104,10 @@ static MString* generate_geometry_shader(
|
|||
assert(polygon_mode == POLY_MODE_LINE);
|
||||
layout_in = "layout(triangles) in;\n";
|
||||
layout_out = "layout(line_strip, max_vertices = 4) out;\n";
|
||||
body = " emit_vertex(0);\n"
|
||||
" emit_vertex(1);\n"
|
||||
" emit_vertex(2);\n"
|
||||
" emit_vertex(0);\n"
|
||||
body = " emit_vertex(0, 0);\n"
|
||||
" emit_vertex(1, 0);\n"
|
||||
" emit_vertex(2, 0);\n"
|
||||
" emit_vertex(0, 0);\n"
|
||||
" EndPrimitive();\n";
|
||||
break;
|
||||
case PRIM_TYPE_TRIANGLE_STRIP:
|
||||
|
@ -119,15 +120,15 @@ static MString* generate_geometry_shader(
|
|||
* vertex we are using */
|
||||
body = " if ((gl_PrimitiveIDIn & 1) == 0) {\n"
|
||||
" if (gl_PrimitiveIDIn == 0) {\n"
|
||||
" emit_vertex(0);\n" /* bottom right */
|
||||
" emit_vertex(0, 0);\n" /* bottom right */
|
||||
" }\n"
|
||||
" emit_vertex(1);\n" /* top right */
|
||||
" emit_vertex(2);\n" /* bottom left */
|
||||
" emit_vertex(0);\n" /* bottom right */
|
||||
" emit_vertex(1, 0);\n" /* top right */
|
||||
" emit_vertex(2, 0);\n" /* bottom left */
|
||||
" emit_vertex(0, 0);\n" /* bottom right */
|
||||
" } else {\n"
|
||||
" emit_vertex(2);\n" /* bottom left */
|
||||
" emit_vertex(1);\n" /* top left */
|
||||
" emit_vertex(0);\n" /* top right */
|
||||
" emit_vertex(2, 0);\n" /* bottom left */
|
||||
" emit_vertex(1, 0);\n" /* top left */
|
||||
" emit_vertex(0, 0);\n" /* top right */
|
||||
" }\n"
|
||||
" EndPrimitive();\n";
|
||||
break;
|
||||
|
@ -140,9 +141,9 @@ static MString* generate_geometry_shader(
|
|||
body = " if (gl_PrimitiveIDIn == 0) {\n"
|
||||
" emit_vertex(0);\n"
|
||||
" }\n"
|
||||
" emit_vertex(1);\n"
|
||||
" emit_vertex(2);\n"
|
||||
" emit_vertex(0);\n"
|
||||
" emit_vertex(1, 0);\n"
|
||||
" emit_vertex(2, 0);\n"
|
||||
" emit_vertex(0, 0);\n"
|
||||
" EndPrimitive();\n";
|
||||
break;
|
||||
case PRIM_TYPE_QUADS:
|
||||
|
@ -150,18 +151,18 @@ static MString* generate_geometry_shader(
|
|||
layout_in = "layout(lines_adjacency) in;\n";
|
||||
if (polygon_mode == POLY_MODE_LINE) {
|
||||
layout_out = "layout(line_strip, max_vertices = 5) out;\n";
|
||||
body = " emit_vertex(0);\n"
|
||||
" emit_vertex(1);\n"
|
||||
" emit_vertex(2);\n"
|
||||
" emit_vertex(3);\n"
|
||||
" emit_vertex(0);\n"
|
||||
body = " emit_vertex(0, 3);\n"
|
||||
" emit_vertex(1, 3);\n"
|
||||
" emit_vertex(2, 3);\n"
|
||||
" emit_vertex(3, 3);\n"
|
||||
" emit_vertex(0, 3);\n"
|
||||
" EndPrimitive();\n";
|
||||
} else if (polygon_mode == POLY_MODE_FILL) {
|
||||
layout_out = "layout(triangle_strip, max_vertices = 4) out;\n";
|
||||
body = " emit_vertex(0);\n"
|
||||
" emit_vertex(1);\n"
|
||||
" emit_vertex(3);\n"
|
||||
" emit_vertex(2);\n"
|
||||
body = " emit_vertex(3, 3);\n"
|
||||
" emit_vertex(0, 3);\n"
|
||||
" emit_vertex(2, 3);\n"
|
||||
" emit_vertex(1, 3);\n"
|
||||
" EndPrimitive();\n";
|
||||
} else {
|
||||
assert(false);
|
||||
|
@ -175,20 +176,20 @@ static MString* generate_geometry_shader(
|
|||
layout_out = "layout(line_strip, max_vertices = 5) out;\n";
|
||||
body = " if ((gl_PrimitiveIDIn & 1) != 0) { return; }\n"
|
||||
" if (gl_PrimitiveIDIn == 0) {\n"
|
||||
" emit_vertex(0);\n"
|
||||
" emit_vertex(0, 3);\n"
|
||||
" }\n"
|
||||
" emit_vertex(1);\n"
|
||||
" emit_vertex(3);\n"
|
||||
" emit_vertex(2);\n"
|
||||
" emit_vertex(0);\n"
|
||||
" emit_vertex(1, 3);\n"
|
||||
" emit_vertex(3, 3);\n"
|
||||
" emit_vertex(2, 3);\n"
|
||||
" emit_vertex(0, 3);\n"
|
||||
" EndPrimitive();\n";
|
||||
} else if (polygon_mode == POLY_MODE_FILL) {
|
||||
layout_out = "layout(triangle_strip, max_vertices = 4) out;\n";
|
||||
body = " if ((gl_PrimitiveIDIn & 1) != 0) { return; }\n"
|
||||
" emit_vertex(0);\n"
|
||||
" emit_vertex(1);\n"
|
||||
" emit_vertex(2);\n"
|
||||
" emit_vertex(3);\n"
|
||||
" emit_vertex(0, 3);\n"
|
||||
" emit_vertex(1, 3);\n"
|
||||
" emit_vertex(2, 3);\n"
|
||||
" emit_vertex(3, 3);\n"
|
||||
" EndPrimitive();\n";
|
||||
} else {
|
||||
assert(false);
|
||||
|
@ -198,12 +199,25 @@ static MString* generate_geometry_shader(
|
|||
case PRIM_TYPE_POLYGON:
|
||||
if (polygon_mode == POLY_MODE_LINE) {
|
||||
*gl_primitive_mode = GL_LINE_LOOP;
|
||||
} else if (polygon_mode == POLY_MODE_FILL) {
|
||||
return NULL;
|
||||
}
|
||||
if (polygon_mode == POLY_MODE_FILL) {
|
||||
*gl_primitive_mode = GL_TRIANGLE_FAN;
|
||||
if (!shade_model_flat) {
|
||||
return NULL;
|
||||
}
|
||||
layout_in = "layout(triangles) in;\n";
|
||||
layout_out = "layout(triangle_strip, max_vertices = 3) out;\n";
|
||||
body = " emit_vertex(0, 2);\n"
|
||||
" emit_vertex(1, 2);\n"
|
||||
" emit_vertex(2, 2);\n"
|
||||
" EndPrimitive();\n";
|
||||
} else {
|
||||
assert(false);
|
||||
return NULL;
|
||||
}
|
||||
return NULL;
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(false);
|
||||
return NULL;
|
||||
|
@ -217,18 +231,52 @@ static MString* generate_geometry_shader(
|
|||
"\n");
|
||||
mstring_append(s, layout_in);
|
||||
mstring_append(s, layout_out);
|
||||
mstring_append(s, "\n");
|
||||
if (shade_model_flat) {
|
||||
mstring_append(s,
|
||||
STRUCT_V_VERTEX_DATA_IN_ARRAY_FLAT
|
||||
"\n"
|
||||
STRUCT_VERTEX_DATA_OUT_FLAT
|
||||
"\n"
|
||||
"void emit_vertex(int index, int provoking_index) {\n"
|
||||
" gl_Position = gl_in[index].gl_Position;\n"
|
||||
" gl_PointSize = gl_in[index].gl_PointSize;\n"
|
||||
" vtx_inv_w = v_vtx_inv_w[index];\n"
|
||||
" vtxD0 = v_vtxD0[provoking_index];\n"
|
||||
" vtxD1 = v_vtxD1[provoking_index];\n"
|
||||
" vtxB0 = v_vtxB0[provoking_index];\n"
|
||||
" vtxB1 = v_vtxB1[provoking_index];\n"
|
||||
" vtxFog = v_vtxFog[index];\n"
|
||||
" vtxT0 = v_vtxT0[index];\n"
|
||||
" vtxT1 = v_vtxT1[index];\n"
|
||||
" vtxT2 = v_vtxT2[index];\n"
|
||||
" vtxT3 = v_vtxT3[index];\n"
|
||||
" EmitVertex();\n"
|
||||
"}\n");
|
||||
} else {
|
||||
mstring_append(s,
|
||||
STRUCT_V_VERTEX_DATA_IN_ARRAY_SMOOTH
|
||||
"\n"
|
||||
STRUCT_VERTEX_DATA_OUT_SMOOTH
|
||||
"\n"
|
||||
"void emit_vertex(int index, int _unused) {\n"
|
||||
" gl_Position = gl_in[index].gl_Position;\n"
|
||||
" gl_PointSize = gl_in[index].gl_PointSize;\n"
|
||||
" vtx_inv_w = v_vtx_inv_w[index];\n"
|
||||
" vtxD0 = v_vtxD0[index];\n"
|
||||
" vtxD1 = v_vtxD1[index];\n"
|
||||
" vtxB0 = v_vtxB0[index];\n"
|
||||
" vtxB1 = v_vtxB1[index];\n"
|
||||
" vtxFog = v_vtxFog[index];\n"
|
||||
" vtxT0 = v_vtxT0[index];\n"
|
||||
" vtxT1 = v_vtxT1[index];\n"
|
||||
" vtxT2 = v_vtxT2[index];\n"
|
||||
" vtxT3 = v_vtxT3[index];\n"
|
||||
" EmitVertex();\n"
|
||||
"}\n");
|
||||
}
|
||||
|
||||
mstring_append(s, "\n"
|
||||
STRUCT_VERTEX_DATA
|
||||
"noperspective in VertexData v_vtx[];\n"
|
||||
"noperspective out VertexData g_vtx;\n"
|
||||
"\n"
|
||||
"void emit_vertex(int index) {\n"
|
||||
" gl_Position = gl_in[index].gl_Position;\n"
|
||||
" gl_PointSize = gl_in[index].gl_PointSize;\n"
|
||||
" g_vtx = v_vtx[index];\n"
|
||||
" EmitVertex();\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"void main() {\n");
|
||||
mstring_append(s, body);
|
||||
mstring_append(s, "}\n");
|
||||
|
@ -694,17 +742,16 @@ GLSL_DEFINE(materialEmissionColor, GLSL_LTCTXA(NV_IGRAPH_XF_LTCTXA_CM_COL) ".xyz
|
|||
state->surface_scale_factor);
|
||||
}
|
||||
|
||||
|
||||
mstring_append(body,
|
||||
" if (oPos.w == 0.0 || isinf(oPos.w)) {\n"
|
||||
" vtx.inv_w = 1.0;\n"
|
||||
" vtx_inv_w = 1.0;\n"
|
||||
" } else {\n"
|
||||
" vtx.inv_w = 1.0 / oPos.w;\n"
|
||||
" vtx_inv_w = 1.0 / oPos.w;\n"
|
||||
" }\n");
|
||||
}
|
||||
|
||||
static MString *generate_vertex_shader(const ShaderState *state,
|
||||
char vtx_prefix)
|
||||
bool prefix_outputs)
|
||||
{
|
||||
int i;
|
||||
MString *header = mstring_from_str(
|
||||
|
@ -758,13 +805,32 @@ GLSL_DEFINE(texMat3, GLSL_C_MAT4(NV_IGRAPH_XF_XFCTX_T3MAT))
|
|||
" float y = float(bitfieldExtract(cmp, 11, 11)) / 1023.0;\n"
|
||||
" float z = float(bitfieldExtract(cmp, 22, 10)) / 511.0;\n"
|
||||
" return vec4(x, y, z, 1);\n"
|
||||
"}\n"
|
||||
STRUCT_VERTEX_DATA);
|
||||
|
||||
mstring_append_fmt(header, "noperspective out VertexData %c_vtx;\n",
|
||||
vtx_prefix);
|
||||
mstring_append_fmt(header, "#define vtx %c_vtx\n",
|
||||
vtx_prefix);
|
||||
"}\n");
|
||||
if (prefix_outputs) {
|
||||
if (state->shade_model_flat) {
|
||||
mstring_append(header, STRUCT_V_VERTEX_DATA_OUT_FLAT);
|
||||
} else {
|
||||
mstring_append(header, STRUCT_V_VERTEX_DATA_OUT_SMOOTH);
|
||||
}
|
||||
mstring_append(header,
|
||||
"#define vtx_inv_w v_vtx_inv_w\n"
|
||||
"#define vtxD0 v_vtxD0\n"
|
||||
"#define vtxD1 v_vtxD1\n"
|
||||
"#define vtxB0 v_vtxB0\n"
|
||||
"#define vtxB1 v_vtxB1\n"
|
||||
"#define vtxFog v_vtxFog\n"
|
||||
"#define vtxT0 v_vtxT0\n"
|
||||
"#define vtxT1 v_vtxT1\n"
|
||||
"#define vtxT2 v_vtxT2\n"
|
||||
"#define vtxT3 v_vtxT3\n"
|
||||
);
|
||||
} else {
|
||||
if (state->shade_model_flat) {
|
||||
mstring_append(header, STRUCT_VERTEX_DATA_OUT_FLAT);
|
||||
} else {
|
||||
mstring_append(header, STRUCT_VERTEX_DATA_OUT_SMOOTH);
|
||||
}
|
||||
}
|
||||
mstring_append(header, "\n");
|
||||
for (i = 0; i < NV2A_VERTEXSHADER_ATTRIBUTES; i++) {
|
||||
if (state->compressed_attrs & (1 << i)) {
|
||||
|
@ -885,15 +951,15 @@ STRUCT_VERTEX_DATA);
|
|||
|
||||
/* Set outputs */
|
||||
mstring_append(body, "\n"
|
||||
" vtx.D0 = clamp(oD0, 0.0, 1.0) * vtx.inv_w;\n"
|
||||
" vtx.D1 = clamp(oD1, 0.0, 1.0) * vtx.inv_w;\n"
|
||||
" vtx.B0 = clamp(oB0, 0.0, 1.0) * vtx.inv_w;\n"
|
||||
" vtx.B1 = clamp(oB1, 0.0, 1.0) * vtx.inv_w;\n"
|
||||
" vtx.Fog = oFog.x * vtx.inv_w;\n"
|
||||
" vtx.T0 = oT0 * vtx.inv_w;\n"
|
||||
" vtx.T1 = oT1 * vtx.inv_w;\n"
|
||||
" vtx.T2 = oT2 * vtx.inv_w;\n"
|
||||
" vtx.T3 = oT3 * vtx.inv_w;\n"
|
||||
" vtxD0 = clamp(oD0, 0.0, 1.0) * vtx_inv_w;\n"
|
||||
" vtxD1 = clamp(oD1, 0.0, 1.0) * vtx_inv_w;\n"
|
||||
" vtxB0 = clamp(oB0, 0.0, 1.0) * vtx_inv_w;\n"
|
||||
" vtxB1 = clamp(oB1, 0.0, 1.0) * vtx_inv_w;\n"
|
||||
" vtxFog = oFog.x * vtx_inv_w;\n"
|
||||
" vtxT0 = oT0 * vtx_inv_w;\n"
|
||||
" vtxT1 = oT1 * vtx_inv_w;\n"
|
||||
" vtxT2 = oT2 * vtx_inv_w;\n"
|
||||
" vtxT3 = oT3 * vtx_inv_w;\n"
|
||||
" gl_Position = oPos;\n"
|
||||
" gl_PointSize = oPts.x;\n"
|
||||
"\n"
|
||||
|
@ -955,7 +1021,6 @@ ShaderBinding *generate_shaders(const ShaderState *state)
|
|||
/* Ensure numeric values are printed with '.' radix, no grouping */
|
||||
setlocale(LC_NUMERIC, "C");
|
||||
|
||||
char vtx_prefix;
|
||||
GLuint program = glCreateProgram();
|
||||
|
||||
/* Create an option geometry shader and find primitive type */
|
||||
|
@ -964,7 +1029,8 @@ ShaderBinding *generate_shaders(const ShaderState *state)
|
|||
generate_geometry_shader(state->polygon_front_mode,
|
||||
state->polygon_back_mode,
|
||||
state->primitive_mode,
|
||||
&gl_primitive_mode);
|
||||
&gl_primitive_mode,
|
||||
state->shade_model_flat);
|
||||
if (geometry_shader_code) {
|
||||
const char* geometry_shader_code_str =
|
||||
mstring_get_str(geometry_shader_code);
|
||||
|
@ -973,13 +1039,10 @@ ShaderBinding *generate_shaders(const ShaderState *state)
|
|||
"geometry shader");
|
||||
glAttachShader(program, geometry_shader);
|
||||
mstring_unref(geometry_shader_code);
|
||||
vtx_prefix = 'v';
|
||||
} else {
|
||||
vtx_prefix = 'g';
|
||||
}
|
||||
|
||||
/* create the vertex shader */
|
||||
MString *vertex_shader_code = generate_vertex_shader(state, vtx_prefix);
|
||||
MString *vertex_shader_code = generate_vertex_shader(state, geometry_shader_code);
|
||||
GLuint vertex_shader = create_gl_shader(GL_VERTEX_SHADER,
|
||||
mstring_get_str(vertex_shader_code),
|
||||
"vertex shader");
|
||||
|
|
|
@ -97,6 +97,8 @@ typedef struct ShaderState {
|
|||
bool point_params_enable;
|
||||
float point_size;
|
||||
float point_params[8];
|
||||
|
||||
bool shade_model_flat;
|
||||
} ShaderState;
|
||||
|
||||
typedef struct ShaderBinding {
|
||||
|
|
|
@ -23,19 +23,27 @@
|
|||
|
||||
#include "debug.h"
|
||||
|
||||
#define STRUCT_VERTEX_DATA "struct VertexData {\n" \
|
||||
" float inv_w;\n" \
|
||||
" vec4 D0;\n" \
|
||||
" vec4 D1;\n" \
|
||||
" vec4 B0;\n" \
|
||||
" vec4 B1;\n" \
|
||||
" float Fog;\n" \
|
||||
" vec4 T0;\n" \
|
||||
" vec4 T1;\n" \
|
||||
" vec4 T2;\n" \
|
||||
" vec4 T3;\n" \
|
||||
"};\n"
|
||||
#define DEF_VERTEX_DATA(qualifier, in_out, prefix, suffix) \
|
||||
"noperspective " in_out " float " prefix "vtx_inv_w" suffix ";\n" \
|
||||
qualifier " " in_out " vec4 " prefix "vtxD0" suffix ";\n" \
|
||||
qualifier " " in_out " vec4 " prefix "vtxD1" suffix ";\n" \
|
||||
qualifier " " in_out " vec4 " prefix "vtxB0" suffix ";\n" \
|
||||
qualifier " " in_out " vec4 " prefix "vtxB1" suffix ";\n" \
|
||||
"noperspective " in_out " float " prefix "vtxFog" suffix ";\n" \
|
||||
"noperspective " in_out " vec4 " prefix "vtxT0" suffix ";\n" \
|
||||
"noperspective " in_out " vec4 " prefix "vtxT1" suffix ";\n" \
|
||||
"noperspective " in_out " vec4 " prefix "vtxT2" suffix ";\n" \
|
||||
"noperspective " in_out " vec4 " prefix "vtxT3" suffix ";\n"
|
||||
|
||||
#define STRUCT_VERTEX_DATA_OUT_SMOOTH DEF_VERTEX_DATA("noperspective", "out", "", "")
|
||||
#define STRUCT_VERTEX_DATA_IN_SMOOTH DEF_VERTEX_DATA("noperspective", "in", "", "")
|
||||
#define STRUCT_V_VERTEX_DATA_OUT_SMOOTH DEF_VERTEX_DATA("noperspective", "out", "v_", "")
|
||||
#define STRUCT_V_VERTEX_DATA_IN_ARRAY_SMOOTH DEF_VERTEX_DATA("noperspective", "in", "v_", "[]")
|
||||
|
||||
#define STRUCT_VERTEX_DATA_OUT_FLAT DEF_VERTEX_DATA("flat", "out", "", "")
|
||||
#define STRUCT_VERTEX_DATA_IN_FLAT DEF_VERTEX_DATA("flat", "in", "", "")
|
||||
#define STRUCT_V_VERTEX_DATA_OUT_FLAT DEF_VERTEX_DATA("flat", "out", "v_", "")
|
||||
#define STRUCT_V_VERTEX_DATA_IN_ARRAY_FLAT DEF_VERTEX_DATA("flat", "in", "v_", "[]")
|
||||
|
||||
typedef struct {
|
||||
int ref;
|
||||
|
|
|
@ -821,9 +821,9 @@ void vsh_translate(uint16_t version,
|
|||
* around the perspective divide */
|
||||
mstring_append(body,
|
||||
" if (oPos.w == 0.0 || isinf(oPos.w)) {\n"
|
||||
" vtx.inv_w = 1.0;\n"
|
||||
" vtx_inv_w = 1.0;\n"
|
||||
" } else {\n"
|
||||
" vtx.inv_w = 1.0 / oPos.w;\n"
|
||||
" vtx_inv_w = 1.0 / oPos.w;\n"
|
||||
" }\n"
|
||||
);
|
||||
|
||||
|
|
Loading…
Reference in New Issue