Foggen + Fog WIP

This commit is contained in:
Jannik Vogel 2015-07-25 21:01:17 +02:00
parent 78a3163925
commit 177a4d78f8
5 changed files with 164 additions and 6 deletions

View File

@ -2838,6 +2838,21 @@ static void pgraph_bind_shaders(PGRAPHState *pg)
}
}
/* Fog */
state.fog_enable = pg->regs[NV_PGRAPH_CONTROL_3]
& NV_PGRAPH_CONTROL_3_FOGENABLE;
if (state.fog_enable) {
/*FIXME: Use CSV0_D? */
state.fog_mode = GET_MASK(pg->regs[NV_PGRAPH_CONTROL_3],
NV_PGRAPH_CONTROL_3_FOG_MODE);
state.foggen = GET_MASK(pg->regs[NV_PGRAPH_CSV0_D],
NV_PGRAPH_CSV0_D_FOGGENMODE);
} else {
/* FIXME: Do we still pass the fogmode? */
state.fog_mode = 0;
state.foggen = 0;
}
/* Texture matrices */
for (i = 0; i < 4; i++) {
state.texture_matrix_enable[i] = pg->texture_matrix_enable[i];
@ -2962,6 +2977,39 @@ static void pgraph_bind_shaders(PGRAPHState *pg)
}
/* Fog */
{
GLint loc;
uint32_t fog_color = pg->regs[NV_PGRAPH_FOGCOLOR];
loc = glGetUniformLocation(pg->shader_binding->gl_program, "fogColor");
if (loc != -1) {
glUniform4f(loc,
GET_MASK(fog_color, NV_PGRAPH_FOGCOLOR_RED) / 255.0,
GET_MASK(fog_color, NV_PGRAPH_FOGCOLOR_GREEN) / 255.0,
GET_MASK(fog_color, NV_PGRAPH_FOGCOLOR_BLUE) / 255.0,
GET_MASK(fog_color, NV_PGRAPH_FOGCOLOR_ALPHA) / 255.0);
}
/* FIXME: PGRAPH regs have a 16 byte stride in emulation! can't just
* upload this as an array =(
*/
loc = glGetUniformLocation(pg->shader_binding->gl_program,
"fogParam[0]");
if (loc != -1) {
glUniform1f(loc, *(float*)&pg->regs[NV_PGRAPH_FOGPARAM0]);
}
loc = glGetUniformLocation(pg->shader_binding->gl_program,
"fogParam[1]");
if (loc != -1) {
glUniform1f(loc, *(float*)&pg->regs[NV_PGRAPH_FOGPARAM1]);
}
loc = glGetUniformLocation(pg->shader_binding->gl_program, "fogPlane");
if (loc != -1) {
glUniform4fv(loc, 1, pg->fog_plane);
}
}
/* For each vertex weight */
for (i = 0; i < 4; i++) {
char name[32];
@ -4358,7 +4406,11 @@ static void pgraph_method(NV2AState *d,
case NV097_SET_FOG_PARAMS ...
NV097_SET_FOG_PARAMS + 8:
slot = (class_method - NV097_SET_FOG_PARAMS) / 4;
pg->regs[NV_PGRAPH_FOGPARAM0 + slot*4] = parameter;
if (slot < 2) {
pg->regs[NV_PGRAPH_FOGPARAM0 + slot*4] = parameter;
} else {
/* FIXME: No idea where slot = 2 is */
}
break;
case NV097_SET_TEXGEN_VIEW_MODEL:
SET_MASK(pg->regs[NV_PGRAPH_CSV0_D], NV_PGRAPH_CSV0_D_TEXGEN_REF,
@ -6783,7 +6835,7 @@ static void pgraph_method_log(unsigned int subchannel,
static unsigned int last = 0;
static unsigned int count = 0;
if (last == 0x1800 && method != last) {
NV2A_DPRINTF("pgraph method (%d) 0x%x * %d",
NV2A_GL_DPRINTF(true, "pgraph method (%d) 0x%x * %d",
subchannel, last, count);
}
if (method != 0x1800) {

View File

@ -280,9 +280,8 @@ static QString* get_var(struct PixelShader *ps, int reg, bool is_dest)
return qstring_from_str("c_0_1");
}
break;
case PS_REGISTER_FOG: // TODO
//return qstring_from_str("fog");
return qstring_from_str("vec4(1.0)");
case PS_REGISTER_FOG:
return qstring_from_str("clamp(pFog, 0.0, 1.0)");
case PS_REGISTER_V0:
return qstring_from_str("v0");
case PS_REGISTER_V1:

View File

@ -115,6 +115,9 @@ static QString* generate_fixed_function(const ShaderState state,
qstring_append(s,
"\n"
/* FIXME: Add these uniforms using code when they are used */
"uniform vec4 fogColor;\n"
"uniform vec4 fogPlane;\n"
"uniform float fogParam[2];\n"
"uniform mat4 texMat0;\n"
"uniform mat4 texMat1;\n"
"uniform mat4 texMat2;\n"
@ -255,6 +258,85 @@ static QString* generate_fixed_function(const ShaderState state,
}
}
/* Fog */
if (state.fog_enable) {
/* From: https://www.opengl.org/registry/specs/NV/fog_distance.txt */
switch(state.foggen) {
case FOGGEN_SPEC_ALPHA:
assert(false); /* FIXME: Do this before or after calculations in VSH? */
if (state.fixed_function) {
/* FIXME: Do we have to clamp here? */
qstring_append(s, "float fogDistance = clamp(specular.a, 0.0, 1.0);\n");
} else if (state.vertex_program) {
qstring_append(s, "float fogDistance = oD1.a;\n");
} else {
assert(false);
}
break;
case FOGGEN_RADIAL:
qstring_append(s, "float fogDistance = length(tPosition.xyz)");
break;
case FOGGEN_PLANAR:
case FOGGEN_ABS_PLANAR:
qstring_append(s, "float fogDistance = dot(fogPlane.xyz,tPosition.xyz)+fogPlane.w;\n");
if (state.foggen == FOGGEN_ABS_PLANAR) {
qstring_append(s, "fogDistance = abs(fogDistance);\n");
}
break;
case FOGGEN_FOG_X:
if (state.fixed_function) {
qstring_append(s, "float fogDistance = fogCoord;\n");
} else if (state.vertex_program) {
qstring_append(s, "float fogDistance = oFog.x;\n");
} else {
assert(false);
}
break;
default:
assert(false);
break;
}
switch (state.fog_mode) {
case FOG_MODE_LINEAR:
case FOG_MODE_LINEAR_ABS:
qstring_append(s, "float fogFactor = fogDistance * fogParam[1] + fogParam[0];\n");
qstring_append(s, "fogFactor -= 1.0;\n"); /* FIXME: WHHYYY?!! */
break;
case FOG_MODE_EXP:
case FOG_MODE_EXP_ABS:
assert(false); /* FIXME: fogParam[0] and fogParam[0] ?? */
qstring_append(s, "float fogFactor = exp(fogDistance);\n");
break;
case FOG_MODE_EXP2:
case FOG_MODE_EXP2_ABS:
assert(false); /* FIXME: fogParam[0] and fogParam[0] ?? */
qstring_append(s, "float fogFactor = exp(fogDistance * fogDistance);\n");
break;
default:
assert(false);
break;
}
/* Calculate absolute for the modes which need it */
switch (state.fog_mode) {
case FOG_MODE_LINEAR_ABS:
case FOG_MODE_EXP_ABS:
case FOG_MODE_EXP2_ABS:
qstring_append(s, "fogFactor = abs(fogFactor);\n");
break;
default:
break;
}
/* FIXME: What about fog alpha?! */
qstring_append(s, "vec4 tFog = vec4(fogColor.rgb, fogFactor);\n");
} else {
/* FIXME: Is the fog still calculated / passed somehow?!
* Maybe vec4(fogColor, fogCoord) ?
*/
qstring_append(s, "vec4 tFog = vec4(0.0);\n");
}
/* If skinning is off the composite matrix already includes the MV matrix */
if (state.skinning == SKINNING_OFF) {
qstring_append(s, "tPosition = position;\n");
@ -273,7 +355,7 @@ static QString* generate_fixed_function(const ShaderState state,
qstring_append(s, "vtx.D1 = specular * vtx.inv_w;\n");
qstring_append(s, "vtx.B0 = backDiffuse * vtx.inv_w;\n");
qstring_append(s, "vtx.B1 = backSpecular * vtx.inv_w;\n");
qstring_append(s, "vtx.Fog = vec4(0.0,0.0,0.0,1.0) * vtx.inv_w;\n");
qstring_append(s, "vtx.Fog = tFog * vtx.inv_w;\n");
qstring_append(s, "vtx.T0 = tTexture0 * vtx.inv_w;\n");
qstring_append(s, "vtx.T1 = tTexture1 * vtx.inv_w;\n");
qstring_append(s, "vtx.T2 = tTexture2 * vtx.inv_w;\n");

View File

@ -65,6 +65,10 @@ typedef struct ShaderState {
bool texture_matrix_enable[4];
enum VshTexgen texgen[4][4];
bool fog_enable;
enum VshFoggen foggen;
enum VshFogMode fog_mode;
enum VshSkinning skinning;
bool normalization;

View File

@ -33,6 +33,27 @@ enum VshTexgen {
TEXGEN_REFLECTION_MAP,
};
enum VshFogMode {
FOG_MODE_LINEAR,
FOG_MODE_EXP,
FOG_MODE_ERROR2, /* Doesn't exist */
FOG_MODE_EXP2,
FOG_MODE_LINEAR_ABS,
FOG_MODE_EXP_ABS,
FOG_MODE_ERROR6, /* Doesn't exist */
FOG_MODE_EXP2_ABS
};
enum VshFoggen {
FOGGEN_SPEC_ALPHA,
FOGGEN_RADIAL,
FOGGEN_PLANAR,
FOGGEN_ABS_PLANAR,
FOGGEN_ERROR4,
FOGGEN_ERROR5,
FOGGEN_FOG_X
};
enum VshSkinning {
SKINNING_OFF,
SKINNING_1WEIGHTS,