fix fixed-function, and cleanups

This commit is contained in:
espes 2015-07-12 01:26:48 +10:00
parent 0a9ad10583
commit 537b05b838
3 changed files with 55 additions and 48 deletions

View File

@ -1143,7 +1143,7 @@ typedef struct ShaderState {
int program_length;
/* primitive format for geomotry shader */
unsigned int primitive_mode;
unsigned int primitive_mode;
} ShaderState;
typedef struct ShaderBinding {
@ -2122,25 +2122,17 @@ static void generate_geometry_shader_pass_vertex(QString* s, const char* v)
static QString* generate_geometry_shader(unsigned int primitive_mode)
{
/* generate a geometry shader to support deprecated primitive types */
QString* s = qstring_new();
qstring_append(s, "#version 330\n");
qstring_append(s, "\n");
switch (primitive_mode) {
// case NV097_SET_BEGIN_END_OP_POINTS:
// qstring_append(s, "layout(points) in;\n");
// qstring_append(s, "layout(points, max_vertices = 1) out;\n");
// break;
// case NV097_SET_BEGIN_END_OP_LINES:
// case NV097_SET_BEGIN_END_OP_LINE_STRIP:
// qstring_append(s, "layout(lines) in;")
// qstring_append(s, "layout(line_strip, max_vertices = 6) out;\n");
case NV097_SET_BEGIN_END_OP_QUADS:
qstring_append(s, "layout(lines_adjacency) in;\n");
qstring_append(s, "layout(triangle_strip, max_vertices = 6) out;\n");
break;
default:
qstring_append(s, "layout(triangles) in;\n");
qstring_append(s, "layout(triangle_strip, max_vertices = 3) out;\n");
assert(false);
break;
}
qstring_append(s, "\n");
@ -2179,10 +2171,7 @@ static QString* generate_geometry_shader(unsigned int primitive_mode)
qstring_append(s, "EndPrimitive();\n");
break;
default:
generate_geometry_shader_pass_vertex(s, "0");
generate_geometry_shader_pass_vertex(s, "1");
generate_geometry_shader_pass_vertex(s, "2");
qstring_append(s, "EndPrimitive();\n");
assert(false);
break;
}
qstring_append(s, "}\n");
@ -2206,7 +2195,7 @@ static ShaderBinding* generate_shaders(const ShaderState state)
if (state.fixed_function) {
/* generate vertex shader mimicking fixed function */
vertex_shader_code = qstring_new();
qstring_append(vertex_shader_code,
qstring_append(vertex_shader_code,
"#version 330\n"
"\n"
"in vec4 position;\n"
@ -2214,10 +2203,12 @@ static ShaderBinding* generate_shaders(const ShaderState state)
"in vec4 diffuse;\n"
"in vec4 specular;\n"
"in float fogCoord;\n"
"in vec4 multiTexCoord0;\n"
"in vec4 multiTexCoord1;\n"
"in vec4 multiTexCoord2;\n"
"in vec4 multiTexCoord3;\n"
"in vec4 backDiffuse;\n"
"in vec4 backSpecular;\n"
"in vec4 texture0;\n"
"in vec4 texture1;\n"
"in vec4 texture2;\n"
"in vec4 texture3;\n"
"\n");
qstring_append_fmt(vertex_shader_code,
@ -2256,15 +2247,21 @@ static ShaderBinding* generate_shaders(const ShaderState state)
qstring_append_fmt(vertex_shader_code,
"%cPos_w = 1.0/gl_Position.w;\n", v_prefix);
qstring_append_fmt(vertex_shader_code,
"%cD0 = diffuse;\n", v_prefix);
"%cD0 = diffuse * %cPos_w;\n", v_prefix, v_prefix);
qstring_append_fmt(vertex_shader_code,
"%cT0 = multiTexCoord0;\n", v_prefix);
"%cD1 = specular * %cPos_w;\n", v_prefix, v_prefix);
qstring_append_fmt(vertex_shader_code,
"%cT1 = multiTexCoord1;\n", v_prefix);
"%cB0 = backDiffuse * %cPos_w;\n", v_prefix, v_prefix);
qstring_append_fmt(vertex_shader_code,
"%cT2 = multiTexCoord2;\n", v_prefix);
"%cB1 = backSpecular * %cPos_w;\n", v_prefix, v_prefix);
qstring_append_fmt(vertex_shader_code,
"%cT3 = multiTexCoord3;\n", v_prefix);
"%cT0 = texture0 * %cPos_w;\n", v_prefix, v_prefix);
qstring_append_fmt(vertex_shader_code,
"%cT1 = texture1 * %cPos_w;\n", v_prefix, v_prefix);
qstring_append_fmt(vertex_shader_code,
"%cT2 = texture2 * %cPos_w;\n", v_prefix, v_prefix);
qstring_append_fmt(vertex_shader_code,
"%cT3 = texture3 * %cPos_w;\n", v_prefix, v_prefix);
qstring_append(vertex_shader_code, "}\n");
@ -2273,7 +2270,6 @@ static ShaderBinding* generate_shaders(const ShaderState state)
(uint32_t*)state.program_data,
state.program_length,
v_prefix);
} else {
assert(false);
}
@ -2309,10 +2305,12 @@ static ShaderBinding* generate_shaders(const ShaderState state)
glBindAttribLocation(program, NV2A_VERTEX_ATTR_DIFFUSE, "diffuse");
glBindAttribLocation(program, NV2A_VERTEX_ATTR_SPECULAR, "specular");
glBindAttribLocation(program, NV2A_VERTEX_ATTR_FOG, "fog");
glBindAttribLocation(program, NV2A_VERTEX_ATTR_TEXTURE0, "multiTexCoord0");
glBindAttribLocation(program, NV2A_VERTEX_ATTR_TEXTURE1, "multiTexCoord1");
glBindAttribLocation(program, NV2A_VERTEX_ATTR_TEXTURE2, "multiTexCoord2");
glBindAttribLocation(program, NV2A_VERTEX_ATTR_TEXTURE3, "multiTexCoord3");
glBindAttribLocation(program, NV2A_VERTEX_ATTR_BACK_DIFFUSE, "backDiffuse");
glBindAttribLocation(program, NV2A_VERTEX_ATTR_BACK_SPECULAR, "backSpecular");
glBindAttribLocation(program, NV2A_VERTEX_ATTR_TEXTURE0, "texture0");
glBindAttribLocation(program, NV2A_VERTEX_ATTR_TEXTURE1, "texture1");
glBindAttribLocation(program, NV2A_VERTEX_ATTR_TEXTURE2, "texture2");
glBindAttribLocation(program, NV2A_VERTEX_ATTR_TEXTURE3, "texture3");
} else if (state.vertex_program) {
/* Bind attributes for transform program*/
char tmp[8];
@ -2320,6 +2318,8 @@ static ShaderBinding* generate_shaders(const ShaderState state)
snprintf(tmp, sizeof(tmp), "v%d", i);
glBindAttribLocation(program, i, tmp);
}
} else {
assert(false);
}

