Cheap HW transform solution for raven02's texture scaling fix.

This commit is contained in:
Henrik Rydgard 2013-07-10 01:22:15 +02:00
parent ad356edbd6
commit bf1e07661a
4 changed files with 36 additions and 19 deletions

View File

@ -595,6 +595,11 @@ void GLES_GPU::ExecuteOp(u32 op, u32 diff) {
break;
case GE_CMD_TEXMAPMODE:
if (diff) {
shaderManager_->DirtyUniform(DIRTY_UVSCALEOFFSET);
}
break;
case GE_CMD_TEXSHADELS:
break;

View File

@ -308,21 +308,35 @@ void LinkedShader::updateUniforms() {
// Texturing
if (u_uvscaleoffset != -1 && (dirtyUniforms & DIRTY_UVSCALEOFFSET)) {
float uvscaleoff[4] = {gstate_c.uScale, gstate_c.vScale, gstate_c.uOff, gstate_c.vOff};
float uvscaleoff[4];
if (gstate.isModeThrough()) {
// We never get here because we don't use HW transform with through mode.
// Although - why don't we?
uvscaleoff[0] /= gstate_c.curTextureWidth;
uvscaleoff[1] /= gstate_c.curTextureHeight;
uvscaleoff[2] /= gstate_c.curTextureWidth;
uvscaleoff[3] /= gstate_c.curTextureHeight;
uvscaleoff[0] = gstate_c.uScale / gstate_c.curTextureWidth;
uvscaleoff[1] = gstate_c.vScale / gstate_c.curTextureHeight;
uvscaleoff[2] = gstate_c.uOff / gstate_c.curTextureWidth;
uvscaleoff[3] = gstate_c.vOff / gstate_c.curTextureHeight;
glUniform4fv(u_uvscaleoffset, 1, uvscaleoff);
} else {
static const float rescale[4] = {2.0f, 2*127.5f/128.f, 2*32767.5f/32768.f, 2.0f};
float factor = rescale[(gstate.vertType & GE_VTYPE_TC_MASK) >> GE_VTYPE_TC_SHIFT];
uvscaleoff[0] *= factor;
uvscaleoff[1] *= factor;
int w = 1 << (gstate.texsize[0] & 0xf);
int h = 1 << ((gstate.texsize[0] >> 8) & 0xf);
float widthFactor = (float)w / (float)gstate_c.curTextureWidth;
float heightFactor = (float)h / (float)gstate_c.curTextureHeight;
if ((gstate.texmapmode & 3) == 0) {
static const float rescale[4] = {2.0f, 2*127.5f/128.f, 2*32767.5f/32768.f, 2.0f};
float factor = rescale[(gstate.vertType & GE_VTYPE_TC_MASK) >> GE_VTYPE_TC_SHIFT];
uvscaleoff[0] = gstate_c.uScale * factor * widthFactor;
uvscaleoff[1] = gstate_c.vScale * factor * heightFactor;
uvscaleoff[2] = gstate_c.uOff * widthFactor;
uvscaleoff[3] = gstate_c.vOff * heightFactor;
} else {
uvscaleoff[0] = widthFactor;
uvscaleoff[1] = heightFactor;
uvscaleoff[2] = 0.0f;
uvscaleoff[3] = 0.0f;
}
glUniform4fv(u_uvscaleoffset, 1, uvscaleoff);
}
glUniform4fv(u_uvscaleoffset, 1, uvscaleoff);
}
// Transform

View File

@ -720,6 +720,8 @@ void TransformDrawEngine::SoftwareTransformAndDraw(
// Illegal
break;
}
uv[0] = uv[0] * widthFactor;
uv[1] = uv[1] * heightFactor;
// Transform the coord by the view matrix.
Vec3ByMatrix43(v, out, gstate.viewMatrix);
@ -731,12 +733,7 @@ void TransformDrawEngine::SoftwareTransformAndDraw(
transformed[index].fog = fogCoef;
memcpy(&transformed[index].u, uv, 3 * sizeof(float));
if (gstate_c.flipTexture) {
if (throughmode) {
transformed[index].v = 1.0f - transformed[index].v;
} else {
transformed[index].u = transformed[index].u * (float) widthFactor ;
transformed[index].v = 1.0f - transformed[index].v * (float) heightFactor;
}
transformed[index].v = 1.0f - transformed[index].v;
}
for (int i = 0; i < 4; i++) {
transformed[index].color0[i] = c0[i] * 255.0f;

View File

@ -211,8 +211,9 @@ void GenerateVertexShader(int prim, char *buffer, bool useHWTransform) {
}
#endif
}
if (gstate.getUVGenMode() == 0)
if (doTexture) {
WRITE(p, "uniform vec4 u_uvscaleoffset;\n");
}
for (int i = 0; i < 4; i++) {
if (doLight[i] != LIGHT_OFF) {
// This is needed for shade mapping
@ -538,13 +539,13 @@ void GenerateVertexShader(int prim, char *buffer, bool useHWTransform) {
temp_tc = "vec4(0.0, 0.0, 1.0, 1.0)";
break;
}
WRITE(p, " v_texcoord = (u_texmtx * %s).xyz;\n", temp_tc);
WRITE(p, " v_texcoord = (u_texmtx * %s).xyz * vec3(u_uvscaleoffset.xy, 1.0);\n", temp_tc);
}
// Transform by texture matrix. XYZ as we are doing projection mapping.
break;
case 2: // Shade mapping - use dots from light sources.
WRITE(p, " v_texcoord = vec2(1.0 + dot(normalize(u_lightpos%i), worldnormal), 1.0 - dot(normalize(u_lightpos%i), worldnormal)) * 0.5;\n", gstate.getUVLS0(), gstate.getUVLS1());
WRITE(p, " v_texcoord = u_uvscaleoffset.xy * vec2(1.0 + dot(normalize(u_lightpos%i), worldnormal), 1.0 - dot(normalize(u_lightpos%i), worldnormal)) * 0.5;\n", gstate.getUVLS0(), gstate.getUVLS1());
break;
case 3: