mirror of
https://github.com/libretro/ppsspp.git
synced 2024-11-23 16:19:44 +00:00
HW transform: Avoid 4x3 matrices for GLES 2.0 compat. Add option to turn hw transform on.
This commit is contained in:
parent
4d4370232c
commit
4bf2e52623
@ -57,6 +57,7 @@ void CConfig::Load(const char *iniFileName)
|
||||
graphics->Get("DisplayFramebuffer", &bDisplayFramebuffer, false);
|
||||
graphics->Get("WindowZoom", &iWindowZoom, 1);
|
||||
graphics->Get("BufferedRendering", &bBufferedRendering, true);
|
||||
graphics->Get("HardwareTransform", &bHardwareTransform, false);
|
||||
|
||||
IniFile::Section *sound = iniFile.GetOrCreateSection("Sound");
|
||||
sound->Get("Enable", &bEnableSound, true);
|
||||
@ -93,6 +94,7 @@ void CConfig::Save()
|
||||
graphics->Set("DisplayFramebuffer", bDisplayFramebuffer);
|
||||
graphics->Set("WindowZoom", iWindowZoom);
|
||||
graphics->Set("BufferedRendering", bBufferedRendering);
|
||||
graphics->Set("HardwareTransform", bHardwareTransform);
|
||||
|
||||
IniFile::Section *sound = iniFile.GetOrCreateSection("Sound");
|
||||
sound->Set("Enable", bEnableSound);
|
||||
|
@ -41,7 +41,10 @@ public:
|
||||
bool bSpeedLimit;
|
||||
bool bConfirmOnQuit;
|
||||
bool bIgnoreBadMemAccess;
|
||||
|
||||
// GFX
|
||||
bool bDisplayFramebuffer;
|
||||
bool bHardwareTransform;
|
||||
bool bBufferedRendering;
|
||||
bool bDrawWireframe;
|
||||
|
||||
|
@ -153,6 +153,27 @@ static void SetColorUniform3ExtraFloat(int uniform, u32 color, float extra)
|
||||
glUniform4fv(uniform, 1, col);
|
||||
}
|
||||
|
||||
static void SetMatrix4x3(int uniform, const float *m4x3) {
|
||||
float m4x4[16];
|
||||
m4x4[0] = m4x3[0];
|
||||
m4x4[1] = m4x3[1];
|
||||
m4x4[2] = m4x3[2];
|
||||
m4x4[3] = 0.0f;
|
||||
m4x4[4] = m4x3[3];
|
||||
m4x4[5] = m4x3[4];
|
||||
m4x4[6] = m4x3[5];
|
||||
m4x4[7] = 0.0f;
|
||||
m4x4[8] = m4x3[6];
|
||||
m4x4[9] = m4x3[7];
|
||||
m4x4[10] = m4x3[8];
|
||||
m4x4[11] = 0.0f;
|
||||
m4x4[12] = m4x3[9];
|
||||
m4x4[13] = m4x3[10];
|
||||
m4x4[14] = m4x3[11];
|
||||
m4x4[15] = 1.0f;
|
||||
glUniformMatrix4fv(uniform, 1, GL_FALSE, m4x4);
|
||||
}
|
||||
|
||||
void LinkedShader::use() {
|
||||
glUseProgram(program);
|
||||
glUniform1i(u_tex, 0);
|
||||
@ -203,17 +224,17 @@ void LinkedShader::use() {
|
||||
|
||||
// Transform
|
||||
if (u_world != -1 && (dirtyUniforms & DIRTY_WORLDMATRIX)) {
|
||||
glUniformMatrix4x3fv(u_world, 1, GL_FALSE, gstate.worldMatrix);
|
||||
SetMatrix4x3(u_world, gstate.worldMatrix);
|
||||
}
|
||||
if (u_view != -1 && (dirtyUniforms & DIRTY_VIEWMATRIX)) {
|
||||
glUniformMatrix4x3fv(u_view, 1, GL_FALSE, gstate.viewMatrix);
|
||||
SetMatrix4x3(u_view, gstate.viewMatrix);
|
||||
}
|
||||
if (u_texmtx != -1 && (dirtyUniforms & DIRTY_TEXMATRIX)) {
|
||||
glUniformMatrix4x3fv(u_texmtx, 1, GL_FALSE, gstate.tgenMatrix);
|
||||
SetMatrix4x3(u_texmtx, gstate.tgenMatrix);
|
||||
}
|
||||
for (int i = 0; i < 8; i++) {
|
||||
if (u_bone[i] != -1 && (dirtyUniforms & (DIRTY_BONEMATRIX0 << i))) {
|
||||
glUniformMatrix4x3fv(u_bone[i], 1, GL_FALSE, gstate.boneMatrix + 12 * i);
|
||||
SetMatrix4x3(u_bone[i], gstate.boneMatrix + 12 * i);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -26,6 +26,7 @@
|
||||
|
||||
#include "../ge_constants.h"
|
||||
#include "../GPUState.h"
|
||||
#include "../../Core/Config.h"
|
||||
|
||||
#include "VertexShaderGenerator.h"
|
||||
|
||||
@ -44,8 +45,9 @@ static char buffer[16384];
|
||||
|
||||
bool CanUseHardwareTransform(int prim)
|
||||
{
|
||||
return !gstate.isModeThrough() && false; // prim != GE_PRIM_RECTANGLES;
|
||||
//return !gstate.isModeThrough() && prim != GE_PRIM_RECTANGLES;
|
||||
if (!g_Config.bHardwareTransform)
|
||||
return false;
|
||||
return !gstate.isModeThrough() && prim != GE_PRIM_RECTANGLES;
|
||||
}
|
||||
|
||||
// prim so we can special case for RECTANGLES :(
|
||||
@ -192,16 +194,16 @@ char *GenerateVertexShader(int prim)
|
||||
|
||||
if (hwXForm) {
|
||||
// When transforming by hardware, we need a great deal more uniforms...
|
||||
WRITE(p, "uniform mat4x3 u_world;\n");
|
||||
WRITE(p, "uniform mat4x3 u_view;\n");
|
||||
WRITE(p, "uniform mat4 u_world;\n");
|
||||
WRITE(p, "uniform mat4 u_view;\n");
|
||||
if (gstate.getUVGenMode() == 0)
|
||||
WRITE(p, "uniform vec4 u_uvscaleoffset;\n");
|
||||
else if (gstate.getUVGenMode() == 1)
|
||||
WRITE(p, "uniform mat4x3 u_texmtx;\n");
|
||||
WRITE(p, "uniform mat4 u_texmtx;\n");
|
||||
if ((gstate.vertType & GE_VTYPE_WEIGHT_MASK) != GE_VTYPE_WEIGHT_NONE) {
|
||||
int numBones = 1 + ((gstate.vertType & GE_VTYPE_WEIGHTCOUNT_MASK) >> GE_VTYPE_WEIGHTCOUNT_SHIFT);
|
||||
for (int i = 0; i < numBones; i++) {
|
||||
WRITE(p, "uniform mat4x3 u_bone%i;\n", i);
|
||||
WRITE(p, "uniform mat4 u_bone%i;\n", i);
|
||||
}
|
||||
}
|
||||
if (gstate.lightingEnable & 1) {
|
||||
@ -258,9 +260,9 @@ char *GenerateVertexShader(int prim)
|
||||
// Step 1: World Transform / Skinning
|
||||
if ((gstate.vertType & GE_VTYPE_WEIGHT_MASK) == GE_VTYPE_WEIGHT_NONE) {
|
||||
// No skinning, just standard T&L.
|
||||
WRITE(p, " vec3 worldpos = u_world * vec4(a_position, 1.0);\n");
|
||||
WRITE(p, " vec3 worldpos = (u_world * vec4(a_position, 1.0)).xyz;\n");
|
||||
if (hasNormal)
|
||||
WRITE(p, " vec3 worldnormal = normalize(u_world * vec4(a_normal, 0.0));\n");
|
||||
WRITE(p, " vec3 worldnormal = (u_world * vec4(a_normal, 0.0)).xyz;\n");
|
||||
} else {
|
||||
WRITE(p, " vec3 worldpos = vec3(0.0, 0.0, 0.0);\n");
|
||||
if (hasNormal)
|
||||
@ -271,15 +273,17 @@ char *GenerateVertexShader(int prim)
|
||||
// workaround for "cant do .x of scalar" issue
|
||||
if (numWeights == 1 && i == 0) weightAttr = "a_weight0123";
|
||||
if (numWeights == 5 && i == 4) weightAttr = "a_weight4567";
|
||||
WRITE(p, " worldpos += %s * (u_bone%i * vec4(a_position, 1.0));\n", weightAttr, i);
|
||||
WRITE(p, " worldpos += %s * (u_bone%i * vec4(a_position, 1.0)).xyz;\n", weightAttr, i);
|
||||
if (hasNormal)
|
||||
WRITE(p, " worldnormal += %s * (u_bone%i * vec4(a_normal, 0.0));\n", weightAttr, i);
|
||||
WRITE(p, " worldnormal += %s * (u_bone%i * vec4(a_normal, 0.0)).xyz;\n", weightAttr, i);
|
||||
}
|
||||
// Finally, multiply by world matrix (yes, we have to).
|
||||
WRITE(p, " worldpos = u_world * vec4(worldpos, 1.0);\n");
|
||||
WRITE(p, " worldpos = (u_world * vec4(worldpos, 1.0)).xyz;\n");
|
||||
if (hasNormal)
|
||||
WRITE(p, " worldnormal = u_world * vec4(worldnormal, 0.0);\n");
|
||||
WRITE(p, " worldnormal = (u_world * vec4(worldnormal, 0.0)).xyz;\n");
|
||||
}
|
||||
if (hasNormal)
|
||||
WRITE(p, " worldnormal = normalize(worldnormal);\n");
|
||||
|
||||
// Step 2: Color/Lighting
|
||||
if (hasColor) {
|
||||
@ -395,7 +399,7 @@ char *GenerateVertexShader(int prim)
|
||||
}
|
||||
}
|
||||
// Step 4: Final view and projection transforms.
|
||||
WRITE(p, " gl_Position = u_proj * vec4(u_view * vec4(worldpos, 1.0), 1.0);\n");
|
||||
WRITE(p, " gl_Position = u_proj * (u_view * vec4(worldpos, 1.0));\n");
|
||||
}
|
||||
if (gstate.isFogEnabled())
|
||||
WRITE(p, " v_depth = gl_Position.z;\n");
|
||||
|
@ -353,6 +353,11 @@ namespace MainWindow
|
||||
UpdateMenus();
|
||||
break;
|
||||
|
||||
case ID_OPTIONS_HARDWARETRANSFORM:
|
||||
g_Config.bHardwareTransform = !g_Config.bHardwareTransform;
|
||||
UpdateMenus();
|
||||
break;
|
||||
|
||||
case ID_FILE_EXIT:
|
||||
DestroyWindow(hWnd);
|
||||
break;
|
||||
@ -632,6 +637,7 @@ namespace MainWindow
|
||||
CHECKITEM(ID_OPTIONS_BUFFEREDRENDERING, g_Config.bBufferedRendering);
|
||||
CHECKITEM(ID_OPTIONS_SHOWDEBUGSTATISTICS, g_Config.bShowDebugStats);
|
||||
CHECKITEM(ID_OPTIONS_WIREFRAME, g_Config.bDrawWireframe);
|
||||
CHECKITEM(ID_OPTIONS_HARDWARETRANSFORM, g_Config.bHardwareTransform);
|
||||
|
||||
BOOL enable = !Core_IsStepping();
|
||||
EnableMenuItem(menu,ID_EMULATION_RUN,enable);
|
||||
|
@ -214,6 +214,7 @@ BEGIN
|
||||
MENUITEM "&Toggle Full Screen\tF12", ID_OPTIONS_FULLSCREEN
|
||||
MENUITEM "&Display Raw Framebuffer", ID_OPTIONS_DISPLAYRAWFRAMEBUFFER
|
||||
MENUITEM "&Buffered Rendering\tF5", ID_OPTIONS_BUFFEREDRENDERING
|
||||
MENUITEM "&Hardware Transform", ID_OPTIONS_HARDWARETRANSFORM
|
||||
MENUITEM "&Wireframe (experimental)", ID_OPTIONS_WIREFRAME
|
||||
MENUITEM "&Show Debug Statistics", ID_OPTIONS_SHOWDEBUGSTATISTICS
|
||||
MENUITEM SEPARATOR
|
||||
|
@ -244,13 +244,14 @@
|
||||
#define ID_CPU_FASTINTERPRETER 40121
|
||||
#define ID_OPTIONS_SHOWDEBUGSTATISTICS 40122
|
||||
#define ID_OPTIONS_WIREFRAME 40123
|
||||
#define ID_OPTIONS_HARDWARETRANSFORM 40124
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 232
|
||||
#define _APS_NEXT_COMMAND_VALUE 40124
|
||||
#define _APS_NEXT_COMMAND_VALUE 40125
|
||||
#define _APS_NEXT_CONTROL_VALUE 1162
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
|
@ -241,7 +241,7 @@ void SettingsScreen::render() {
|
||||
int y = 50;
|
||||
UICheckBox(GEN_ID, x, y += 50, "Enable Sound Emulation", ALIGN_TOPLEFT, &g_Config.bEnableSound);
|
||||
UICheckBox(GEN_ID, x, y += 50, "Buffered Rendering (may fix flicker)", ALIGN_TOPLEFT, &g_Config.bBufferedRendering);
|
||||
|
||||
UICheckBox(GEN_ID, x, y += 50, "Hardware Transform (experimental)", ALIGN_TOPLEFT, &g_Config.bHardwareTransform);
|
||||
|
||||
bool useFastInt = g_Config.iCpuCore == CPU_FASTINTERPRETER;
|
||||
UICheckBox(GEN_ID, x, y += 50, "Slightly faster interpreter (may crash)", ALIGN_TOPLEFT, &useFastInt);
|
||||
|
Loading…
Reference in New Issue
Block a user