View File

@ -544,6 +544,7 @@ static QString* psh_convert(struct PixelShader *ps)
qstring_append(preflight, "out vec4 fragColor;\n");
qstring_append(preflight, "\n");
/* calculate perspective-correct inputs */
QString *vars = qstring_new();
qstring_append(vars, "float pFactor = gPos_w;\n");
qstring_append(vars, "vec4 pD0 = gD0 / pFactor;\n");

View File

@ -782,6 +782,9 @@ QString* vsh_translate(uint16_t version,
}
assert(has_final);
/* pre-divide and output the generated W so we can do persepctive correct
* interpolation manually. OpenGL can't, since we give it a W of 1 to work
* around the perspective divide */
qstring_append_fmt(body,
"if (oPos.w == 0.0 || isinf(oPos.w)) {\n"
" %cPos_w = 1.0;"
@ -801,27 +804,30 @@ QString* vsh_translate(uint16_t version,
qstring_append(body,
/* the shaders leave the result in screen space, while
* opengl expects it in clip coordinates.
* Use the magic viewport constants for now,
* but they're not necessarily present...
*/
* opengl expects it in clip space.
*/
" /* Un-screenspace transform */\n"
"oPos.x = (oPos.x - viewportOffset.x) / viewportScale.x;\n"
"oPos.y = (oPos.y - viewportOffset.y) / viewportScale.y;\n"
"if (clipRange.y != clipRange.x) {\n"
" oPos.z = (oPos.z - 0.5 * (clipRange.x + clipRange.y)) / (0.5 * (clipRange.y - clipRange.x));\n"
"}\n"
"if (oPos.w <= 0.0) {\n"
/* undo the perspective divide in the case where the point would be
* clipped so opengl can clip it correctly */
" oPos.xyz *= oPos.w;\n"
"} else {\n"
" oPos.w = 1.0;\n"
/* Use magic viewport constants to translate xyz back into clip space
* TODO: Are they always present?
*/
"oPos.x = (oPos.x - viewportOffset.x) / viewportScale.x;\n"
"oPos.y = (oPos.y - viewportOffset.y) / viewportScale.y;\n"
"if (clipRange.y != clipRange.x) {\n"
" oPos.z = (oPos.z - 0.5 * (clipRange.x + clipRange.y)) / (0.5 * (clipRange.y - clipRange.x));\n"
"}\n"
" /* Set outputs */\n"
/* Correct for the perspective divide */
"if (oPos.w <= 0.0) {\n"
/* undo the perspective divide in the case where the point would be
* clipped so opengl can clip it correctly */
" oPos.xyz *= oPos.w;\n"
"} else {\n"
/* we don't want the OpenGL perspective divide to happen, but we
* can't multiply by W because it could be meaningless here */
" oPos.w = 1.0;\n"
"}\n"
/* Set outputs */
" gl_Position = oPos;\n"
" gl_PointSize = oPts.x;\n"
"\n"