Medium Quality mode for spline patch

This commit is contained in:
raven02 2014-04-25 20:44:02 +08:00
parent b0e97a0d4c
commit aa08944528
4 changed files with 323 additions and 285 deletions

View file

@ -393,7 +393,7 @@ static ConfigSetting graphicsSettings[] = {
// Not really a graphics setting...
ReportedConfigSetting("TimerHack", &g_Config.bTimerHack, &DefaultTimerHack),
ReportedConfigSetting("AlphaMaskHack", &g_Config.bAlphaMaskHack, false),
ReportedConfigSetting("LowQualitySplineBezier", &g_Config.bLowQualitySplineBezier, false),
ReportedConfigSetting("SplineBezierQuality", &g_Config.iSplineBezierQuality, 2),
ReportedConfigSetting("PostShader", &g_Config.sPostShaderName, "Off"),
ConfigSetting(false),

View file

@ -139,7 +139,7 @@ public:
bool bAlwaysDepthWrite;
bool bTimerHack;
bool bAlphaMaskHack;
bool bLowQualitySplineBezier;
int iSplineBezierQuality; // 0 = low , 1 = Intermediate , 2 = High
std::string sPostShaderName; // Off for off.
// Sound

View file

@ -25,6 +25,12 @@
// Here's how to evaluate them fast:
// http://and-what-happened.blogspot.se/2012/07/evaluating-b-splines-aka-basis-splines.html
enum quality {
LOW_QUALITY = 0,
MEDIUM_QUALITY = 1,
HIGH_QUALITY = 2,
};
// This normalizes a set of vertices in any format to SimpleVertex format, by processing away morphing AND skinning.
// The rest of the transform pipeline like lighting will go as normal, either hardware or software.
// The implementation is initially a bit inefficient but shouldn't be a big deal.
@ -341,11 +347,8 @@ void spline_knot(int n, int type, float *knot) {
knot[n + 4] = n - 2;
}
}
void TesselateSplinePatch(u8 *&dest, int &count, const SplinePatch &spatch, u32 origVertType) {
void _SplinePatchLowQuality(u8 *&dest, int &count, const SplinePatch &spatch, u32 origVertType) {
const float third = 1.0f / 3.0f;
if (g_Config.bLowQualitySplineBezier) {
// Fast and easy way - just draw the control points, generate some very basic normal vector substitutes.
// Very inaccurate but okay for Loco Roco. Maybe should keep it as an option because it's fast.
@ -394,7 +397,10 @@ void TesselateSplinePatch(u8 *&dest, int &count, const SplinePatch &spatch, u32
count += 6;
}
}
} else {
}
void _SplinePatchFullQuality(u8 *&dest, int &count, const SplinePatch &spatch, u32 origVertType, int patch_cap) {
// Full correct tessellation of spline patches.
// Does not yet generate normals and is atrociously slow (see spline_s...)
@ -416,8 +422,8 @@ void TesselateSplinePatch(u8 *&dest, int &count, const SplinePatch &spatch, u32
if (patch_div_t <= 0) patch_div_t = 1;
// TODO: Remove this cap when spline_s has been optimized.
if (patch_div_s > 64) patch_div_s = 64;
if (patch_div_t > 64) patch_div_t = 64;
if (patch_div_s > patch_cap) patch_div_s = patch_cap;
if (patch_div_t > patch_cap) patch_div_t = patch_cap;
// First compute all the vertices and put them in an array
SimpleVertex *vertices = new SimpleVertex[(patch_div_s + 1) * (patch_div_t + 1)];
@ -435,19 +441,22 @@ void TesselateSplinePatch(u8 *&dest, int &count, const SplinePatch &spatch, u32
vert->pos.SetZero();
if (origVertType & GE_VTYPE_NRM_MASK) {
vert->nrm.SetZero();
} else {
}
else {
vert->nrm.SetZero();
vert->nrm.z = 1.0f;
}
if (origVertType & GE_VTYPE_COL_MASK) {
memset(vert->color, 0, 4);
} else {
}
else {
memcpy(vert->color, spatch.points[0]->color, 4);
}
if (origVertType & GE_VTYPE_TC_MASK) {
vert->uv[0] = 0.0f;
vert->uv[1] = 0.0f;
} else {
}
else {
vert->uv[0] = tu_width * ((float)tile_u / (float)patch_div_s);
vert->uv[1] = tv_height * ((float)tile_v / (float)patch_div_t);
}
@ -533,12 +542,25 @@ void TesselateSplinePatch(u8 *&dest, int &count, const SplinePatch &spatch, u32
delete[] vertices;
}
void TesselateSplinePatch(u8 *&dest, int &count, const SplinePatch &spatch, u32 origVertType) {
switch (g_Config.iSplineBezierQuality) {
case LOW_QUALITY:
_SplinePatchLowQuality(dest, count, spatch, origVertType);
break;
case MEDIUM_QUALITY:
_SplinePatchFullQuality(dest, count, spatch, origVertType, 8);
break;
case HIGH_QUALITY:
_SplinePatchFullQuality(dest, count, spatch, origVertType, 64);
break;
}
void TesselateBezierPatch(u8 *&dest, int &count, int tess_u, int tess_v, const BezierPatch &patch, u32 origVertType) {
const float third = 1.0f / 3.0f;
if (g_Config.bLowQualitySplineBezier) {
}
void _BezierPatchLowQuality(u8 *&dest, int &count, int tess_u, int tess_v, const BezierPatch &patch, u32 origVertType) {
const float third = 1.0f / 3.0f;
// Fast and easy way - just draw the control points, generate some very basic normal vector subsitutes.
// Very inaccurate though but okay for Loco Roco. Maybe should keep it as an option.
@ -585,7 +607,10 @@ void TesselateBezierPatch(u8 *&dest, int &count, int tess_u, int tess_v, const B
count += 6;
}
}
} else {
}
void _BezierPatchHighQuality(u8 *&dest, int &count, int tess_u, int tess_v, const BezierPatch &patch, u32 origVertType) {
const float third = 1.0f / 3.0f;
// Full correct tesselation of bezier patches.
// Note: Does not handle splines correctly.
@ -635,7 +660,8 @@ void TesselateBezierPatch(u8 *&dest, int &count, int tess_u, int tess_v, const B
vert.nrm = Cross(derivU, derivV).Normalized();
if (gstate.patchfacing & 1)
vert.nrm *= -1.0f;
} else {
}
else {
vert.nrm.SetZero();
}
@ -677,6 +703,17 @@ void TesselateBezierPatch(u8 *&dest, int &count, int tess_u, int tess_v, const B
delete[] vertices;
}
void TesselateBezierPatch(u8 *&dest, int &count, int tess_u, int tess_v, const BezierPatch &patch, u32 origVertType) {
switch (g_Config.iSplineBezierQuality) {
case LOW_QUALITY:
_BezierPatchLowQuality(dest, count, tess_u, tess_v, patch, origVertType);
break;
case MEDIUM_QUALITY:
case HIGH_QUALITY:
_BezierPatchHighQuality(dest, count, tess_u, tess_v, patch, origVertType);
break;
}
}
void TransformDrawEngine::SubmitSpline(void* control_points, void* indices, int count_u, int count_v, int type_u, int type_v, GEPatchPrimType prim_type, u32 vertType) {

View file

@ -165,7 +165,8 @@ void GameSettingsScreen::CreateViews() {
// vtxJit->SetEnabled(false);
}
graphicsSettings->Add(new CheckBox(&g_Config.bLowQualitySplineBezier, gs->T("LowCurves", "Low quality spline/bezier curves")));
static const char *quality[] = { "Low", "Medium", "High"};
graphicsSettings->Add(new PopupMultiChoice(&g_Config.iSplineBezierQuality, gs->T("LowCurves", "Spline/Bezier curves quality"), quality, 0, ARRAY_SIZE(quality), gs, screenManager()));
// In case we're going to add few other antialiasing option like MSAA in the future.
// graphicsSettings->Add(new CheckBox(&g_Config.bFXAA, gs->T("FXAA")));