refactor xform matrix out of gles. use xform matrix in vulkan
This commit is contained in:
parent
2f363a7355
commit
07958f08ae
|
@ -329,7 +329,8 @@ bool rend_single_frame()
|
||||||
}
|
}
|
||||||
while (!_pvrrc);
|
while (!_pvrrc);
|
||||||
bool do_swp = rend_frame(_pvrrc);
|
bool do_swp = rend_frame(_pvrrc);
|
||||||
swap_pending = settings.rend.DelayFrameSwapping && do_swp && !_pvrrc->rend.isRenderFramebuffer;
|
swap_pending = settings.rend.DelayFrameSwapping && do_swp && !_pvrrc->rend.isRenderFramebuffer
|
||||||
|
&& settings.pvr.rend != 4; // TODO Fix vulkan
|
||||||
|
|
||||||
#if !defined(TARGET_NO_THREADS)
|
#if !defined(TARGET_NO_THREADS)
|
||||||
if (_pvrrc->rend.isRTT)
|
if (_pvrrc->rend.isRTT)
|
||||||
|
|
|
@ -40,7 +40,6 @@ struct gl4_ctx
|
||||||
{
|
{
|
||||||
GLuint program;
|
GLuint program;
|
||||||
|
|
||||||
GLuint extra_depth_scale;
|
|
||||||
GLuint normal_matrix;
|
GLuint normal_matrix;
|
||||||
} modvol_shader;
|
} modvol_shader;
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include "oslib/oslib.h"
|
#include "oslib/oslib.h"
|
||||||
#include "rend/rend.h"
|
#include "rend/rend.h"
|
||||||
#include "rend/gui.h"
|
#include "rend/gui.h"
|
||||||
|
#include "rend/transform_matrix.h"
|
||||||
|
|
||||||
//Fragment and vertex shaders code
|
//Fragment and vertex shaders code
|
||||||
|
|
||||||
|
@ -513,7 +514,6 @@ static void create_modvol_shader()
|
||||||
|
|
||||||
gl4.modvol_shader.program=gl_CompileAndLink(vshader, ModifierVolumeShader);
|
gl4.modvol_shader.program=gl_CompileAndLink(vshader, ModifierVolumeShader);
|
||||||
gl4.modvol_shader.normal_matrix = glGetUniformLocation(gl4.modvol_shader.program, "normal_matrix");
|
gl4.modvol_shader.normal_matrix = glGetUniformLocation(gl4.modvol_shader.program, "normal_matrix");
|
||||||
gl4.modvol_shader.extra_depth_scale = glGetUniformLocation(gl4.modvol_shader.program, "extra_depth_scale");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool gl_create_resources()
|
static bool gl_create_resources()
|
||||||
|
@ -639,38 +639,29 @@ static bool RenderFrame()
|
||||||
DoCleanup();
|
DoCleanup();
|
||||||
create_modvol_shader();
|
create_modvol_shader();
|
||||||
|
|
||||||
bool is_rtt = pvrrc.isRTT;
|
const bool is_rtt = pvrrc.isRTT;
|
||||||
|
|
||||||
|
TransformMatrix<true> matrices(pvrrc);
|
||||||
|
gl4ShaderUniforms.normal_mat = matrices.GetNormalMatrix();
|
||||||
|
const glm::mat4& scissor_mat = matrices.GetScissorMatrix();
|
||||||
|
ViewportMatrix = matrices.GetViewportMatrix();
|
||||||
|
|
||||||
//these should be adjusted based on the current PVR scaling etc params
|
|
||||||
float dc_width;
|
|
||||||
float dc_height;
|
|
||||||
GetFramebufferSize(dc_width, dc_height);
|
|
||||||
|
|
||||||
if (!is_rtt)
|
if (!is_rtt)
|
||||||
gcflip = 0;
|
gcflip = 0;
|
||||||
else
|
else
|
||||||
gcflip = 1;
|
gcflip = 1;
|
||||||
|
|
||||||
float scale_x;
|
|
||||||
float scale_y;
|
|
||||||
float scissoring_scale_x;
|
|
||||||
float scissoring_scale_y;
|
|
||||||
GetFramebufferScaling(scale_x, scale_y, scissoring_scale_x, scissoring_scale_y);
|
|
||||||
|
|
||||||
dc_width *= scale_x;
|
|
||||||
dc_height *= scale_y;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Handle Dc to screen scaling
|
Handle Dc to screen scaling
|
||||||
*/
|
*/
|
||||||
float screen_scaling = settings.rend.ScreenScaling / 100.f;
|
const float screen_scaling = settings.rend.ScreenScaling / 100.f;
|
||||||
int rendering_width;
|
int rendering_width;
|
||||||
int rendering_height;
|
int rendering_height;
|
||||||
if (is_rtt)
|
if (is_rtt)
|
||||||
{
|
{
|
||||||
int scaling = settings.rend.RenderToTextureBuffer ? 1 : settings.rend.RenderToTextureUpscale;
|
int scaling = settings.rend.RenderToTextureBuffer ? 1 : settings.rend.RenderToTextureUpscale;
|
||||||
rendering_width = dc_width * scaling;
|
rendering_width = matrices.GetDreamcastViewport().x * scaling;
|
||||||
rendering_height = dc_height * scaling;
|
rendering_height = matrices.GetDreamcastViewport().y * scaling;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -679,11 +670,6 @@ static bool RenderFrame()
|
||||||
}
|
}
|
||||||
resize(rendering_width, rendering_height);
|
resize(rendering_width, rendering_height);
|
||||||
|
|
||||||
float ds2s_offs_x;
|
|
||||||
|
|
||||||
glm::mat4 scissor_mat;
|
|
||||||
SetupMatrices(dc_width, dc_height, scale_x, scale_y, scissoring_scale_x, scissoring_scale_y, ds2s_offs_x, gl4ShaderUniforms.normal_mat, scissor_mat);
|
|
||||||
|
|
||||||
gl4ShaderUniforms.extra_depth_scale = settings.rend.ExtraDepthScale;
|
gl4ShaderUniforms.extra_depth_scale = settings.rend.ExtraDepthScale;
|
||||||
|
|
||||||
//DEBUG_LOG(RENDERER, "scale: %f, %f, %f, %f", gl4ShaderUniforms.scale_coefs[0], gl4ShaderUniforms.scale_coefs[1], gl4ShaderUniforms.scale_coefs[2], gl4ShaderUniforms.scale_coefs[3]);
|
//DEBUG_LOG(RENDERER, "scale: %f, %f, %f, %f", gl4ShaderUniforms.scale_coefs[0], gl4ShaderUniforms.scale_coefs[1], gl4ShaderUniforms.scale_coefs[2], gl4ShaderUniforms.scale_coefs[3]);
|
||||||
|
@ -724,7 +710,6 @@ static bool RenderFrame()
|
||||||
glcache.UseProgram(gl4.modvol_shader.program);
|
glcache.UseProgram(gl4.modvol_shader.program);
|
||||||
|
|
||||||
glUniformMatrix4fv(gl4.modvol_shader.normal_matrix, 1, GL_FALSE, &gl4ShaderUniforms.normal_mat[0][0]);
|
glUniformMatrix4fv(gl4.modvol_shader.normal_matrix, 1, GL_FALSE, &gl4ShaderUniforms.normal_mat[0][0]);
|
||||||
glUniform1f(gl4.modvol_shader.extra_depth_scale, gl4ShaderUniforms.extra_depth_scale);
|
|
||||||
|
|
||||||
gl4ShaderUniforms.PT_ALPHA=(PT_ALPHA_REF&0xFF)/255.0f;
|
gl4ShaderUniforms.PT_ALPHA=(PT_ALPHA_REF&0xFF)/255.0f;
|
||||||
|
|
||||||
|
@ -768,7 +753,8 @@ static bool RenderFrame()
|
||||||
}
|
}
|
||||||
DEBUG_LOG(RENDERER, "RTT packmode=%d stride=%d - %d,%d -> %d,%d", FB_W_CTRL.fb_packmode, FB_W_LINESTRIDE.stride * 8,
|
DEBUG_LOG(RENDERER, "RTT packmode=%d stride=%d - %d,%d -> %d,%d", FB_W_CTRL.fb_packmode, FB_W_LINESTRIDE.stride * 8,
|
||||||
FB_X_CLIP.min, FB_Y_CLIP.min, FB_X_CLIP.max, FB_Y_CLIP.max);
|
FB_X_CLIP.min, FB_Y_CLIP.min, FB_X_CLIP.max, FB_Y_CLIP.max);
|
||||||
output_fbo = gl4BindRTT(FB_W_SOF1 & VRAM_MASK, dc_width, dc_height, channels, format);
|
output_fbo = gl4BindRTT(FB_W_SOF1 & VRAM_MASK, (u32)lroundf(matrices.GetDreamcastViewport().x),
|
||||||
|
(u32)lroundf(matrices.GetDreamcastViewport().y), channels, format);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -809,23 +795,7 @@ static bool RenderFrame()
|
||||||
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(struct PolyParam) * pvrrc.global_param_tr.used(), pvrrc.global_param_tr.head(), GL_STATIC_DRAW);
|
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(struct PolyParam) * pvrrc.global_param_tr.used(), pvrrc.global_param_tr.head(), GL_STATIC_DRAW);
|
||||||
glCheck();
|
glCheck();
|
||||||
|
|
||||||
//not all scaling affects pixel operations, scale to adjust for that
|
if (is_rtt || !settings.rend.WideScreen || matrices.IsClipped())
|
||||||
scale_x *= scissoring_scale_x;
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
//handy to debug really stupid render-not-working issues ...
|
|
||||||
DEBUG_LOG(RENDERER, "SS: %dx%d", screen_width, screen_height);
|
|
||||||
DEBUG_LOG(RENDERER, "SCI: %d, %f", pvrrc.fb_X_CLIP.max, dc2s_scale_h);
|
|
||||||
DEBUG_LOG(RENDERER, "SCI: %f, %f, %f, %f", offs_x+pvrrc.fb_X_CLIP.min/scale_x,(pvrrc.fb_Y_CLIP.min/scale_y)*dc2s_scale_h,(pvrrc.fb_X_CLIP.max-pvrrc.fb_X_CLIP.min+1)/scale_x*dc2s_scale_h,(pvrrc.fb_Y_CLIP.max-pvrrc.fb_Y_CLIP.min+1)/scale_y*dc2s_scale_h);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
bool wide_screen_on = !is_rtt && settings.rend.WideScreen
|
|
||||||
&& pvrrc.fb_X_CLIP.min == 0
|
|
||||||
&& lroundf((pvrrc.fb_X_CLIP.max + 1) / scale_x) == 640L
|
|
||||||
&& pvrrc.fb_Y_CLIP.min == 0
|
|
||||||
&& lroundf((pvrrc.fb_Y_CLIP.max + 1) / scale_y) == 480L;
|
|
||||||
|
|
||||||
if (!wide_screen_on)
|
|
||||||
{
|
{
|
||||||
float width;
|
float width;
|
||||||
float height;
|
float height;
|
||||||
|
@ -853,9 +823,9 @@ static bool RenderFrame()
|
||||||
min_y += height;
|
min_y += height;
|
||||||
height = -height;
|
height = -height;
|
||||||
}
|
}
|
||||||
if (ds2s_offs_x > 0)
|
if (matrices.GetSidebarWidth() > 0)
|
||||||
{
|
{
|
||||||
float scaled_offs_x = ds2s_offs_x * screen_scaling;
|
float scaled_offs_x = matrices.GetSidebarWidth() * screen_scaling;
|
||||||
|
|
||||||
glcache.ClearColor(0.f, 0.f, 0.f, 0.f);
|
glcache.ClearColor(0.f, 0.f, 0.f, 0.f);
|
||||||
glcache.Enable(GL_SCISSOR_TEST);
|
glcache.Enable(GL_SCISSOR_TEST);
|
||||||
|
@ -883,8 +853,6 @@ static bool RenderFrame()
|
||||||
glcache.Enable(GL_SCISSOR_TEST);
|
glcache.Enable(GL_SCISSOR_TEST);
|
||||||
}
|
}
|
||||||
|
|
||||||
//restore scale_x
|
|
||||||
scale_x /= scissoring_scale_x;
|
|
||||||
gl4DrawStrips(output_fbo, rendering_width, rendering_height);
|
gl4DrawStrips(output_fbo, rendering_width, rendering_height);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -895,7 +863,7 @@ static bool RenderFrame()
|
||||||
glcache.ClearColor(0.f, 0.f, 0.f, 0.f);
|
glcache.ClearColor(0.f, 0.f, 0.f, 0.f);
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
gl4DrawFramebuffer(dc_width, dc_height);
|
gl4DrawFramebuffer(640.f, 480.f);
|
||||||
}
|
}
|
||||||
|
|
||||||
eglCheck();
|
eglCheck();
|
||||||
|
@ -917,7 +885,7 @@ struct gl4rend : Renderer
|
||||||
{
|
{
|
||||||
screen_width=w;
|
screen_width=w;
|
||||||
screen_height=h;
|
screen_height=h;
|
||||||
resize(lroundf(w * settings.rend.ScreenScaling / 100.f), lroundf(h * settings.rend.ScreenScaling / 100.f));
|
resize((int)lroundf(w * settings.rend.ScreenScaling / 100.f), (int)lroundf(h * settings.rend.ScreenScaling / 100.f));
|
||||||
}
|
}
|
||||||
void Term() override
|
void Term() override
|
||||||
{
|
{
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include "wsi/gl_context.h"
|
#include "wsi/gl_context.h"
|
||||||
#include "cfg/cfg.h"
|
#include "cfg/cfg.h"
|
||||||
#include "rend/osd.h"
|
#include "rend/osd.h"
|
||||||
|
#include "rend/transform_matrix.h"
|
||||||
|
|
||||||
#ifdef GLES
|
#ifdef GLES
|
||||||
#ifndef GL_RED
|
#ifndef GL_RED
|
||||||
|
@ -20,7 +21,6 @@
|
||||||
#include "oslib/oslib.h"
|
#include "oslib/oslib.h"
|
||||||
#include "rend/rend.h"
|
#include "rend/rend.h"
|
||||||
#include "input/gamepad.h"
|
#include "input/gamepad.h"
|
||||||
#include <glm/gtx/transform.hpp>
|
|
||||||
|
|
||||||
float fb_scale_x, fb_scale_y; // FIXME
|
float fb_scale_x, fb_scale_y; // FIXME
|
||||||
|
|
||||||
|
@ -816,7 +816,6 @@ static void create_modvol_shader()
|
||||||
gl.modvol_shader.normal_matrix = glGetUniformLocation(gl.modvol_shader.program, "normal_matrix");
|
gl.modvol_shader.normal_matrix = glGetUniformLocation(gl.modvol_shader.program, "normal_matrix");
|
||||||
gl.modvol_shader.sp_ShaderColor = glGetUniformLocation(gl.modvol_shader.program, "sp_ShaderColor");
|
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.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()
|
bool gl_create_resources()
|
||||||
|
@ -1026,161 +1025,6 @@ static void upload_vertex_indices()
|
||||||
glCheck();
|
glCheck();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GetFramebufferScaling(float& scale_x, float& scale_y, float& scissoring_scale_x, float& scissoring_scale_y)
|
|
||||||
{
|
|
||||||
scale_x = 1;
|
|
||||||
scale_y = 1;
|
|
||||||
scissoring_scale_x = 1;
|
|
||||||
scissoring_scale_y = 1;
|
|
||||||
|
|
||||||
if (!pvrrc.isRTT && !pvrrc.isRenderFramebuffer)
|
|
||||||
{
|
|
||||||
scale_x = fb_scale_x;
|
|
||||||
scale_y = fb_scale_y;
|
|
||||||
if (SCALER_CTL.vscalefactor >= 0x400)
|
|
||||||
{
|
|
||||||
// Interlace mode A (single framebuffer)
|
|
||||||
if (SCALER_CTL.interlace == 0)
|
|
||||||
scale_y *= (float)SCALER_CTL.vscalefactor / 0x400;
|
|
||||||
else
|
|
||||||
// Interlace mode B (alternating framebuffers)
|
|
||||||
scissoring_scale_y /= (float)SCALER_CTL.vscalefactor / 0x400;
|
|
||||||
}
|
|
||||||
|
|
||||||
// VO pixel doubling is done after fb rendering/clipping
|
|
||||||
// so it should be used for scissoring as well
|
|
||||||
if (VO_CONTROL.pixel_double)
|
|
||||||
scale_x *= 0.5f;
|
|
||||||
|
|
||||||
// the X Scaler halves the horizontal resolution but
|
|
||||||
// before clipping/scissoring
|
|
||||||
if (SCALER_CTL.hscale)
|
|
||||||
{
|
|
||||||
scissoring_scale_x /= 2.f;
|
|
||||||
scale_x *= 2.f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void GetFramebufferSize(float& dc_width, float& dc_height)
|
|
||||||
{
|
|
||||||
if (pvrrc.isRTT)
|
|
||||||
{
|
|
||||||
dc_width = pvrrc.fb_X_CLIP.max - pvrrc.fb_X_CLIP.min + 1;
|
|
||||||
dc_height = pvrrc.fb_Y_CLIP.max - pvrrc.fb_Y_CLIP.min + 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
dc_width = 640;
|
|
||||||
dc_height = 480;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetupMatrices(float dc_width, float dc_height,
|
|
||||||
float scale_x, float scale_y, float scissoring_scale_x, float scissoring_scale_y,
|
|
||||||
float &ds2s_offs_x, glm::mat4& normal_mat, glm::mat4& scissor_mat)
|
|
||||||
{
|
|
||||||
float screen_scaling = settings.rend.ScreenScaling / 100.f;
|
|
||||||
|
|
||||||
if (pvrrc.isRTT)
|
|
||||||
{
|
|
||||||
ShaderUniforms.normal_mat = glm::translate(glm::vec3(-1, -1, 0))
|
|
||||||
* glm::scale(glm::vec3(2.0f / dc_width, 2.0f / dc_height, 1.f));
|
|
||||||
scissor_mat = ShaderUniforms.normal_mat;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
float startx = 0;
|
|
||||||
float starty = 0;
|
|
||||||
bool vga = FB_R_CTRL.vclk_div == 1;
|
|
||||||
switch (SPG_LOAD.hcount)
|
|
||||||
{
|
|
||||||
case 857: // NTSC, VGA
|
|
||||||
startx = VO_STARTX.HStart - (vga ? 0xa8 : 0xa4);
|
|
||||||
break;
|
|
||||||
case 863: // PAL
|
|
||||||
startx = VO_STARTX.HStart - 0xae;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
INFO_LOG(PVR, "unknown video mode: hcount %d", SPG_LOAD.hcount);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
switch (SPG_LOAD.vcount)
|
|
||||||
{
|
|
||||||
case 524: // NTSC, VGA
|
|
||||||
starty = VO_STARTY.VStart_field1 - (vga ? 0x28 : 0x12);
|
|
||||||
break;
|
|
||||||
case 262: // NTSC 240p
|
|
||||||
starty = VO_STARTY.VStart_field1 - 0x11;
|
|
||||||
break;
|
|
||||||
case 624: // PAL
|
|
||||||
starty = VO_STARTY.VStart_field1 - 0x2d;
|
|
||||||
break;
|
|
||||||
case 312: // PAL 240p
|
|
||||||
starty = VO_STARTY.VStart_field1 - 0x2e;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
INFO_LOG(PVR, "unknown video mode: vcount %d", SPG_LOAD.vcount);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
// some heuristic...
|
|
||||||
startx *= 0.8;
|
|
||||||
starty *= 1.1;
|
|
||||||
normal_mat = glm::translate(glm::vec3(startx, starty, 0));
|
|
||||||
scissor_mat = normal_mat;
|
|
||||||
|
|
||||||
float screen_stretching = settings.rend.ScreenStretching / 100.f;
|
|
||||||
float dc2s_scale_h;
|
|
||||||
|
|
||||||
if (settings.rend.Rotate90)
|
|
||||||
{
|
|
||||||
dc2s_scale_h = screen_height / 640.0f;
|
|
||||||
ds2s_offs_x = (screen_width - dc2s_scale_h * 480.0f * screen_stretching) / 2;
|
|
||||||
float y_coef = 2.0f / (screen_width / dc2s_scale_h * scale_y) * screen_stretching;
|
|
||||||
float x_coef = -2.0f / dc_width;
|
|
||||||
glm::mat4 trans_rot = glm::rotate((float)M_PI_2, glm::vec3(0, 0, 1))
|
|
||||||
* glm::translate(glm::vec3(1, -1 + 2 * ds2s_offs_x / screen_width, 0));
|
|
||||||
normal_mat = trans_rot
|
|
||||||
* glm::scale(glm::vec3(x_coef, y_coef, 1.f))
|
|
||||||
* normal_mat;
|
|
||||||
scissor_mat = trans_rot
|
|
||||||
* glm::scale(glm::vec3(x_coef / scissoring_scale_x,
|
|
||||||
y_coef/ scissoring_scale_y, 1.f))
|
|
||||||
* scissor_mat; // FIXME scale_x not used, except in dc_width???
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
dc2s_scale_h = screen_height / 480.0f;
|
|
||||||
ds2s_offs_x = (screen_width - dc2s_scale_h * 640.0f * screen_stretching) / 2;
|
|
||||||
float x_coef = 2.0f / (screen_width / dc2s_scale_h * scale_x) * screen_stretching;
|
|
||||||
float y_coef = -2.0f / dc_height;
|
|
||||||
normal_mat = glm::translate(glm::vec3(-1 + 2 * ds2s_offs_x / screen_width, 1, 0))
|
|
||||||
* glm::scale(glm::vec3(x_coef, y_coef, 1.f))
|
|
||||||
* normal_mat;
|
|
||||||
scissor_mat = glm::translate(glm::vec3(-1 + 2 * ds2s_offs_x / screen_width, 1, 0))
|
|
||||||
* glm::scale(glm::vec3(x_coef / scissoring_scale_x,
|
|
||||||
y_coef / scissoring_scale_y, 1.f))
|
|
||||||
* scissor_mat;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
normal_mat = glm::scale(glm::vec3(1, 1, 1 / settings.rend.ExtraDepthScale))
|
|
||||||
* normal_mat;
|
|
||||||
|
|
||||||
glm::mat4 vp_trans = glm::translate(glm::vec3(1, 1, 0));
|
|
||||||
if (pvrrc.isRTT)
|
|
||||||
{
|
|
||||||
vp_trans = glm::scale(glm::vec3(dc_width / 2, dc_height / 2, 1.f))
|
|
||||||
* vp_trans;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
vp_trans = glm::scale(glm::vec3(screen_width * screen_scaling / 2, screen_height * screen_scaling / 2, 1.f))
|
|
||||||
* vp_trans;
|
|
||||||
}
|
|
||||||
ViewportMatrix = vp_trans * normal_mat;
|
|
||||||
scissor_mat = vp_trans * scissor_mat;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool RenderFrame()
|
bool RenderFrame()
|
||||||
{
|
{
|
||||||
DoCleanup();
|
DoCleanup();
|
||||||
|
@ -1200,39 +1044,16 @@ bool RenderFrame()
|
||||||
vtx_min_fZ *= 0.98f;
|
vtx_min_fZ *= 0.98f;
|
||||||
vtx_max_fZ *= 1.001f;
|
vtx_max_fZ *= 1.001f;
|
||||||
|
|
||||||
//calculate a projection so that it matches the pvr x,y setup, and
|
TransformMatrix<true> matrices(pvrrc);
|
||||||
//a) Z is linearly scaled between 0 ... 1
|
ShaderUniforms.normal_mat = matrices.GetNormalMatrix();
|
||||||
//b) W is passed though for proper perspective calculations
|
const glm::mat4& scissor_mat = matrices.GetScissorMatrix();
|
||||||
|
ViewportMatrix = matrices.GetViewportMatrix();
|
||||||
//these should be adjusted based on the current PVR scaling etc params
|
|
||||||
float dc_width;
|
|
||||||
float dc_height;
|
|
||||||
GetFramebufferSize(dc_width, dc_height);
|
|
||||||
|
|
||||||
if (!is_rtt)
|
if (!is_rtt)
|
||||||
gcflip = 0;
|
gcflip = 0;
|
||||||
else
|
else
|
||||||
gcflip = 1;
|
gcflip = 1;
|
||||||
|
|
||||||
float scale_x;
|
|
||||||
float scale_y;
|
|
||||||
float scissoring_scale_x;
|
|
||||||
float scissoring_scale_y;
|
|
||||||
GetFramebufferScaling(scale_x, scale_y, scissoring_scale_x, scissoring_scale_y);
|
|
||||||
|
|
||||||
dc_width *= scale_x;
|
|
||||||
dc_height *= scale_y;
|
|
||||||
|
|
||||||
/*
|
|
||||||
Handle Dc to screen scaling
|
|
||||||
*/
|
|
||||||
float screen_scaling = settings.rend.ScreenScaling / 100.f;
|
|
||||||
|
|
||||||
float ds2s_offs_x;
|
|
||||||
|
|
||||||
glm::mat4 scissor_mat;
|
|
||||||
SetupMatrices(dc_width, dc_height, scale_x, scale_y, scissoring_scale_x, scissoring_scale_y, ds2s_offs_x, ShaderUniforms.normal_mat, scissor_mat);
|
|
||||||
|
|
||||||
ShaderUniforms.depth_coefs[0] = 2 / (vtx_max_fZ - vtx_min_fZ);
|
ShaderUniforms.depth_coefs[0] = 2 / (vtx_max_fZ - vtx_min_fZ);
|
||||||
ShaderUniforms.depth_coefs[1] = -vtx_min_fZ - 1;
|
ShaderUniforms.depth_coefs[1] = -vtx_min_fZ - 1;
|
||||||
ShaderUniforms.depth_coefs[2] = 0;
|
ShaderUniforms.depth_coefs[2] = 0;
|
||||||
|
@ -1276,7 +1097,6 @@ bool RenderFrame()
|
||||||
glcache.UseProgram(gl.modvol_shader.program);
|
glcache.UseProgram(gl.modvol_shader.program);
|
||||||
|
|
||||||
glUniform4fv( gl.modvol_shader.depth_scale, 1, ShaderUniforms.depth_coefs);
|
glUniform4fv( gl.modvol_shader.depth_scale, 1, ShaderUniforms.depth_coefs);
|
||||||
glUniform1f(gl.modvol_shader.extra_depth_scale, ShaderUniforms.extra_depth_scale);
|
|
||||||
glUniformMatrix4fv(gl.modvol_shader.normal_matrix, 1, GL_FALSE, &ShaderUniforms.normal_mat[0][0]);
|
glUniformMatrix4fv(gl.modvol_shader.normal_matrix, 1, GL_FALSE, &ShaderUniforms.normal_mat[0][0]);
|
||||||
|
|
||||||
ShaderUniforms.PT_ALPHA=(PT_ALPHA_REF&0xFF)/255.0f;
|
ShaderUniforms.PT_ALPHA=(PT_ALPHA_REF&0xFF)/255.0f;
|
||||||
|
@ -1287,6 +1107,8 @@ bool RenderFrame()
|
||||||
ShaderUniforms.Set(&it.second);
|
ShaderUniforms.Set(&it.second);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const float screen_scaling = settings.rend.ScreenScaling / 100.f;
|
||||||
|
|
||||||
//setup render target first
|
//setup render target first
|
||||||
if (is_rtt)
|
if (is_rtt)
|
||||||
{
|
{
|
||||||
|
@ -1325,7 +1147,7 @@ bool RenderFrame()
|
||||||
}
|
}
|
||||||
DEBUG_LOG(RENDERER, "RTT packmode=%d stride=%d - %d,%d -> %d,%d", FB_W_CTRL.fb_packmode, FB_W_LINESTRIDE.stride * 8,
|
DEBUG_LOG(RENDERER, "RTT packmode=%d stride=%d - %d,%d -> %d,%d", FB_W_CTRL.fb_packmode, FB_W_LINESTRIDE.stride * 8,
|
||||||
FB_X_CLIP.min, FB_Y_CLIP.min, FB_X_CLIP.max, FB_Y_CLIP.max);
|
FB_X_CLIP.min, FB_Y_CLIP.min, FB_X_CLIP.max, FB_Y_CLIP.max);
|
||||||
BindRTT(FB_W_SOF1 & VRAM_MASK, dc_width, dc_height, channels, format);
|
BindRTT(FB_W_SOF1 & VRAM_MASK, FB_X_CLIP.max - FB_X_CLIP.min + 1, FB_Y_CLIP.max - FB_Y_CLIP.min + 1, channels, format);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1343,11 +1165,7 @@ bool RenderFrame()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wide_screen_on = !is_rtt && settings.rend.WideScreen
|
bool wide_screen_on = !is_rtt && settings.rend.WideScreen && !matrices.IsClipped();
|
||||||
&& pvrrc.fb_X_CLIP.min == 0
|
|
||||||
&& lroundf((pvrrc.fb_X_CLIP.max + 1) / scale_x) == 640L
|
|
||||||
&& pvrrc.fb_Y_CLIP.min == 0
|
|
||||||
&& lroundf((pvrrc.fb_Y_CLIP.max + 1) / scale_y) == 480L;
|
|
||||||
|
|
||||||
//Color is cleared by the background plane
|
//Color is cleared by the background plane
|
||||||
|
|
||||||
|
@ -1406,9 +1224,9 @@ bool RenderFrame()
|
||||||
min_y += height;
|
min_y += height;
|
||||||
height = -height;
|
height = -height;
|
||||||
}
|
}
|
||||||
if (ds2s_offs_x > 0)
|
if (matrices.GetSidebarWidth() > 0)
|
||||||
{
|
{
|
||||||
float scaled_offs_x = ds2s_offs_x * screen_scaling;
|
float scaled_offs_x = matrices.GetSidebarWidth() * screen_scaling;
|
||||||
|
|
||||||
glcache.ClearColor(0.f, 0.f, 0.f, 0.f);
|
glcache.ClearColor(0.f, 0.f, 0.f, 0.f);
|
||||||
glcache.Enable(GL_SCISSOR_TEST);
|
glcache.Enable(GL_SCISSOR_TEST);
|
||||||
|
|
|
@ -53,7 +53,6 @@ struct gl_ctx
|
||||||
GLuint program;
|
GLuint program;
|
||||||
|
|
||||||
GLuint depth_scale;
|
GLuint depth_scale;
|
||||||
GLuint extra_depth_scale;
|
|
||||||
GLuint sp_ShaderColor;
|
GLuint sp_ShaderColor;
|
||||||
GLuint normal_matrix;
|
GLuint normal_matrix;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,19 @@
|
||||||
// Personal message to whoever wrote this code originally: please quit programming. Stop making other people's life miserable
|
/*
|
||||||
|
This file is part of reicast.
|
||||||
|
|
||||||
|
reicast is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
reicast is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with reicast. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
#include "osd.h"
|
#include "osd.h"
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include "input/gamepad.h"
|
#include "input/gamepad.h"
|
||||||
|
|
|
@ -1,3 +1,19 @@
|
||||||
|
/*
|
||||||
|
This file is part of reicast.
|
||||||
|
|
||||||
|
reicast is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
reicast is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with reicast. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,216 @@
|
||||||
|
/*
|
||||||
|
Created on: Oct 22, 2019
|
||||||
|
|
||||||
|
Copyright 2019 flyinghead
|
||||||
|
|
||||||
|
This file is part of Flycast.
|
||||||
|
|
||||||
|
Flycast is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
Flycast is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with Flycast. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
#include <glm/gtx/transform.hpp>
|
||||||
|
#include "hw/pvr/ta_ctx.h"
|
||||||
|
|
||||||
|
extern float fb_scale_x, fb_scale_y;
|
||||||
|
extern int screen_width, screen_height;
|
||||||
|
|
||||||
|
template<bool invertY>
|
||||||
|
class TransformMatrix
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TransformMatrix() = default;
|
||||||
|
TransformMatrix(const rend_context& renderingContext)
|
||||||
|
{
|
||||||
|
CalcMatrices(&renderingContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsClipped() const
|
||||||
|
{
|
||||||
|
return renderingContext->fb_X_CLIP.min != 0
|
||||||
|
|| lroundf((renderingContext->fb_X_CLIP.max + 1) / scale_x) != 640L
|
||||||
|
|| renderingContext->fb_Y_CLIP.min != 0
|
||||||
|
|| lroundf((renderingContext->fb_Y_CLIP.max + 1) / scale_y) != 480L;
|
||||||
|
}
|
||||||
|
|
||||||
|
const glm::mat4& GetNormalMatrix() const {
|
||||||
|
return normalMatrix;
|
||||||
|
}
|
||||||
|
const glm::mat4& GetScissorMatrix() const {
|
||||||
|
return scissorMatrix;
|
||||||
|
}
|
||||||
|
const glm::mat4& GetViewportMatrix() const {
|
||||||
|
return viewportMatrix;
|
||||||
|
}
|
||||||
|
|
||||||
|
float GetSidebarWidth() const {
|
||||||
|
return sidebarWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::vec2 GetDreamcastViewport() const {
|
||||||
|
return dcViewport;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CalcMatrices(const rend_context *renderingContext)
|
||||||
|
{
|
||||||
|
this->renderingContext = renderingContext;
|
||||||
|
|
||||||
|
GetFramebufferScaling(false, scale_x, scale_y);
|
||||||
|
|
||||||
|
if (renderingContext->isRTT)
|
||||||
|
{
|
||||||
|
dcViewport.x = renderingContext->fb_X_CLIP.max - renderingContext->fb_X_CLIP.min + 1;
|
||||||
|
dcViewport.y = renderingContext->fb_Y_CLIP.max - renderingContext->fb_Y_CLIP.min + 1;
|
||||||
|
normalMatrix = glm::translate(glm::vec3(-1, -1, 0))
|
||||||
|
* glm::scale(glm::vec3(2.0f / dcViewport.x, 2.0f / dcViewport.y, 1.f));
|
||||||
|
scissorMatrix = normalMatrix;
|
||||||
|
sidebarWidth = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dcViewport.x = 640.f * scale_x;
|
||||||
|
dcViewport.y = 480.f * scale_y;
|
||||||
|
|
||||||
|
float startx = 0;
|
||||||
|
float starty = 0;
|
||||||
|
const bool vga = FB_R_CTRL.vclk_div == 1;
|
||||||
|
switch (SPG_LOAD.hcount)
|
||||||
|
{
|
||||||
|
case 857: // NTSC, VGA
|
||||||
|
startx = VO_STARTX.HStart - (vga ? 0xa8 : 0xa4);
|
||||||
|
break;
|
||||||
|
case 863: // PAL
|
||||||
|
startx = VO_STARTX.HStart - 0xae;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
INFO_LOG(PVR, "unknown video mode: hcount %d", SPG_LOAD.hcount);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
switch (SPG_LOAD.vcount)
|
||||||
|
{
|
||||||
|
case 524: // NTSC, VGA
|
||||||
|
starty = VO_STARTY.VStart_field1 - (vga ? 0x28 : 0x12);
|
||||||
|
break;
|
||||||
|
case 262: // NTSC 240p
|
||||||
|
starty = VO_STARTY.VStart_field1 - 0x11;
|
||||||
|
break;
|
||||||
|
case 624: // PAL
|
||||||
|
starty = VO_STARTY.VStart_field1 - 0x2d;
|
||||||
|
break;
|
||||||
|
case 312: // PAL 240p
|
||||||
|
starty = VO_STARTY.VStart_field1 - 0x2e;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
INFO_LOG(PVR, "unknown video mode: vcount %d", SPG_LOAD.vcount);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// some heuristic...
|
||||||
|
startx *= 0.8;
|
||||||
|
starty *= 1.1;
|
||||||
|
normalMatrix = glm::translate(glm::vec3(startx, starty, 0));
|
||||||
|
scissorMatrix = normalMatrix;
|
||||||
|
|
||||||
|
const float screen_stretching = settings.rend.ScreenStretching / 100.f;
|
||||||
|
float scissoring_scale_x, scissoring_scale_y;
|
||||||
|
GetFramebufferScaling(true, scissoring_scale_x, scissoring_scale_y);
|
||||||
|
|
||||||
|
if (settings.rend.Rotate90)
|
||||||
|
{
|
||||||
|
float dc2s_scale_h = screen_height / 640.0f;
|
||||||
|
sidebarWidth = (screen_width - dc2s_scale_h * 480.0f * screen_stretching) / 2;
|
||||||
|
float y_coef = -2.0f / (screen_width / dc2s_scale_h * scale_y) * screen_stretching;
|
||||||
|
float x_coef = -2.0f / dcViewport.x * (invertY ? -1 : 1);
|
||||||
|
glm::mat4 trans_rot = glm::rotate((float)M_PI_2, glm::vec3(0, 0, 1))
|
||||||
|
* glm::translate(glm::vec3(invertY ? -1.f : 1.f, 1 - 2 * sidebarWidth / screen_width, 0));
|
||||||
|
normalMatrix = trans_rot
|
||||||
|
* glm::scale(glm::vec3(x_coef, y_coef, 1.f))
|
||||||
|
* normalMatrix;
|
||||||
|
scissorMatrix = trans_rot
|
||||||
|
* glm::scale(glm::vec3(x_coef / scale_x * scissoring_scale_x, y_coef / scale_y * scissoring_scale_y, 1.f))
|
||||||
|
* scissorMatrix;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
float dc2s_scale_h = screen_height / 480.0f;
|
||||||
|
sidebarWidth = (screen_width - dc2s_scale_h * 640.0f * screen_stretching) / 2;
|
||||||
|
float x_coef = 2.0f / (screen_width / dc2s_scale_h * scale_x) * screen_stretching;
|
||||||
|
float y_coef = 2.0f / dcViewport.y * (invertY ? -1 : 1);
|
||||||
|
normalMatrix = glm::translate(glm::vec3(-1 + 2 * sidebarWidth / screen_width, invertY ? 1 : -1, 0))
|
||||||
|
* glm::scale(glm::vec3(x_coef, y_coef, 1.f))
|
||||||
|
* normalMatrix;
|
||||||
|
scissorMatrix = glm::translate(glm::vec3(-1 + 2 * sidebarWidth / screen_width, invertY ? 1 : -1, 0))
|
||||||
|
* glm::scale(glm::vec3(x_coef / scale_x * scissoring_scale_x, y_coef / scale_y * scissoring_scale_y, 1.f))
|
||||||
|
* scissorMatrix;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
normalMatrix = glm::scale(glm::vec3(1, 1, 1 / settings.rend.ExtraDepthScale))
|
||||||
|
* normalMatrix;
|
||||||
|
|
||||||
|
glm::mat4 vp_trans = glm::translate(glm::vec3(1, 1, 0));
|
||||||
|
if (renderingContext->isRTT)
|
||||||
|
{
|
||||||
|
vp_trans = glm::scale(glm::vec3(dcViewport.x / 2, dcViewport.y / 2, 1.f))
|
||||||
|
* vp_trans;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
float screen_scaling = settings.rend.ScreenScaling / 100.f;
|
||||||
|
vp_trans = glm::scale(glm::vec3(screen_width * screen_scaling / 2, screen_height * screen_scaling / 2, 1.f))
|
||||||
|
* vp_trans;
|
||||||
|
}
|
||||||
|
viewportMatrix = vp_trans * normalMatrix;
|
||||||
|
scissorMatrix = vp_trans * scissorMatrix;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void GetFramebufferScaling(bool scissor, float& scale_x, float& scale_y)
|
||||||
|
{
|
||||||
|
scale_x = 1.f;
|
||||||
|
scale_y = 1.f;
|
||||||
|
|
||||||
|
if (!renderingContext->isRTT && !renderingContext->isRenderFramebuffer)
|
||||||
|
{
|
||||||
|
scale_x = fb_scale_x;
|
||||||
|
scale_y = fb_scale_y;
|
||||||
|
if (SCALER_CTL.vscalefactor > 0x400)
|
||||||
|
{
|
||||||
|
// Interlace mode A (single framebuffer)
|
||||||
|
if (SCALER_CTL.interlace == 0 && !scissor)
|
||||||
|
scale_y *= roundf((float)SCALER_CTL.vscalefactor / 0x400);
|
||||||
|
else if (SCALER_CTL.interlace == 1 && scissor)
|
||||||
|
// Interlace mode B (alternating framebuffers)
|
||||||
|
scale_y *= roundf((float)SCALER_CTL.vscalefactor / 0x400);
|
||||||
|
}
|
||||||
|
|
||||||
|
// VO pixel doubling is done after fb rendering/clipping
|
||||||
|
// so it should be used for scissoring as well
|
||||||
|
if (VO_CONTROL.pixel_double)
|
||||||
|
scale_x *= 0.5f;
|
||||||
|
|
||||||
|
// the X Scaler halves the horizontal resolution but
|
||||||
|
// before clipping/scissoring
|
||||||
|
if (SCALER_CTL.hscale && !scissor)
|
||||||
|
scale_x *= 2.f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const rend_context *renderingContext = nullptr;
|
||||||
|
|
||||||
|
glm::mat4 normalMatrix;
|
||||||
|
glm::mat4 scissorMatrix;
|
||||||
|
glm::mat4 viewportMatrix;
|
||||||
|
glm::vec2 dcViewport;
|
||||||
|
float scale_x = 0;
|
||||||
|
float scale_y = 0;
|
||||||
|
float sidebarWidth = 0;
|
||||||
|
};
|
|
@ -20,11 +20,8 @@
|
||||||
*/
|
*/
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include "drawer.h"
|
#include "drawer.h"
|
||||||
#include "../gui.h"
|
|
||||||
#include "hw/pvr/pvr_mem.h"
|
#include "hw/pvr/pvr_mem.h"
|
||||||
|
|
||||||
extern float fb_scale_x, fb_scale_y;
|
|
||||||
|
|
||||||
void Drawer::SortTriangles()
|
void Drawer::SortTriangles()
|
||||||
{
|
{
|
||||||
sortedPolys.resize(pvrrc.render_passes.used());
|
sortedPolys.resize(pvrrc.render_passes.used());
|
||||||
|
@ -84,33 +81,15 @@ TileClipping Drawer::SetTileClip(u32 val, vk::Rect2D& clipRect)
|
||||||
{
|
{
|
||||||
if (!pvrrc.isRTT)
|
if (!pvrrc.isRTT)
|
||||||
{
|
{
|
||||||
csx /= scale_x;
|
glm::vec4 clip_start(csx, csy, 0, 1);
|
||||||
csy /= scale_y;
|
glm::vec4 clip_end(cex, cey, 0, 1);
|
||||||
cex /= scale_x;
|
clip_start = matrices.GetViewportMatrix() * clip_start;
|
||||||
cey /= scale_y;
|
clip_end = matrices.GetViewportMatrix() * clip_end;
|
||||||
float dc2s_scale_h;
|
|
||||||
float ds2s_offs_x;
|
|
||||||
float screen_stretching = settings.rend.ScreenStretching / 100.f;
|
|
||||||
|
|
||||||
if (settings.rend.Rotate90)
|
csx = clip_start[0];
|
||||||
{
|
csy = clip_start[1];
|
||||||
float t = cex;
|
cey = clip_end[1];
|
||||||
cex = cey;
|
cex = clip_end[0];
|
||||||
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
|
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
else if (!settings.rend.RenderToTextureBuffer)
|
else if (!settings.rend.RenderToTextureBuffer)
|
||||||
{
|
{
|
||||||
|
@ -290,79 +269,8 @@ bool Drawer::Draw(const Texture *fogTexture)
|
||||||
{
|
{
|
||||||
extern bool fog_needs_update;
|
extern bool fog_needs_update;
|
||||||
|
|
||||||
bool is_rtt = pvrrc.isRTT;
|
|
||||||
float dc_width = 640;
|
|
||||||
float dc_height = 480;
|
|
||||||
|
|
||||||
if (is_rtt)
|
|
||||||
{
|
|
||||||
dc_width = pvrrc.fb_X_CLIP.max - pvrrc.fb_X_CLIP.min + 1;
|
|
||||||
dc_height = pvrrc.fb_Y_CLIP.max - pvrrc.fb_Y_CLIP.min + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
scale_x = 1;
|
|
||||||
scissor_scale_x = 1;
|
|
||||||
scale_y = 1;
|
|
||||||
|
|
||||||
if (!is_rtt && !pvrrc.isRenderFramebuffer)
|
|
||||||
{
|
|
||||||
scale_x = fb_scale_x;
|
|
||||||
scissor_scale_x = fb_scale_x;
|
|
||||||
scale_y = fb_scale_y;
|
|
||||||
if (SCALER_CTL.interlace == 0 && SCALER_CTL.vscalefactor > 0x400)
|
|
||||||
scale_y *= roundf((float)SCALER_CTL.vscalefactor / 0x400);
|
|
||||||
|
|
||||||
//Pixel doubling is on VO, so it does not affect any pixel operations
|
|
||||||
if (VO_CONTROL.pixel_double)
|
|
||||||
{
|
|
||||||
scissor_scale_x *= 0.5f;
|
|
||||||
scale_x *= 0.5f;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (SCALER_CTL.hscale)
|
|
||||||
scale_x *= 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
dc_width *= scale_x;
|
|
||||||
dc_height *= scale_y;
|
|
||||||
|
|
||||||
float screen_stretching = settings.rend.ScreenStretching / 100.f;
|
|
||||||
float screen_scaling = settings.rend.ScreenScaling / 100.f;
|
|
||||||
|
|
||||||
float dc2s_scale_h;
|
|
||||||
float ds2s_offs_x;
|
|
||||||
|
|
||||||
VertexShaderUniforms vtxUniforms;
|
VertexShaderUniforms vtxUniforms;
|
||||||
if (is_rtt)
|
vtxUniforms.normal_matrix = matrices.GetNormalMatrix();
|
||||||
{
|
|
||||||
vtxUniforms.scale[0] = 2.0f / dc_width;
|
|
||||||
vtxUniforms.scale[1] = 2.0f / dc_height;
|
|
||||||
vtxUniforms.scale[2] = 1;
|
|
||||||
vtxUniforms.scale[3] = 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (settings.rend.Rotate90)
|
|
||||||
{
|
|
||||||
dc2s_scale_h = screen_height / 640.0f;
|
|
||||||
ds2s_offs_x = (screen_width - dc2s_scale_h * 480.0f * screen_stretching) / 2;
|
|
||||||
vtxUniforms.scale[0] = -2.0f / (screen_width / dc2s_scale_h * scale_x) * screen_stretching;
|
|
||||||
vtxUniforms.scale[1] = 2.0f / dc_width;
|
|
||||||
vtxUniforms.scale[2] = 1 - 2 * ds2s_offs_x / screen_width;
|
|
||||||
vtxUniforms.scale[3] = 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
dc2s_scale_h = screen_height / 480.0f;
|
|
||||||
ds2s_offs_x = (screen_width - dc2s_scale_h * 640.0f * screen_stretching) / 2;
|
|
||||||
vtxUniforms.scale[0] = 2.0f / (screen_width / dc2s_scale_h * scale_x) * screen_stretching;
|
|
||||||
vtxUniforms.scale[1] = 2.0f / dc_height;
|
|
||||||
vtxUniforms.scale[2] = 1 - 2 * ds2s_offs_x / screen_width;
|
|
||||||
vtxUniforms.scale[3] = 1;
|
|
||||||
}
|
|
||||||
//-1 -> too much to left
|
|
||||||
}
|
|
||||||
vtxUniforms.extra_depth_scale = settings.rend.ExtraDepthScale;
|
|
||||||
|
|
||||||
FragmentShaderUniforms fragUniforms;
|
FragmentShaderUniforms fragUniforms;
|
||||||
fragUniforms.extra_depth_scale = settings.rend.ExtraDepthScale;
|
fragUniforms.extra_depth_scale = settings.rend.ExtraDepthScale;
|
||||||
|
@ -445,16 +353,16 @@ bool Drawer::Draw(const Texture *fogTexture)
|
||||||
DrawList(cmdBuffer, ListType_Translucent, false, pvrrc.global_param_tr, previous_pass.tr_count, current_pass.tr_count - previous_pass.tr_count);
|
DrawList(cmdBuffer, ListType_Translucent, false, pvrrc.global_param_tr, previous_pass.tr_count, current_pass.tr_count - previous_pass.tr_count);
|
||||||
previous_pass = current_pass;
|
previous_pass = current_pass;
|
||||||
}
|
}
|
||||||
if (!is_rtt)
|
|
||||||
gui_display_osd();
|
|
||||||
|
|
||||||
return !is_rtt;
|
return !pvrrc.isRTT;
|
||||||
}
|
}
|
||||||
|
|
||||||
vk::CommandBuffer TextureDrawer::BeginRenderPass()
|
vk::CommandBuffer TextureDrawer::BeginRenderPass()
|
||||||
{
|
{
|
||||||
DEBUG_LOG(RENDERER, "RenderToTexture packmode=%d stride=%d - %d,%d -> %d,%d", FB_W_CTRL.fb_packmode, FB_W_LINESTRIDE.stride * 8,
|
DEBUG_LOG(RENDERER, "RenderToTexture packmode=%d stride=%d - %d,%d -> %d,%d", FB_W_CTRL.fb_packmode, FB_W_LINESTRIDE.stride * 8,
|
||||||
FB_X_CLIP.min, FB_Y_CLIP.min, FB_X_CLIP.max, FB_Y_CLIP.max);
|
FB_X_CLIP.min, FB_Y_CLIP.min, FB_X_CLIP.max, FB_Y_CLIP.max);
|
||||||
|
matrices.CalcMatrices(&pvrrc);
|
||||||
|
|
||||||
textureAddr = FB_W_SOF1 & VRAM_MASK;
|
textureAddr = FB_W_SOF1 & VRAM_MASK;
|
||||||
u32 origWidth = pvrrc.fb_X_CLIP.max - pvrrc.fb_X_CLIP.min + 1;
|
u32 origWidth = pvrrc.fb_X_CLIP.max - pvrrc.fb_X_CLIP.min + 1;
|
||||||
u32 origHeight = pvrrc.fb_Y_CLIP.max - pvrrc.fb_Y_CLIP.min + 1;
|
u32 origHeight = pvrrc.fb_Y_CLIP.max - pvrrc.fb_Y_CLIP.min + 1;
|
||||||
|
@ -631,12 +539,12 @@ vk::CommandBuffer ScreenDrawer::BeginRenderPass()
|
||||||
GetContext()->NewFrame();
|
GetContext()->NewFrame();
|
||||||
GetContext()->BeginRenderPass();
|
GetContext()->BeginRenderPass();
|
||||||
vk::CommandBuffer commandBuffer = GetContext()->GetCurrentCommandBuffer();
|
vk::CommandBuffer commandBuffer = GetContext()->GetCurrentCommandBuffer();
|
||||||
commandBuffer.setViewport(0, vk::Viewport(0.0f, 0.0f, (float) ((screen_width)), (float) ((screen_height)), 1.0f, 0.0f));
|
commandBuffer.setViewport(0, vk::Viewport(0.0f, 0.0f, (float)screen_width, (float)screen_height, 1.0f, 0.0f));
|
||||||
bool wide_screen_on = settings.rend.WideScreen && !pvrrc.isRenderFramebuffer
|
|
||||||
&& pvrrc.fb_X_CLIP.min == 0
|
matrices.CalcMatrices(&pvrrc);
|
||||||
&& lroundf((pvrrc.fb_X_CLIP.max + 1) / scissor_scale_x) == 640L
|
|
||||||
&& pvrrc.fb_Y_CLIP.min == 0
|
bool wide_screen_on = settings.rend.WideScreen && !pvrrc.isRenderFramebuffer && !matrices.IsClipped();
|
||||||
&& lroundf((pvrrc.fb_Y_CLIP.max + 1) / scale_y) == 480L;
|
|
||||||
if (!wide_screen_on)
|
if (!wide_screen_on)
|
||||||
{
|
{
|
||||||
float width;
|
float width;
|
||||||
|
@ -653,45 +561,27 @@ vk::CommandBuffer ScreenDrawer::BeginRenderPass()
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
width = (pvrrc.fb_X_CLIP.max - pvrrc.fb_X_CLIP.min + 1) / scissor_scale_x;
|
glm::vec4 clip_min(pvrrc.fb_X_CLIP.min, pvrrc.fb_Y_CLIP.min, 0, 1);
|
||||||
height = (pvrrc.fb_Y_CLIP.max - pvrrc.fb_Y_CLIP.min + 1) / scale_y;
|
glm::vec4 clip_dim(pvrrc.fb_X_CLIP.max - pvrrc.fb_X_CLIP.min + 1,
|
||||||
min_x = pvrrc.fb_X_CLIP.min / scissor_scale_x;
|
pvrrc.fb_Y_CLIP.max - pvrrc.fb_Y_CLIP.min + 1, 0, 0);
|
||||||
min_y = pvrrc.fb_Y_CLIP.min / scale_y;
|
clip_min = matrices.GetScissorMatrix() * clip_min;
|
||||||
|
clip_dim = matrices.GetScissorMatrix() * clip_dim;
|
||||||
|
|
||||||
if (SCALER_CTL.interlace && SCALER_CTL.vscalefactor > 0x400)
|
min_x = clip_min[0];
|
||||||
|
min_y = clip_min[1];
|
||||||
|
width = clip_dim[0];
|
||||||
|
height = clip_dim[1];
|
||||||
|
if (width < 0)
|
||||||
{
|
{
|
||||||
// Clipping is done after scaling/filtering so account for that if enabled
|
min_x += width;
|
||||||
height *= (float) SCALER_CTL.vscalefactor / 0x400;
|
width = -width;
|
||||||
min_y *= (float) SCALER_CTL.vscalefactor / 0x400;
|
}
|
||||||
|
if (height < 0)
|
||||||
|
{
|
||||||
|
min_y += height;
|
||||||
|
height = -height;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (settings.rend.Rotate90)
|
|
||||||
{
|
|
||||||
float t = width;
|
|
||||||
width = height;
|
|
||||||
height = t;
|
|
||||||
t = min_x;
|
|
||||||
min_x = min_y;
|
|
||||||
min_y = 640 - t - height;
|
|
||||||
}
|
|
||||||
const float screen_stretching = settings.rend.ScreenStretching / 100.f;
|
|
||||||
const float screen_scaling = settings.rend.ScreenScaling / 100.f;
|
|
||||||
float dc2s_scale_h, ds2s_offs_x;
|
|
||||||
if (settings.rend.Rotate90)
|
|
||||||
{
|
|
||||||
dc2s_scale_h = screen_height / 640.0f;
|
|
||||||
ds2s_offs_x = (screen_width - dc2s_scale_h * 480.0f * screen_stretching) / 2;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
dc2s_scale_h = screen_height / 480.0f;
|
|
||||||
ds2s_offs_x = (screen_width - dc2s_scale_h * 640.0f * screen_stretching) / 2;
|
|
||||||
}
|
|
||||||
// Add x offset for aspect ratio > 4/3
|
|
||||||
min_x = (min_x * dc2s_scale_h * screen_stretching + ds2s_offs_x) * screen_scaling;
|
|
||||||
min_y = min_y * dc2s_scale_h * screen_scaling;
|
|
||||||
width *= dc2s_scale_h * screen_stretching * screen_scaling;
|
|
||||||
height *= dc2s_scale_h * screen_scaling;
|
|
||||||
|
|
||||||
baseScissor = vk::Rect2D(
|
baseScissor = vk::Rect2D(
|
||||||
vk::Offset2D((u32)std::max(lroundf(min_x), 0L), (u32)std::max(lroundf(min_y), 0L)),
|
vk::Offset2D((u32)std::max(lroundf(min_x), 0L), (u32)std::max(lroundf(min_y), 0L)),
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include "rend/sorter.h"
|
#include "rend/sorter.h"
|
||||||
|
#include "rend/transform_matrix.h"
|
||||||
#include "vulkan.h"
|
#include "vulkan.h"
|
||||||
#include "buffer.h"
|
#include "buffer.h"
|
||||||
#include "commandpool.h"
|
#include "commandpool.h"
|
||||||
|
@ -68,10 +69,7 @@ protected:
|
||||||
|
|
||||||
PipelineManager *pipelineManager = nullptr;
|
PipelineManager *pipelineManager = nullptr;
|
||||||
vk::Rect2D baseScissor;
|
vk::Rect2D baseScissor;
|
||||||
// temp stuff
|
TransformMatrix<false> matrices;
|
||||||
float scale_x = 1.f;
|
|
||||||
float scissor_scale_x = 1.f;
|
|
||||||
float scale_y = 1.f;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TileClipping SetTileClip(u32 val, vk::Rect2D& clipRect);
|
TileClipping SetTileClip(u32 val, vk::Rect2D& clipRect);
|
||||||
|
|
|
@ -319,7 +319,7 @@ void PipelineManager::CreatePipeline(u32 listType, bool sortTriangles, const Pol
|
||||||
vk::DynamicState dynamicStates[2] = { vk::DynamicState::eViewport, vk::DynamicState::eScissor };
|
vk::DynamicState dynamicStates[2] = { vk::DynamicState::eViewport, vk::DynamicState::eScissor };
|
||||||
vk::PipelineDynamicStateCreateInfo pipelineDynamicStateCreateInfo(vk::PipelineDynamicStateCreateFlags(), 2, dynamicStates);
|
vk::PipelineDynamicStateCreateInfo pipelineDynamicStateCreateInfo(vk::PipelineDynamicStateCreateFlags(), 2, dynamicStates);
|
||||||
|
|
||||||
vk::ShaderModule vertex_module = shaderManager->GetVertexShader(VertexShaderParams{ pp.pcw.Gouraud == 1, false }); // TODO rotate90
|
vk::ShaderModule vertex_module = shaderManager->GetVertexShader(VertexShaderParams{ pp.pcw.Gouraud == 1 });
|
||||||
FragmentShaderParams params = {};
|
FragmentShaderParams params = {};
|
||||||
params.alphaTest = listType == ListType_Punch_Through;
|
params.alphaTest = listType == ListType_Punch_Through;
|
||||||
params.bumpmap = pp.tcw.PixelFmt == PixelBumpMap;
|
params.bumpmap = pp.tcw.PixelFmt == PixelBumpMap;
|
||||||
|
|
|
@ -195,7 +195,6 @@ private:
|
||||||
| (pp->tsp.DstInstr << 17);
|
| (pp->tsp.DstInstr << 17);
|
||||||
hash |= (pp->isp.ZWriteDis << 20) | (pp->isp.CullMode << 21) | (pp->isp.DepthMode << 23);
|
hash |= (pp->isp.ZWriteDis << 20) | (pp->isp.CullMode << 21) | (pp->isp.DepthMode << 23);
|
||||||
hash |= (u32)sortTriangles << 26;
|
hash |= (u32)sortTriangles << 26;
|
||||||
// TODO hash |= (u32)rotate90 << 27;
|
|
||||||
|
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,6 @@ static const char VertexShaderSource[] = R"(
|
||||||
#extension GL_ARB_shading_language_420pack : enable
|
#extension GL_ARB_shading_language_420pack : enable
|
||||||
|
|
||||||
#define pp_Gouraud %d
|
#define pp_Gouraud %d
|
||||||
#define ROTATE_90 %d
|
|
||||||
|
|
||||||
#if pp_Gouraud == 0
|
#if pp_Gouraud == 0
|
||||||
#define INTERPOLATION flat
|
#define INTERPOLATION flat
|
||||||
|
@ -38,8 +37,7 @@ static const char VertexShaderSource[] = R"(
|
||||||
|
|
||||||
layout (std140, set = 0, binding = 0) uniform VertexShaderUniforms
|
layout (std140, set = 0, binding = 0) uniform VertexShaderUniforms
|
||||||
{
|
{
|
||||||
vec4 scale;
|
mat4 normal_matrix;
|
||||||
float extra_depth_scale;
|
|
||||||
} uniformBuffer;
|
} uniformBuffer;
|
||||||
|
|
||||||
layout (location = 0) in vec4 in_pos;
|
layout (location = 0) in vec4 in_pos;
|
||||||
|
@ -62,13 +60,9 @@ void main()
|
||||||
gl_Position = vec4(0.0, 0.0, 1.0, 1.0 / vpos.z);
|
gl_Position = vec4(0.0, 0.0, 1.0, 1.0 / vpos.z);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
vpos = uniformBuffer.normal_matrix * vpos;
|
||||||
vpos.w = uniformBuffer.extra_depth_scale / vpos.z;
|
vpos.w = 1.0 / vpos.z;
|
||||||
vpos.z = vpos.w;
|
vpos.z = vpos.w;
|
||||||
#if ROTATE_90 == 1
|
|
||||||
vpos.xy = vec2(vpos.y, -vpos.x);
|
|
||||||
#endif
|
|
||||||
vpos.xy = vpos.xy * uniformBuffer.scale.xy - uniformBuffer.scale.zw;
|
|
||||||
vpos.xy *= vpos.w;
|
vpos.xy *= vpos.w;
|
||||||
gl_Position = vpos;
|
gl_Position = vpos;
|
||||||
}
|
}
|
||||||
|
@ -252,8 +246,7 @@ static const char ModVolVertexShaderSource[] = R"(
|
||||||
|
|
||||||
layout (std140, set = 0, binding = 0) uniform VertexShaderUniforms
|
layout (std140, set = 0, binding = 0) uniform VertexShaderUniforms
|
||||||
{
|
{
|
||||||
vec4 scale;
|
mat4 normal_matrix;
|
||||||
float extra_depth_scale;
|
|
||||||
} uniformBuffer;
|
} uniformBuffer;
|
||||||
|
|
||||||
layout (location = 0) in vec4 in_pos;
|
layout (location = 0) in vec4 in_pos;
|
||||||
|
@ -267,9 +260,9 @@ void main()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
vpos.w = uniformBuffer.extra_depth_scale / vpos.z;
|
vpos = uniformBuffer.normal_matrix * vpos;
|
||||||
|
vpos.w = 1.0 / vpos.z;
|
||||||
vpos.z = vpos.w;
|
vpos.z = vpos.w;
|
||||||
vpos.xy = vpos.xy * uniformBuffer.scale.xy - uniformBuffer.scale.zw;
|
|
||||||
vpos.xy *= vpos.w;
|
vpos.xy *= vpos.w;
|
||||||
gl_Position = vpos;
|
gl_Position = vpos;
|
||||||
}
|
}
|
||||||
|
@ -542,7 +535,7 @@ vk::UniqueShaderModule ShaderManager::compileShader(const VertexShaderParams& pa
|
||||||
{
|
{
|
||||||
char buf[sizeof(VertexShaderSource) * 2];
|
char buf[sizeof(VertexShaderSource) * 2];
|
||||||
|
|
||||||
sprintf(buf, VertexShaderSource, (int)params.gouraud, (int)params.rotate90);
|
sprintf(buf, VertexShaderSource, (int)params.gouraud);
|
||||||
return createShaderModule(VulkanContext::Instance()->GetDevice(), vk::ShaderStageFlagBits::eVertex, buf);
|
return createShaderModule(VulkanContext::Instance()->GetDevice(), vk::ShaderStageFlagBits::eVertex, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,15 +19,15 @@
|
||||||
along with Flycast. If not, see <https://www.gnu.org/licenses/>.
|
along with Flycast. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
#include <glm/glm.hpp>
|
||||||
#include "vulkan.h"
|
#include "vulkan.h"
|
||||||
#include "SPIRV/GlslangToSpv.h"
|
#include "SPIRV/GlslangToSpv.h"
|
||||||
|
|
||||||
struct VertexShaderParams
|
struct VertexShaderParams
|
||||||
{
|
{
|
||||||
bool gouraud;
|
bool gouraud;
|
||||||
bool rotate90;
|
|
||||||
|
|
||||||
u32 hash() { return (((u32)gouraud) << 1) | rotate90; }
|
u32 hash() { return (u32)gouraud; }
|
||||||
};
|
};
|
||||||
|
|
||||||
// alpha test, clip test, use alpha, texture, ignore alpha, shader instr, offset, fog, gouraud, bump, clamp, trilinear
|
// alpha test, clip test, use alpha, texture, ignore alpha, shader instr, offset, fog, gouraud, bump, clamp, trilinear
|
||||||
|
@ -58,8 +58,7 @@ struct FragmentShaderParams
|
||||||
// std140 alignment required
|
// std140 alignment required
|
||||||
struct VertexShaderUniforms
|
struct VertexShaderUniforms
|
||||||
{
|
{
|
||||||
float scale[4];
|
glm::mat4 normal_matrix;
|
||||||
float extra_depth_scale;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// std140 alignment required
|
// std140 alignment required
|
||||||
|
|
|
@ -142,17 +142,23 @@ public:
|
||||||
curTexture->SetCommandBuffer(nullptr);
|
curTexture->SetCommandBuffer(nullptr);
|
||||||
texCommandPool.EndFrame();
|
texCommandPool.EndFrame();
|
||||||
|
|
||||||
float screen_stretching = settings.rend.ScreenStretching / 100.f;
|
TransformMatrix<false> matrices(pvrrc);
|
||||||
float dc2s_scale_h, ds2s_offs_x;
|
glm::vec4 viewport_min = matrices.GetViewportMatrix() * glm::vec4(0, 0, 0, 1.f);
|
||||||
if (settings.rend.Rotate90)
|
glm::vec4 viewport_dim = matrices.GetViewportMatrix() * glm::vec4(640.f, 480.f, 0, 0);
|
||||||
|
|
||||||
|
float min_x = viewport_min[0];
|
||||||
|
float min_y = viewport_min[1];
|
||||||
|
width = viewport_dim[0];
|
||||||
|
height = viewport_dim[1];
|
||||||
|
if (width < 0)
|
||||||
{
|
{
|
||||||
dc2s_scale_h = screen_height / 640.0f;
|
min_x += width;
|
||||||
ds2s_offs_x = (screen_width - dc2s_scale_h * 480.0f * screen_stretching) / 2;
|
width = -width;
|
||||||
}
|
}
|
||||||
else
|
if (height < 0)
|
||||||
{
|
{
|
||||||
dc2s_scale_h = screen_height / 480.0f;
|
min_y += height;
|
||||||
ds2s_offs_x = (screen_width - dc2s_scale_h * 640.0f * screen_stretching) / 2;
|
height = -height;
|
||||||
}
|
}
|
||||||
|
|
||||||
vk::CommandBuffer cmdBuffer = screenDrawer.BeginRenderPass();
|
vk::CommandBuffer cmdBuffer = screenDrawer.BeginRenderPass();
|
||||||
|
@ -165,9 +171,10 @@ public:
|
||||||
|
|
||||||
float blendConstants[4] = { 1.0, 1.0, 1.0, 1.0 };
|
float blendConstants[4] = { 1.0, 1.0, 1.0, 1.0 };
|
||||||
cmdBuffer.setBlendConstants(blendConstants);
|
cmdBuffer.setBlendConstants(blendConstants);
|
||||||
// FIXME scaling, stretching...
|
|
||||||
vk::Viewport viewport(ds2s_offs_x, 0.f, screen_width - ds2s_offs_x * 2, (float)screen_height);
|
vk::Viewport viewport(min_x, min_y, width, height);
|
||||||
cmdBuffer.setViewport(0, 1, &viewport);
|
cmdBuffer.setViewport(0, 1, &viewport);
|
||||||
|
cmdBuffer.setScissor(0, vk::Rect2D(vk::Offset2D(min_x, min_y), vk::Extent2D(width, height)));
|
||||||
cmdBuffer.draw(3, 1, 0, 0);
|
cmdBuffer.draw(3, 1, 0, 0);
|
||||||
|
|
||||||
gui_display_osd();
|
gui_display_osd();
|
||||||
|
@ -211,6 +218,7 @@ public:
|
||||||
|
|
||||||
void DrawOSD(bool clear_screen) override
|
void DrawOSD(bool clear_screen) override
|
||||||
{
|
{
|
||||||
|
gui_display_osd();
|
||||||
if (!vjoyTexture)
|
if (!vjoyTexture)
|
||||||
return;
|
return;
|
||||||
if (clear_screen)
|
if (clear_screen)
|
||||||
|
@ -218,22 +226,13 @@ public:
|
||||||
GetContext()->NewFrame();
|
GetContext()->NewFrame();
|
||||||
GetContext()->BeginRenderPass();
|
GetContext()->BeginRenderPass();
|
||||||
}
|
}
|
||||||
const float screen_stretching = settings.rend.ScreenStretching / 100.f;
|
const float dc2s_scale_h = screen_height / 480.0f;
|
||||||
float dc2s_scale_h, ds2s_offs_x;
|
const float sidebarWidth = (screen_width - dc2s_scale_h * 640.0f) / 2;
|
||||||
if (settings.rend.Rotate90)
|
|
||||||
{
|
|
||||||
dc2s_scale_h = screen_height / 640.0f;
|
|
||||||
ds2s_offs_x = (screen_width - dc2s_scale_h * 480.0f * screen_stretching) / 2;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
dc2s_scale_h = screen_height / 480.0f;
|
|
||||||
ds2s_offs_x = (screen_width - dc2s_scale_h * 640.0f * screen_stretching) / 2;
|
|
||||||
}
|
|
||||||
std::vector<OSDVertex> osdVertices = GetOSDVertices();
|
std::vector<OSDVertex> osdVertices = GetOSDVertices();
|
||||||
const float x1 = 2.0f / (screen_width / dc2s_scale_h /* FIXME * scale_x */) * screen_stretching;
|
const float x1 = 2.0f / (screen_width / dc2s_scale_h);
|
||||||
const float y1 = 2.0f / 480 /* FIXME dc_height */;
|
const float y1 = 2.0f / 480;
|
||||||
const float x2 = 1 - 2 * ds2s_offs_x / screen_width;
|
const float x2 = 1 - 2 * sidebarWidth / screen_width;
|
||||||
const float y2 = 1;
|
const float y2 = 1;
|
||||||
for (OSDVertex& vtx : osdVertices)
|
for (OSDVertex& vtx : osdVertices)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue