gl: 90deg screen rotation option. Fix scissor/clip wrt scale/stretch
90deg CC screen rotation option for some arcade games Fix scissoring and clipping when screen scaling/stretching/rotating Clear shader cache when screen rotation changes Properly delete all gl programs and shaders when needed
This commit is contained in:
parent
251b4d381d
commit
0445542ec2
|
@ -519,6 +519,7 @@ void InitSettings()
|
|||
settings.rend.ScreenStretching = 100;
|
||||
settings.rend.Fog = true;
|
||||
settings.rend.FloatVMUs = false;
|
||||
settings.rend.Rotate90 = false;
|
||||
|
||||
settings.pvr.ta_skip = 0;
|
||||
settings.pvr.rend = 0;
|
||||
|
@ -604,6 +605,7 @@ void LoadSettings(bool game_specific)
|
|||
settings.rend.ScreenStretching = cfgLoadInt(config_section, "rend.ScreenStretching", settings.rend.ScreenStretching);
|
||||
settings.rend.Fog = cfgLoadBool(config_section, "rend.Fog", settings.rend.Fog);
|
||||
settings.rend.FloatVMUs = cfgLoadBool(config_section, "rend.FloatVMUs", settings.rend.FloatVMUs);
|
||||
settings.rend.Rotate90 = cfgLoadBool(config_section, "rend.Rotate90", settings.rend.Rotate90);
|
||||
|
||||
settings.pvr.ta_skip = cfgLoadInt(config_section, "ta.skip", settings.pvr.ta_skip);
|
||||
settings.pvr.rend = cfgLoadInt(config_section, "pvr.rend", settings.pvr.rend);
|
||||
|
@ -730,6 +732,7 @@ void SaveSettings()
|
|||
cfgSaveInt("config", "rend.ScreenStretching", settings.rend.ScreenStretching);
|
||||
cfgSaveBool("config", "rend.Fog", settings.rend.Fog);
|
||||
cfgSaveBool("config", "rend.FloatVMUs", settings.rend.FloatVMUs);
|
||||
cfgSaveBool("config", "rend.Rotate90", settings.rend.Rotate90);
|
||||
cfgSaveInt("config", "ta.skip", settings.pvr.ta_skip);
|
||||
cfgSaveInt("config", "pvr.rend", settings.pvr.rend);
|
||||
|
||||
|
|
|
@ -331,23 +331,23 @@ void initABuffer()
|
|||
{
|
||||
char source[16384];
|
||||
sprintf(source, final_shader_source, 1);
|
||||
gl4CompilePipelineShader(&g_abuffer_final_shader, source);
|
||||
gl4CompilePipelineShader(&g_abuffer_final_shader, false, source);
|
||||
}
|
||||
if (g_abuffer_final_nosort_shader.program == 0)
|
||||
{
|
||||
char source[16384];
|
||||
sprintf(source, final_shader_source, 0);
|
||||
gl4CompilePipelineShader(&g_abuffer_final_nosort_shader, source);
|
||||
gl4CompilePipelineShader(&g_abuffer_final_nosort_shader, false, source);
|
||||
}
|
||||
if (g_abuffer_clear_shader.program == 0)
|
||||
gl4CompilePipelineShader(&g_abuffer_clear_shader, clear_shader_source);
|
||||
gl4CompilePipelineShader(&g_abuffer_clear_shader, false, clear_shader_source);
|
||||
if (g_abuffer_tr_modvol_shaders[0].program == 0)
|
||||
{
|
||||
char source[16384];
|
||||
for (int mode = 0; mode < ModeCount; mode++)
|
||||
{
|
||||
sprintf(source, tr_modvol_shader_source, mode);
|
||||
gl4CompilePipelineShader(&g_abuffer_tr_modvol_shaders[mode], source);
|
||||
gl4CompilePipelineShader(&g_abuffer_tr_modvol_shaders[mode], false, source);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -417,6 +417,17 @@ void termABuffer()
|
|||
glDeleteBuffers(1, &g_quadBuffer);
|
||||
g_quadBuffer = 0;
|
||||
}
|
||||
glcache.DeleteProgram(g_abuffer_final_shader.program);
|
||||
g_abuffer_final_shader.program = 0;
|
||||
glcache.DeleteProgram(g_abuffer_final_nosort_shader.program);
|
||||
g_abuffer_final_nosort_shader.program = 0;
|
||||
glcache.DeleteProgram(g_abuffer_clear_shader.program);
|
||||
g_abuffer_clear_shader.program = 0;
|
||||
for (int mode = 0; mode < ModeCount; mode++)
|
||||
{
|
||||
glcache.DeleteProgram(g_abuffer_tr_modvol_shaders[mode].program);
|
||||
g_abuffer_tr_modvol_shaders[mode].program = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void reshapeABuffer(int w, int h)
|
||||
|
|
|
@ -45,6 +45,7 @@ struct gl4_ctx
|
|||
} modvol_shader;
|
||||
|
||||
std::unordered_map<u32, gl4PipelineShader> shaders;
|
||||
bool rotate90;
|
||||
|
||||
struct
|
||||
{
|
||||
|
@ -66,7 +67,8 @@ bool gl4_render_output_framebuffer();
|
|||
void abufferDrawQuad(bool upsideDown = false, float x = 0.f, float y = 0.f, float w = 0.f, float h = 0.f);
|
||||
|
||||
extern const char *gl4PixelPipelineShader;
|
||||
bool gl4CompilePipelineShader(gl4PipelineShader* s, const char *source = gl4PixelPipelineShader);
|
||||
bool gl4CompilePipelineShader(gl4PipelineShader* s, bool rotate_90, const char *source = gl4PixelPipelineShader);
|
||||
void gl4_delete_shaders();
|
||||
|
||||
extern GLuint stencilTexId;
|
||||
extern GLuint depthTexId;
|
||||
|
|
|
@ -49,6 +49,11 @@ static gl4PipelineShader *gl4GetProgram(u32 cp_AlphaTest, u32 pp_ClipTestMode,
|
|||
u32 pp_Texture, u32 pp_UseAlpha, u32 pp_IgnoreTexA, u32 pp_ShadInstr, u32 pp_Offset,
|
||||
u32 pp_FogCtrl, bool pp_TwoVolumes, u32 pp_DepthFunc, bool pp_Gouraud, bool pp_BumpMap, bool fog_clamping, int pass)
|
||||
{
|
||||
if (settings.rend.Rotate90 != gl4.rotate90)
|
||||
{
|
||||
gl4_delete_shaders();
|
||||
gl4.rotate90 = settings.rend.Rotate90;
|
||||
}
|
||||
u32 rv=0;
|
||||
|
||||
rv|=pp_ClipTestMode;
|
||||
|
@ -83,7 +88,7 @@ static gl4PipelineShader *gl4GetProgram(u32 cp_AlphaTest, u32 pp_ClipTestMode,
|
|||
shader->pp_BumpMap = pp_BumpMap;
|
||||
shader->fog_clamping = fog_clamping;
|
||||
shader->pass = pass;
|
||||
gl4CompilePipelineShader(shader);
|
||||
gl4CompilePipelineShader(shader, settings.rend.Rotate90);
|
||||
}
|
||||
|
||||
return shader;
|
||||
|
|
|
@ -14,6 +14,7 @@ static const char* VertexShaderSource =
|
|||
"\
|
||||
#version 140 \n\
|
||||
#define pp_Gouraud %d \n\
|
||||
#define ROTATE_90 %d \n\
|
||||
\n\
|
||||
#if pp_Gouraud == 0 \n\
|
||||
#define INTERPOLATION flat \n\
|
||||
|
@ -56,6 +57,9 @@ void main() \n\
|
|||
\n\
|
||||
vpos.w = extra_depth_scale / vpos.z; \n\
|
||||
vpos.z = vpos.w; \n\
|
||||
#if ROTATE_90 == 1 \n\
|
||||
vpos.xy = vec2(vpos.y, -vpos.x); \n\
|
||||
#endif \n\
|
||||
vpos.xy=vpos.xy*scale.xy-scale.zw; \n\
|
||||
vpos.xy*=vpos.w; \n\
|
||||
gl_Position = vpos; \n\
|
||||
|
@ -393,11 +397,11 @@ gl4_ctx gl4;
|
|||
|
||||
struct gl4ShaderUniforms_t gl4ShaderUniforms;
|
||||
|
||||
bool gl4CompilePipelineShader( gl4PipelineShader* s, const char *source /* = PixelPipelineShader */)
|
||||
bool gl4CompilePipelineShader( gl4PipelineShader* s, bool rotate_90, const char *source /* = PixelPipelineShader */)
|
||||
{
|
||||
char vshader[16384];
|
||||
|
||||
sprintf(vshader, VertexShaderSource, s->pp_Gouraud);
|
||||
sprintf(vshader, VertexShaderSource, s->pp_Gouraud, rotate_90);
|
||||
|
||||
char pshader[16384];
|
||||
|
||||
|
@ -478,27 +482,45 @@ bool gl4CompilePipelineShader( gl4PipelineShader* s, const char *source /* = Pix
|
|||
|
||||
void gl_term();
|
||||
|
||||
void gl4_delete_shaders()
|
||||
{
|
||||
for (auto it : gl4.shaders)
|
||||
{
|
||||
if (it.second.program != 0)
|
||||
glcache.DeleteProgram(it.second.program);
|
||||
}
|
||||
gl4.shaders.clear();
|
||||
glcache.DeleteProgram(gl4.modvol_shader.program);
|
||||
gl4.modvol_shader.program = 0;
|
||||
}
|
||||
|
||||
static void gles_term(void)
|
||||
{
|
||||
glDeleteProgram(gl4.modvol_shader.program);
|
||||
glDeleteBuffers(1, &gl4.vbo.geometry);
|
||||
gl4.vbo.geometry = 0;
|
||||
glDeleteBuffers(1, &gl4.vbo.modvols);
|
||||
glDeleteBuffers(1, &gl4.vbo.idxs);
|
||||
glDeleteBuffers(1, &gl4.vbo.idxs2);
|
||||
glDeleteBuffers(1, &gl4.vbo.tr_poly_params);
|
||||
for (auto it = gl4.shaders.begin(); it != gl4.shaders.end(); it++)
|
||||
{
|
||||
if (it->second.program != 0)
|
||||
glDeleteProgram(it->second.program);
|
||||
}
|
||||
gl4.shaders.clear();
|
||||
gl4_delete_shaders();
|
||||
glDeleteVertexArrays(1, &gl4.vbo.main_vao);
|
||||
glDeleteVertexArrays(1, &gl4.vbo.modvol_vao);
|
||||
|
||||
gl_term();
|
||||
}
|
||||
|
||||
static void create_modvol_shader()
|
||||
{
|
||||
if (gl4.modvol_shader.program != 0)
|
||||
return;
|
||||
char vshader[16384];
|
||||
sprintf(vshader, VertexShaderSource, 1, settings.rend.Rotate90);
|
||||
|
||||
gl4.modvol_shader.program=gl_CompileAndLink(vshader, ModifierVolumeShader);
|
||||
gl4.modvol_shader.scale = glGetUniformLocation(gl4.modvol_shader.program, "scale");
|
||||
gl4.modvol_shader.extra_depth_scale = glGetUniformLocation(gl4.modvol_shader.program, "extra_depth_scale");
|
||||
}
|
||||
|
||||
static bool gl_create_resources()
|
||||
{
|
||||
if (gl4.vbo.geometry != 0)
|
||||
|
@ -520,12 +542,7 @@ static bool gl_create_resources()
|
|||
gl4SetupMainVBO();
|
||||
gl4SetupModvolVBO();
|
||||
|
||||
char vshader[16384];
|
||||
sprintf(vshader, VertexShaderSource, 1);
|
||||
|
||||
gl4.modvol_shader.program=gl_CompileAndLink(vshader, ModifierVolumeShader);
|
||||
gl4.modvol_shader.scale = glGetUniformLocation(gl4.modvol_shader.program, "scale");
|
||||
gl4.modvol_shader.extra_depth_scale = glGetUniformLocation(gl4.modvol_shader.program, "extra_depth_scale");
|
||||
create_modvol_shader();
|
||||
|
||||
gl_load_osd_resources();
|
||||
|
||||
|
@ -603,6 +620,7 @@ static bool RenderFrame()
|
|||
old_screen_scaling = settings.rend.ScreenScaling;
|
||||
}
|
||||
DoCleanup();
|
||||
create_modvol_shader();
|
||||
|
||||
bool is_rtt=pvrrc.isRTT;
|
||||
|
||||
|
@ -675,6 +693,17 @@ static bool RenderFrame()
|
|||
gl4ShaderUniforms.scale_coefs[3] = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (settings.rend.Rotate90)
|
||||
{
|
||||
dc2s_scale_h = screen_height / 640.0;
|
||||
ds2s_offs_x = (screen_width - dc2s_scale_h * 480.0 * screen_stretching) / 2;
|
||||
gl4ShaderUniforms.scale_coefs[0] = 2.0f / (screen_width / dc2s_scale_h * scale_x) * screen_stretching;
|
||||
gl4ShaderUniforms.scale_coefs[1] = -2.0f / dc_width;
|
||||
gl4ShaderUniforms.scale_coefs[2] = 1 - 2 * ds2s_offs_x / screen_width;
|
||||
gl4ShaderUniforms.scale_coefs[3] = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
dc2s_scale_h = screen_height / 480.0;
|
||||
ds2s_offs_x = (screen_width - dc2s_scale_h * 640.0 * screen_stretching) / 2;
|
||||
|
@ -684,6 +713,7 @@ static bool RenderFrame()
|
|||
gl4ShaderUniforms.scale_coefs[2] = 1 - 2 * ds2s_offs_x / screen_width;
|
||||
gl4ShaderUniforms.scale_coefs[3] = -1;
|
||||
}
|
||||
}
|
||||
|
||||
gl4ShaderUniforms.extra_depth_scale = settings.rend.ExtraDepthScale;
|
||||
|
||||
|
@ -838,11 +868,20 @@ static bool RenderFrame()
|
|||
float min_y = pvrrc.fb_Y_CLIP.min / scale_y;
|
||||
if (!is_rtt)
|
||||
{
|
||||
if (settings.rend.Rotate90)
|
||||
{
|
||||
float t = width;
|
||||
width = height;
|
||||
height = t;
|
||||
t = min_x;
|
||||
min_x = min_y;
|
||||
min_y = 640 - t - height;
|
||||
}
|
||||
// Add x offset for aspect ratio > 4/3
|
||||
min_x = min_x * dc2s_scale_h * screen_stretching + ds2s_offs_x * screen_scaling;
|
||||
min_x = (min_x * dc2s_scale_h * screen_stretching + ds2s_offs_x) * screen_scaling;
|
||||
// Invert y coordinates when rendering to screen
|
||||
min_y = (screen_height - (min_y + height) * dc2s_scale_h) * screen_scaling;
|
||||
width *= dc2s_scale_h * screen_scaling * screen_stretching;
|
||||
width *= dc2s_scale_h * screen_stretching * screen_scaling;
|
||||
height *= dc2s_scale_h * screen_scaling;
|
||||
|
||||
if (ds2s_offs_x > 0)
|
||||
|
|
|
@ -149,6 +149,19 @@ public:
|
|||
return _texture_ids[--_texture_cache_size];
|
||||
}
|
||||
|
||||
void DeleteProgram(GLuint program)
|
||||
{
|
||||
GLsizei shader_count;
|
||||
GLuint shaders[2];
|
||||
glGetAttachedShaders(program, ARRAY_SIZE(shaders), &shader_count, shaders);
|
||||
for (int i = 0; i < shader_count; i++)
|
||||
glDeleteShader(shaders[i]);
|
||||
|
||||
glDeleteProgram(program);
|
||||
if (_program == program)
|
||||
_program = 0;
|
||||
}
|
||||
|
||||
void Reset() {
|
||||
_texture = 0xFFFFFFFFu;
|
||||
_src_blend_factor = 0xFFFFFFFFu;
|
||||
|
|
|
@ -114,13 +114,30 @@ s32 SetTileClip(u32 val, GLint uniform)
|
|||
csy /= scale_y;
|
||||
cex /= scale_x;
|
||||
cey /= scale_y;
|
||||
float dc2s_scale_h;
|
||||
float ds2s_offs_x;
|
||||
float screen_stretching = settings.rend.ScreenStretching / 100.f;
|
||||
|
||||
if (settings.rend.Rotate90)
|
||||
{
|
||||
float t = cex;
|
||||
cex = cey;
|
||||
cey = 640 - csx;
|
||||
csx = csy;
|
||||
csy = 640 - t;
|
||||
dc2s_scale_h = screen_height / 640.0f;
|
||||
ds2s_offs_x = (screen_width - dc2s_scale_h * 480.0 * screen_stretching) / 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
float t = cey;
|
||||
cey = 480 - csy;
|
||||
csy = 480 - t;
|
||||
float dc2s_scale_h = screen_height / 480.0f;
|
||||
float ds2s_offs_x = (screen_width - dc2s_scale_h * 640) / 2;
|
||||
csx = csx * dc2s_scale_h + ds2s_offs_x;
|
||||
cex = cex * dc2s_scale_h + ds2s_offs_x;
|
||||
dc2s_scale_h = screen_height / 480.0f;
|
||||
ds2s_offs_x = (screen_width - dc2s_scale_h * 640.0 * screen_stretching) / 2;
|
||||
}
|
||||
csx = csx * dc2s_scale_h * screen_stretching + ds2s_offs_x;
|
||||
cex = cex * dc2s_scale_h * screen_stretching + ds2s_offs_x;
|
||||
csy = csy * dc2s_scale_h;
|
||||
cey = cey * dc2s_scale_h;
|
||||
}
|
||||
|
|
|
@ -79,6 +79,7 @@ const char* VertexShaderSource =
|
|||
%s \n\
|
||||
#define TARGET_GL %s \n\
|
||||
#define pp_Gouraud %d \n\
|
||||
#define ROTATE_90 %d \n\
|
||||
\n\
|
||||
#define GLES2 0 \n\
|
||||
#define GLES3 1 \n\
|
||||
|
@ -136,6 +137,9 @@ void main() \n\
|
|||
vpos.z = vpos.w; \n\
|
||||
#else \n\
|
||||
vpos.z=depth_scale.x+depth_scale.y*vpos.w; \n\
|
||||
#endif \n\
|
||||
#if ROTATE_90 == 1 \n\
|
||||
vpos.xy = vec2(vpos.y, -vpos.x); \n\
|
||||
#endif \n\
|
||||
vpos.xy=vpos.xy*scale.xy-scale.zw; \n\
|
||||
vpos.xy*=vpos.w; \n\
|
||||
|
@ -850,9 +854,20 @@ GLuint fogTextureId;
|
|||
extern void gl_term();
|
||||
#endif
|
||||
|
||||
static void gl_delete_shaders()
|
||||
{
|
||||
for (auto it : gl.shaders)
|
||||
{
|
||||
if (it.second.program != 0)
|
||||
glcache.DeleteProgram(it.second.program);
|
||||
}
|
||||
gl.shaders.clear();
|
||||
glcache.DeleteProgram(gl.modvol_shader.program);
|
||||
gl.modvol_shader.program = 0;
|
||||
}
|
||||
|
||||
static void gles_term()
|
||||
{
|
||||
glDeleteProgram(gl.modvol_shader.program);
|
||||
glDeleteBuffers(1, &gl.vbo.geometry);
|
||||
gl.vbo.geometry = 0;
|
||||
glDeleteBuffers(1, &gl.vbo.modvols);
|
||||
|
@ -865,7 +880,7 @@ static void gles_term()
|
|||
gl_free_osd_resources();
|
||||
free_output_framebuffer();
|
||||
|
||||
gl.shaders.clear();
|
||||
gl_delete_shaders();
|
||||
gl_term();
|
||||
}
|
||||
|
||||
|
@ -1018,6 +1033,11 @@ PipelineShader *GetProgram(u32 cp_AlphaTest, u32 pp_ClipTestMode,
|
|||
u32 pp_Texture, u32 pp_UseAlpha, u32 pp_IgnoreTexA, u32 pp_ShadInstr, u32 pp_Offset,
|
||||
u32 pp_FogCtrl, bool pp_Gouraud, bool pp_BumpMap, bool fog_clamping, bool trilinear)
|
||||
{
|
||||
if (settings.rend.Rotate90 != gl.rotate90)
|
||||
{
|
||||
gl_delete_shaders();
|
||||
gl.rotate90 = settings.rend.Rotate90;
|
||||
}
|
||||
u32 rv=0;
|
||||
|
||||
rv|=pp_ClipTestMode;
|
||||
|
@ -1058,7 +1078,7 @@ bool CompilePipelineShader( PipelineShader* s)
|
|||
{
|
||||
char vshader[8192];
|
||||
|
||||
sprintf(vshader, VertexShaderSource, gl.glsl_version_header, gl.gl_version, s->pp_Gouraud);
|
||||
sprintf(vshader, VertexShaderSource, gl.glsl_version_header, gl.gl_version, s->pp_Gouraud, settings.rend.Rotate90);
|
||||
|
||||
char pshader[8192];
|
||||
|
||||
|
@ -1144,13 +1164,30 @@ void gl_load_osd_resources()
|
|||
|
||||
void gl_free_osd_resources()
|
||||
{
|
||||
glDeleteProgram(gl.OSD_SHADER.program);
|
||||
glcache.DeleteProgram(gl.OSD_SHADER.program);
|
||||
|
||||
if (osd_tex != 0) {
|
||||
glcache.DeleteTextures(1, &osd_tex);
|
||||
osd_tex = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void create_modvol_shader()
|
||||
{
|
||||
if (gl.modvol_shader.program != 0)
|
||||
return;
|
||||
char vshader[8192];
|
||||
sprintf(vshader, VertexShaderSource, gl.glsl_version_header, gl.gl_version, 1, settings.rend.Rotate90);
|
||||
char fshader[8192];
|
||||
sprintf(fshader, ModifierVolumeShader, gl.glsl_version_header, gl.gl_version);
|
||||
|
||||
gl.modvol_shader.program=gl_CompileAndLink(vshader, fshader);
|
||||
gl.modvol_shader.scale = glGetUniformLocation(gl.modvol_shader.program, "scale");
|
||||
gl.modvol_shader.sp_ShaderColor = glGetUniformLocation(gl.modvol_shader.program, "sp_ShaderColor");
|
||||
gl.modvol_shader.depth_scale = glGetUniformLocation(gl.modvol_shader.program, "depth_scale");
|
||||
gl.modvol_shader.extra_depth_scale = glGetUniformLocation(gl.modvol_shader.program, "extra_depth_scale");
|
||||
}
|
||||
|
||||
bool gl_create_resources()
|
||||
{
|
||||
if (gl.vbo.geometry != 0)
|
||||
|
@ -1174,25 +1211,7 @@ bool gl_create_resources()
|
|||
glGenBuffers(1, &gl.vbo.idxs);
|
||||
glGenBuffers(1, &gl.vbo.idxs2);
|
||||
|
||||
char vshader[8192];
|
||||
sprintf(vshader, VertexShaderSource, gl.glsl_version_header, gl.gl_version, 1);
|
||||
char fshader[8192];
|
||||
sprintf(fshader, ModifierVolumeShader, gl.glsl_version_header, gl.gl_version);
|
||||
|
||||
gl.modvol_shader.program=gl_CompileAndLink(vshader, fshader);
|
||||
gl.modvol_shader.scale = glGetUniformLocation(gl.modvol_shader.program, "scale");
|
||||
gl.modvol_shader.sp_ShaderColor = glGetUniformLocation(gl.modvol_shader.program, "sp_ShaderColor");
|
||||
gl.modvol_shader.depth_scale = glGetUniformLocation(gl.modvol_shader.program, "depth_scale");
|
||||
gl.modvol_shader.extra_depth_scale = glGetUniformLocation(gl.modvol_shader.program, "extra_depth_scale");
|
||||
|
||||
//#define PRECOMPILE_SHADERS
|
||||
#ifdef PRECOMPILE_SHADERS
|
||||
for (u32 i=0;i<sizeof(gl.pogram_table)/sizeof(gl.pogram_table[0]);i++)
|
||||
{
|
||||
if (!CompilePipelineShader( &gl.pogram_table[i] ))
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
create_modvol_shader();
|
||||
|
||||
gl_load_osd_resources();
|
||||
|
||||
|
@ -1512,6 +1531,7 @@ static void upload_vertex_indices()
|
|||
bool RenderFrame()
|
||||
{
|
||||
DoCleanup();
|
||||
create_modvol_shader();
|
||||
|
||||
bool is_rtt=pvrrc.isRTT;
|
||||
|
||||
|
@ -1693,14 +1713,26 @@ bool RenderFrame()
|
|||
}
|
||||
else
|
||||
{
|
||||
dc2s_scale_h = screen_height / 480.0;
|
||||
ds2s_offs_x = (screen_width - dc2s_scale_h * 640.0 * screen_stretching) / 2;
|
||||
//-1 -> too much to left
|
||||
if (settings.rend.Rotate90)
|
||||
{
|
||||
dc2s_scale_h = screen_height / 640.0f;
|
||||
ds2s_offs_x = (screen_width - dc2s_scale_h * 480.0f * screen_stretching) / 2;
|
||||
ShaderUniforms.scale_coefs[0] = 2.0f / (screen_width / dc2s_scale_h * scale_x) * screen_stretching;
|
||||
ShaderUniforms.scale_coefs[1] = -2.0f / dc_width;
|
||||
ShaderUniforms.scale_coefs[2] = 1 - 2 * ds2s_offs_x / screen_width;
|
||||
ShaderUniforms.scale_coefs[3] = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
dc2s_scale_h = screen_height / 480.0f;
|
||||
ds2s_offs_x = (screen_width - dc2s_scale_h * 640.0f * screen_stretching) / 2;
|
||||
ShaderUniforms.scale_coefs[0] = 2.0f / (screen_width / dc2s_scale_h * scale_x) * screen_stretching;
|
||||
ShaderUniforms.scale_coefs[1] = -2.0f / dc_height;
|
||||
ShaderUniforms.scale_coefs[2] = 1 - 2 * ds2s_offs_x / screen_width;
|
||||
ShaderUniforms.scale_coefs[3] = -1;
|
||||
}
|
||||
//-1 -> too much to left
|
||||
}
|
||||
|
||||
ShaderUniforms.depth_coefs[0]=2/(vtx_max_fZ-vtx_min_fZ);
|
||||
ShaderUniforms.depth_coefs[1]=-vtx_min_fZ-1;
|
||||
|
@ -1868,11 +1900,20 @@ bool RenderFrame()
|
|||
float min_y = pvrrc.fb_Y_CLIP.min / scale_y;
|
||||
if (!is_rtt)
|
||||
{
|
||||
if (settings.rend.Rotate90)
|
||||
{
|
||||
float t = width;
|
||||
width = height;
|
||||
height = t;
|
||||
t = min_x;
|
||||
min_x = min_y;
|
||||
min_y = 640 - t - height;
|
||||
}
|
||||
// Add x offset for aspect ratio > 4/3
|
||||
min_x = min_x * dc2s_scale_h * screen_stretching + ds2s_offs_x * screen_scaling;
|
||||
min_x = (min_x * dc2s_scale_h * screen_stretching + ds2s_offs_x) * screen_scaling;
|
||||
// Invert y coordinates when rendering to screen
|
||||
min_y = (screen_height - (min_y + height) * dc2s_scale_h) * screen_scaling;
|
||||
width *= dc2s_scale_h * screen_scaling * screen_stretching;
|
||||
width *= dc2s_scale_h * screen_stretching * screen_scaling;
|
||||
height *= dc2s_scale_h * screen_scaling;
|
||||
|
||||
if (ds2s_offs_x > 0)
|
||||
|
|
|
@ -96,6 +96,7 @@ struct gl_ctx
|
|||
} modvol_shader;
|
||||
|
||||
std::unordered_map<u32, PipelineShader> shaders;
|
||||
bool rotate90;
|
||||
|
||||
struct
|
||||
{
|
||||
|
|
|
@ -490,15 +490,9 @@ void ImGui_ImplOpenGL3_DestroyDeviceObjects()
|
|||
if (g_ElementsHandle) glDeleteBuffers(1, &g_ElementsHandle);
|
||||
g_VboHandle = g_ElementsHandle = 0;
|
||||
|
||||
if (g_ShaderHandle && g_VertHandle) glDetachShader(g_ShaderHandle, g_VertHandle);
|
||||
if (g_VertHandle) glDeleteShader(g_VertHandle);
|
||||
glcache.DeleteProgram(g_ShaderHandle);
|
||||
g_VertHandle = 0;
|
||||
|
||||
if (g_ShaderHandle && g_FragHandle) glDetachShader(g_ShaderHandle, g_FragHandle);
|
||||
if (g_FragHandle) glDeleteShader(g_FragHandle);
|
||||
g_FragHandle = 0;
|
||||
|
||||
if (g_ShaderHandle) glDeleteProgram(g_ShaderHandle);
|
||||
g_ShaderHandle = 0;
|
||||
|
||||
ImGui_ImplOpenGL3_DestroyFontsTexture();
|
||||
|
|
|
@ -804,13 +804,14 @@ static void gui_display_settings()
|
|||
if (ImGui::BeginTabItem("Controls"))
|
||||
{
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, normal_padding);
|
||||
#if DC_PLATFORM == DC_PLATFORM_DREAMCAST
|
||||
#if DC_PLATFORM == DC_PLATFORM_DREAMCAST || DC_PLATFORM == DC_PLATFORM_ATOMISWAVE
|
||||
if (ImGui::CollapsingHeader("Dreamcast Devices", ImGuiTreeNodeFlags_DefaultOpen))
|
||||
{
|
||||
for (int bus = 0; bus < MAPLE_PORTS; bus++)
|
||||
{
|
||||
ImGui::Text("Device %c", bus + 'A');
|
||||
ImGui::SameLine();
|
||||
#if DC_PLATFORM == DC_PLATFORM_DREAMCAST
|
||||
char device_name[32];
|
||||
sprintf(device_name, "##device%d", bus);
|
||||
float w = ImGui::CalcItemWidth() / 3;
|
||||
|
@ -854,6 +855,10 @@ static void gui_display_settings()
|
|||
ImGui::PopID();
|
||||
}
|
||||
ImGui::PopItemWidth();
|
||||
#elif DC_PLATFORM == DC_PLATFORM_ATOMISWAVE
|
||||
if (MapleDevices[bus][5] != NULL)
|
||||
ImGui::Text("%s", maple_device_name(MapleDevices[bus][5]->get_device_type()));
|
||||
#endif
|
||||
}
|
||||
ImGui::Spacing();
|
||||
}
|
||||
|
@ -966,6 +971,9 @@ static void gui_display_settings()
|
|||
ImGui::Checkbox("Show VMU in game", &settings.rend.FloatVMUs);
|
||||
ImGui::SameLine();
|
||||
ShowHelpMarker("Show the VMU LCD screens while in game");
|
||||
ImGui::Checkbox("Rotate screen 90°", &settings.rend.Rotate90);
|
||||
ImGui::SameLine();
|
||||
ShowHelpMarker("Rotate the screen 90° counterclockwise");
|
||||
ImGui::SliderInt("Scaling", (int *)&settings.rend.ScreenScaling, 1, 100);
|
||||
ImGui::SameLine();
|
||||
ShowHelpMarker("Downscaling factor relative to native screen resolution. Higher is better");
|
||||
|
|
|
@ -636,6 +636,7 @@ struct settings_t
|
|||
int ScreenStretching; // in percent. 150 means stretch from 4/3 to 6/3
|
||||
bool Fog;
|
||||
bool FloatVMUs;
|
||||
bool Rotate90; // Rotate the screen 90 deg CC
|
||||
} rend;
|
||||
|
||||
struct
|
||||
|
|
Loading…
Reference in New Issue