Scale down native resolution setting
This commit is contained in:
parent
e2c839dde3
commit
810182c4fe
|
@ -98,7 +98,7 @@ bool fb_dirty;
|
|||
TA_context* _pvrrc;
|
||||
void SetREP(TA_context* cntx);
|
||||
void killtex();
|
||||
bool render_last_frame();
|
||||
bool render_output_framebuffer();
|
||||
|
||||
void dump_frame(const char* file, TA_context* ctx, u8* vram, u8* vram_ref = NULL) {
|
||||
FILE* fw = fopen(file, "wb");
|
||||
|
@ -282,7 +282,7 @@ bool rend_single_frame()
|
|||
}
|
||||
else
|
||||
{
|
||||
render_last_frame();
|
||||
render_output_framebuffer();
|
||||
#if defined(_ANDROID)
|
||||
if (!rs.Wait(100))
|
||||
return false;
|
||||
|
|
|
@ -528,6 +528,7 @@ void InitSettings()
|
|||
settings.rend.ExtraDepthScale = 1.f;
|
||||
settings.rend.CustomTextures = false;
|
||||
settings.rend.DumpTextures = false;
|
||||
settings.rend.ScreenScaling = 100;
|
||||
|
||||
settings.pvr.ta_skip = 0;
|
||||
settings.pvr.rend = 0;
|
||||
|
@ -605,6 +606,8 @@ void LoadSettings(bool game_specific)
|
|||
}
|
||||
settings.rend.CustomTextures = cfgLoadBool(config_section, "rend.CustomTextures", settings.rend.CustomTextures);
|
||||
settings.rend.DumpTextures = cfgLoadBool(config_section, "rend.DumpTextures", settings.rend.DumpTextures);
|
||||
settings.rend.ScreenScaling = cfgLoadInt(config_section, "rend.ScreenScaling", settings.rend.ScreenScaling);
|
||||
settings.rend.ScreenScaling = min(max(1, settings.rend.ScreenScaling), 100);
|
||||
|
||||
settings.pvr.ta_skip = cfgLoadInt(config_section, "ta.skip", settings.pvr.ta_skip);
|
||||
settings.pvr.rend = cfgLoadInt(config_section, "pvr.rend", settings.pvr.rend);
|
||||
|
@ -705,6 +708,7 @@ void SaveSettings()
|
|||
cfgSaveInt("config", "rend.MaxFilteredTextureSize", settings.rend.MaxFilteredTextureSize);
|
||||
cfgSaveBool("config", "rend.CustomTextures", settings.rend.CustomTextures);
|
||||
cfgSaveBool("config", "rend.DumpTextures", settings.rend.DumpTextures);
|
||||
cfgSaveInt("config", "rend.ScreenScaling", settings.rend.ScreenScaling);
|
||||
cfgSaveInt("config", "ta.skip", settings.pvr.ta_skip);
|
||||
cfgSaveInt("config", "pvr.rend", settings.pvr.rend);
|
||||
|
||||
|
|
|
@ -686,9 +686,6 @@ static bool RenderFrame()
|
|||
|
||||
//printf("scale: %f, %f, %f, %f\n",gl4ShaderUniforms.scale_coefs[0],gl4ShaderUniforms.scale_coefs[1],gl4ShaderUniforms.scale_coefs[2],gl4ShaderUniforms.scale_coefs[3]);
|
||||
|
||||
if (!is_rtt)
|
||||
OSD_HOOK();
|
||||
|
||||
//VERT and RAM fog color constants
|
||||
u8* fog_colvert_bgra=(u8*)&FOG_COL_VERT;
|
||||
u8* fog_colram_bgra=(u8*)&FOG_COL_RAM;
|
||||
|
|
|
@ -3,12 +3,10 @@
|
|||
|
||||
GLuint gl4BindRTT(u32 addy, u32 fbw, u32 fbh, u32 channels, u32 fmt)
|
||||
{
|
||||
FBT& rv=fb_rtt;
|
||||
if (gl.rtt.fbo) glDeleteFramebuffers(1,&gl.rtt.fbo);
|
||||
if (gl.rtt.tex) glcache.DeleteTextures(1,&gl.rtt.tex);
|
||||
|
||||
if (rv.fbo) glDeleteFramebuffers(1,&rv.fbo);
|
||||
if (rv.tex) glcache.DeleteTextures(1,&rv.tex);
|
||||
|
||||
rv.TexAddr=addy>>3;
|
||||
gl.rtt.TexAddr=addy>>3;
|
||||
|
||||
// Find the smallest power of two texture that fits the viewport
|
||||
int fbh2 = 2;
|
||||
|
@ -29,17 +27,17 @@ GLuint gl4BindRTT(u32 addy, u32 fbw, u32 fbh, u32 channels, u32 fmt)
|
|||
//glGetIntegerv(GL_FRAMEBUFFER_BINDING, &m_i32OriginalFbo);
|
||||
|
||||
// Create a texture for rendering to
|
||||
rv.tex = glcache.GenTexture();
|
||||
glcache.BindTexture(GL_TEXTURE_2D, rv.tex);
|
||||
gl.rtt.tex = glcache.GenTexture();
|
||||
glcache.BindTexture(GL_TEXTURE_2D, gl.rtt.tex);
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, channels, fbw2, fbh2, 0, channels, fmt, 0);
|
||||
|
||||
// Create the object that will allow us to render to the aforementioned texture
|
||||
glGenFramebuffers(1, &rv.fbo);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, rv.fbo);
|
||||
glGenFramebuffers(1, &gl.rtt.fbo);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, gl.rtt.fbo);
|
||||
|
||||
// Attach the texture to the FBO
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rv.tex, 0);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, gl.rtt.tex, 0);
|
||||
|
||||
// Check that our FBO creation was successful
|
||||
GLuint uStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
||||
|
@ -48,5 +46,5 @@ GLuint gl4BindRTT(u32 addy, u32 fbw, u32 fbh, u32 channels, u32 fmt)
|
|||
|
||||
glViewport(0, 0, fbw, fbh); // TODO CLIP_X/Y min?
|
||||
|
||||
return rv.fbo;
|
||||
return gl.rtt.fbo;
|
||||
}
|
||||
|
|
|
@ -1150,41 +1150,17 @@ void DrawFramebuffer(float w, float h)
|
|||
fbTextureId = 0;
|
||||
}
|
||||
|
||||
void save_current_frame()
|
||||
void render_output_framebuffer()
|
||||
{
|
||||
#ifndef GLES
|
||||
glReadBuffer(GL_FRONT);
|
||||
#endif
|
||||
// (Re-)create the texture and reserve space for it
|
||||
if (g_previous_frame_tex != 0)
|
||||
glcache.DeleteTextures(1, &g_previous_frame_tex);
|
||||
glGenTextures(1, &g_previous_frame_tex);
|
||||
glBindTexture(GL_TEXTURE_2D, g_previous_frame_tex);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, screen_width, screen_height, 0, GL_RGB, GL_UNSIGNED_BYTE, (GLvoid*)NULL);
|
||||
|
||||
// Copy the current framebuffer into it
|
||||
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, screen_width, screen_height);
|
||||
glCheck();
|
||||
}
|
||||
|
||||
bool render_last_frame()
|
||||
{
|
||||
if (g_previous_frame_tex == 0)
|
||||
return false;
|
||||
|
||||
#if HOST_OS != OS_DARWIN
|
||||
//Fix this in a proper way
|
||||
glBindFramebuffer(GL_FRAMEBUFFER,0);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
#endif
|
||||
glViewport(0, 0, screen_width, screen_height);
|
||||
if (gl.ofbo.tex == 0)
|
||||
return;
|
||||
|
||||
float scl = 480.f / screen_height;
|
||||
float tx = (screen_width * scl - 640.f) / 2;
|
||||
DrawQuad(g_previous_frame_tex, -tx, 0, 640.f + tx * 2, 480.f, 0, 1, 1, 0);
|
||||
|
||||
return true;
|
||||
DrawQuad(gl.ofbo.tex, -tx, 0, 640.f + tx * 2, 480.f, 0, 1, 1, 0);
|
||||
}
|
||||
|
|
|
@ -751,7 +751,7 @@ void gl_term()
|
|||
|
||||
memset(gl.pogram_table, 0, sizeof(gl.pogram_table));
|
||||
|
||||
#if HOST_OS==OS_WINDOWS
|
||||
#if HOST_OS==OS_WINDOWS
|
||||
ReleaseDC((HWND)gl.setup.native_wind,(HDC)gl.setup.native_disp);
|
||||
#elif defined(TARGET_PANDORA) || defined(_ANDROID)
|
||||
eglMakeCurrent(gl.setup.display, NULL, NULL, EGL_NO_CONTEXT);
|
||||
|
@ -1247,10 +1247,6 @@ extern u8 rt[4],lt[4];
|
|||
#define key_CONT_DPAD2_LEFT (1 << 14)
|
||||
#define key_CONT_DPAD2_RIGHT (1 << 15)
|
||||
|
||||
u32 osd_base;
|
||||
u32 osd_count;
|
||||
|
||||
|
||||
#if defined(_ANDROID)
|
||||
extern float vjoy_pos[14][8];
|
||||
#else
|
||||
|
@ -1278,7 +1274,10 @@ float vjoy_pos[14][8]=
|
|||
};
|
||||
#endif // !_ANDROID
|
||||
|
||||
float vjoy_sz[2][14] = {
|
||||
static List<Vertex> osd_vertices;
|
||||
static bool osd_vertices_overrun;
|
||||
|
||||
static const float vjoy_sz[2][14] = {
|
||||
{ 64,64,64,64, 64,64,64,64, 64, 90,90, 128, 64 },
|
||||
{ 64,64,64,64, 64,64,64,64, 64, 64,64, 128, 64 },
|
||||
};
|
||||
|
@ -1312,63 +1311,48 @@ static void DrawButton(float* xy, u32 state)
|
|||
|
||||
vtx.x=x; vtx.y=y;
|
||||
vtx.u=xy[4]; vtx.v=xy[5];
|
||||
*pvrrc.verts.Append()=vtx;
|
||||
*osd_vertices.Append() = vtx;
|
||||
|
||||
vtx.x=x+w; vtx.y=y;
|
||||
vtx.u=xy[6]; vtx.v=xy[5];
|
||||
*pvrrc.verts.Append()=vtx;
|
||||
*osd_vertices.Append() = vtx;
|
||||
|
||||
vtx.x=x; vtx.y=y+h;
|
||||
vtx.u=xy[4]; vtx.v=xy[7];
|
||||
*pvrrc.verts.Append()=vtx;
|
||||
*osd_vertices.Append() = vtx;
|
||||
|
||||
vtx.x=x+w; vtx.y=y+h;
|
||||
vtx.u=xy[6]; vtx.v=xy[7];
|
||||
*pvrrc.verts.Append()=vtx;
|
||||
|
||||
osd_count+=4;
|
||||
*osd_vertices.Append() = vtx;
|
||||
}
|
||||
|
||||
static void ClearBG()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
void DrawButton2(float* xy, bool state) { DrawButton(xy,state?0:255); }
|
||||
static void DrawButton2(float* xy, bool state) { DrawButton(xy,state?0:255); }
|
||||
|
||||
static float LastFPSTime;
|
||||
static int lastFrameCount = 0;
|
||||
static float fps = -1;
|
||||
|
||||
void OSD_HOOK()
|
||||
static void osd_gen_vertices()
|
||||
{
|
||||
osd_base=pvrrc.verts.used();
|
||||
osd_count=0;
|
||||
osd_vertices.Init(ARRAY_SIZE(vjoy_pos) * 4, &osd_vertices_overrun, "OSD vertices");
|
||||
DrawButton2(vjoy_pos[0],kcode[0]&key_CONT_DPAD_LEFT);
|
||||
DrawButton2(vjoy_pos[1],kcode[0]&key_CONT_DPAD_UP);
|
||||
DrawButton2(vjoy_pos[2],kcode[0]&key_CONT_DPAD_RIGHT);
|
||||
DrawButton2(vjoy_pos[3],kcode[0]&key_CONT_DPAD_DOWN);
|
||||
|
||||
#ifndef TARGET_PANDORA
|
||||
if (osd_tex)
|
||||
{
|
||||
DrawButton2(vjoy_pos[0],kcode[0]&key_CONT_DPAD_LEFT);
|
||||
DrawButton2(vjoy_pos[1],kcode[0]&key_CONT_DPAD_UP);
|
||||
DrawButton2(vjoy_pos[2],kcode[0]&key_CONT_DPAD_RIGHT);
|
||||
DrawButton2(vjoy_pos[3],kcode[0]&key_CONT_DPAD_DOWN);
|
||||
DrawButton2(vjoy_pos[4],kcode[0]&key_CONT_X);
|
||||
DrawButton2(vjoy_pos[5],kcode[0]&key_CONT_Y);
|
||||
DrawButton2(vjoy_pos[6],kcode[0]&key_CONT_B);
|
||||
DrawButton2(vjoy_pos[7],kcode[0]&key_CONT_A);
|
||||
|
||||
DrawButton2(vjoy_pos[4],kcode[0]&key_CONT_X);
|
||||
DrawButton2(vjoy_pos[5],kcode[0]&key_CONT_Y);
|
||||
DrawButton2(vjoy_pos[6],kcode[0]&key_CONT_B);
|
||||
DrawButton2(vjoy_pos[7],kcode[0]&key_CONT_A);
|
||||
DrawButton2(vjoy_pos[8],kcode[0]&key_CONT_START);
|
||||
|
||||
DrawButton2(vjoy_pos[8],kcode[0]&key_CONT_START);
|
||||
DrawButton(vjoy_pos[9],lt[0]);
|
||||
|
||||
DrawButton(vjoy_pos[9],lt[0]);
|
||||
DrawButton(vjoy_pos[10],rt[0]);
|
||||
|
||||
DrawButton(vjoy_pos[10],rt[0]);
|
||||
|
||||
DrawButton2(vjoy_pos[11],1);
|
||||
DrawButton2(vjoy_pos[12],0);
|
||||
}
|
||||
#endif
|
||||
DrawButton2(vjoy_pos[11],1);
|
||||
DrawButton2(vjoy_pos[12],0);
|
||||
}
|
||||
|
||||
#define OSD_TEX_W 512
|
||||
|
@ -1376,9 +1360,11 @@ void OSD_HOOK()
|
|||
|
||||
void OSD_DRAW(GLuint shader_program)
|
||||
{
|
||||
#ifndef TARGET_PANDORA
|
||||
#ifndef TARGET_PANDORA
|
||||
if (osd_tex)
|
||||
{
|
||||
osd_gen_vertices();
|
||||
|
||||
float u=0;
|
||||
float v=0;
|
||||
|
||||
|
@ -1405,22 +1391,7 @@ void OSD_DRAW(GLuint shader_program)
|
|||
glcache.BindTexture(GL_TEXTURE_2D, osd_tex);
|
||||
glcache.UseProgram(shader_program);
|
||||
|
||||
//reset rendering scale
|
||||
/*
|
||||
float dc_width=640;
|
||||
float dc_height=480;
|
||||
|
||||
float dc2s_scale_h=screen_height/480.0f;
|
||||
float ds2s_offs_x=(screen_width-dc2s_scale_h*640)/2;
|
||||
|
||||
//-1 -> too much to left
|
||||
ShaderUniforms.scale_coefs[0]=2.0f/(screen_width/dc2s_scale_h);
|
||||
ShaderUniforms.scale_coefs[1]=-2/dc_height;
|
||||
ShaderUniforms.scale_coefs[2]=1-2*ds2s_offs_x/(screen_width);
|
||||
ShaderUniforms.scale_coefs[3]=-1;
|
||||
|
||||
glUniform4fv( gl.OSD_SHADER.scale, 1, ShaderUniforms.scale_coefs);
|
||||
*/
|
||||
glBufferData(GL_ARRAY_BUFFER, osd_vertices.bytes(), osd_vertices.head(), GL_STREAM_DRAW);
|
||||
|
||||
glcache.Enable(GL_BLEND);
|
||||
glcache.Disable(GL_DEPTH_TEST);
|
||||
|
@ -1432,10 +1403,10 @@ void OSD_DRAW(GLuint shader_program)
|
|||
glcache.Disable(GL_CULL_FACE);
|
||||
glcache.Disable(GL_SCISSOR_TEST);
|
||||
|
||||
int dfa=osd_count/4;
|
||||
int dfa = osd_vertices.used() / 4;
|
||||
|
||||
for (int i=0;i<dfa;i++)
|
||||
glDrawArrays(GL_TRIANGLE_STRIP,osd_base+i*4,4);
|
||||
for (int i = 0; i < dfa; i++)
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, i * 4, 4);
|
||||
}
|
||||
#endif
|
||||
if (settings.rend.ShowFPS)
|
||||
|
@ -1503,9 +1474,6 @@ bool RenderFrame()
|
|||
|
||||
bool is_rtt=pvrrc.isRTT;
|
||||
|
||||
if (!is_rtt)
|
||||
OSD_HOOK();
|
||||
|
||||
//if (FrameCount&7) return;
|
||||
|
||||
//Setup the matrix
|
||||
|
@ -1669,14 +1637,16 @@ bool RenderFrame()
|
|||
/*
|
||||
Handle Dc to screen scaling
|
||||
*/
|
||||
float screen_scaling = is_rtt ? 1.f : settings.rend.ScreenScaling / 100.f;
|
||||
float dc2s_scale_h = is_rtt ? (screen_width / dc_width) : (screen_height / 480.0);
|
||||
float ds2s_offs_x = is_rtt ? 0 : ((screen_width - dc2s_scale_h * 640.0) / 2);
|
||||
dc2s_scale_h *= screen_scaling;
|
||||
float ds2s_offs_x = is_rtt ? 0 : (((screen_width * screen_scaling) - dc2s_scale_h * 640.0) / 2);
|
||||
|
||||
//-1 -> too much to left
|
||||
ShaderUniforms.scale_coefs[0]=2.0f/(screen_width/dc2s_scale_h*scale_x);
|
||||
ShaderUniforms.scale_coefs[1]=(is_rtt ? 2 : -2) / dc_height; // FIXME CT2 needs 480 here instead of dc_height=512
|
||||
ShaderUniforms.scale_coefs[2]=1-2*ds2s_offs_x/(screen_width);
|
||||
ShaderUniforms.scale_coefs[3]=(is_rtt?1:-1);
|
||||
ShaderUniforms.scale_coefs[0] = 2.0f / (screen_width * screen_scaling / dc2s_scale_h * scale_x);
|
||||
ShaderUniforms.scale_coefs[1]= (is_rtt ? 2 : -2) / dc_height; // FIXME CT2 needs 480 here instead of dc_height=512
|
||||
ShaderUniforms.scale_coefs[2]= 1 - 2 * ds2s_offs_x / (screen_width * screen_scaling);
|
||||
ShaderUniforms.scale_coefs[3]= (is_rtt ? 1 : -1);
|
||||
|
||||
|
||||
ShaderUniforms.depth_coefs[0]=2/(vtx_max_fZ-vtx_min_fZ);
|
||||
|
@ -1789,11 +1759,18 @@ bool RenderFrame()
|
|||
}
|
||||
else
|
||||
{
|
||||
if (settings.rend.ScreenScaling != 100 || gl.swap_buffer_not_preserved)
|
||||
{
|
||||
init_output_framebuffer(screen_width * settings.rend.ScreenScaling / 100, screen_height * settings.rend.ScreenScaling / 100);
|
||||
}
|
||||
else
|
||||
{
|
||||
#if HOST_OS != OS_DARWIN
|
||||
//Fix this in a proper way
|
||||
glBindFramebuffer(GL_FRAMEBUFFER,0);
|
||||
//Fix this in a proper way
|
||||
glBindFramebuffer(GL_FRAMEBUFFER,0);
|
||||
#endif
|
||||
glViewport(0, 0, screen_width, screen_height);
|
||||
glViewport(0, 0, screen_width, screen_height);
|
||||
}
|
||||
}
|
||||
|
||||
bool wide_screen_on = !is_rtt && settings.rend.WideScreen
|
||||
|
@ -1892,8 +1869,6 @@ bool RenderFrame()
|
|||
{
|
||||
glcache.ClearColor(0.f, 0.f, 0.f, 0.f);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, gl.vbo.geometry); glCheck();
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, gl.vbo.idxs); glCheck();
|
||||
DrawFramebuffer(dc_width, dc_height);
|
||||
glBufferData(GL_ARRAY_BUFFER, pvrrc.verts.bytes(), pvrrc.verts.head(), GL_STREAM_DRAW);
|
||||
upload_vertex_indices();
|
||||
|
@ -1908,8 +1883,8 @@ bool RenderFrame()
|
|||
|
||||
if (is_rtt)
|
||||
ReadRTTBuffer();
|
||||
else if (gl.swap_buffer_not_preserved)
|
||||
save_current_frame();
|
||||
else if (settings.rend.ScreenScaling != 100 || gl.swap_buffer_not_preserved)
|
||||
render_output_framebuffer();
|
||||
|
||||
return !is_rtt;
|
||||
}
|
||||
|
|
|
@ -116,6 +116,23 @@ struct gl_ctx
|
|||
#endif
|
||||
} vbo;
|
||||
|
||||
struct
|
||||
{
|
||||
u32 TexAddr;
|
||||
GLuint depthb;
|
||||
GLuint tex;
|
||||
GLuint fbo;
|
||||
} rtt;
|
||||
|
||||
struct
|
||||
{
|
||||
GLuint depthb;
|
||||
GLuint tex;
|
||||
GLuint fbo;
|
||||
int width;
|
||||
int height;
|
||||
} ofbo;
|
||||
|
||||
const char *gl_version;
|
||||
const char *glsl_version_header;
|
||||
int gl_major;
|
||||
|
@ -148,8 +165,6 @@ void gl_free_osd_resources();
|
|||
void gl_swap();
|
||||
bool ProcessFrame(TA_context* ctx);
|
||||
void UpdateFogTexture(u8 *fog_table, GLenum texture_slot, GLint fog_image_format);
|
||||
void save_current_frame();
|
||||
bool render_last_frame();
|
||||
|
||||
text_info raw_GetTexture(TSP tsp, TCW tcw);
|
||||
void killtex();
|
||||
|
@ -164,9 +179,10 @@ void BindRTT(u32 addy, u32 fbw, u32 fbh, u32 channels, u32 fmt);
|
|||
void ReadRTTBuffer();
|
||||
void RenderFramebuffer();
|
||||
void DrawFramebuffer(float w, float h);
|
||||
void init_output_framebuffer(int width, int height);
|
||||
void render_output_framebuffer();
|
||||
|
||||
void HideOSD();
|
||||
void OSD_HOOK();
|
||||
void OSD_DRAW(GLuint shader_program);
|
||||
int GetProgramID(u32 cp_AlphaTest, u32 pp_ClipTestMode,
|
||||
u32 pp_Texture, u32 pp_UseAlpha, u32 pp_IgnoreTexA, u32 pp_ShadInstr, u32 pp_Offset,
|
||||
|
@ -226,17 +242,6 @@ extern struct ShaderUniforms_t
|
|||
|
||||
} ShaderUniforms;
|
||||
|
||||
// Render to texture
|
||||
struct FBT
|
||||
{
|
||||
u32 TexAddr;
|
||||
GLuint depthb,stencilb;
|
||||
GLuint tex;
|
||||
GLuint fbo;
|
||||
};
|
||||
|
||||
extern FBT fb_rtt;
|
||||
|
||||
struct PvrTexInfo;
|
||||
template <class pixel_type> class PixelBuffer;
|
||||
typedef void TexConvFP(PixelBuffer<u16>* pb,u8* p_in,u32 Width,u32 Height);
|
||||
|
|
|
@ -481,18 +481,13 @@ typedef map<u64,TextureCacheData>::iterator TexCacheIter;
|
|||
|
||||
TextureCacheData *getTextureCacheData(TSP tsp, TCW tcw);
|
||||
|
||||
FBT fb_rtt;
|
||||
|
||||
void BindRTT(u32 addy, u32 fbw, u32 fbh, u32 channels, u32 fmt)
|
||||
{
|
||||
FBT& rv=fb_rtt;
|
||||
if (gl.rtt.fbo) glDeleteFramebuffers(1,&gl.rtt.fbo);
|
||||
if (gl.rtt.tex) glcache.DeleteTextures(1,&gl.rtt.tex);
|
||||
if (gl.rtt.depthb) glDeleteRenderbuffers(1,&gl.rtt.depthb);
|
||||
|
||||
if (rv.fbo) glDeleteFramebuffers(1,&rv.fbo);
|
||||
if (rv.tex) glcache.DeleteTextures(1,&rv.tex);
|
||||
if (rv.depthb) glDeleteRenderbuffers(1,&rv.depthb);
|
||||
if (rv.stencilb) glDeleteRenderbuffers(1,&rv.stencilb);
|
||||
|
||||
rv.TexAddr=addy>>3;
|
||||
gl.rtt.TexAddr=addy>>3;
|
||||
|
||||
// Find the smallest power of two texture that fits into the viewport
|
||||
int fbh2 = 2;
|
||||
|
@ -513,8 +508,8 @@ void BindRTT(u32 addy, u32 fbw, u32 fbh, u32 channels, u32 fmt)
|
|||
//glGetIntegerv(GL_FRAMEBUFFER_BINDING, &m_i32OriginalFbo);
|
||||
|
||||
// Generate and bind a render buffer which will become a depth buffer shared between our two FBOs
|
||||
glGenRenderbuffers(1, &rv.depthb);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, rv.depthb);
|
||||
glGenRenderbuffers(1, &gl.rtt.depthb);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, gl.rtt.depthb);
|
||||
|
||||
/*
|
||||
Currently it is unknown to GL that we want our new render buffer to be a depth buffer.
|
||||
|
@ -534,8 +529,8 @@ void BindRTT(u32 addy, u32 fbw, u32 fbh, u32 channels, u32 fmt)
|
|||
#endif
|
||||
|
||||
// Create a texture for rendering to
|
||||
rv.tex = glcache.GenTexture();
|
||||
glcache.BindTexture(GL_TEXTURE_2D, rv.tex);
|
||||
gl.rtt.tex = glcache.GenTexture();
|
||||
glcache.BindTexture(GL_TEXTURE_2D, gl.rtt.tex);
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, channels, fbw2, fbh2, 0, channels, fmt, 0);
|
||||
glcache.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
|
@ -543,19 +538,19 @@ void BindRTT(u32 addy, u32 fbw, u32 fbh, u32 channels, u32 fmt)
|
|||
glcache.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glcache.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
// Create the object that will allow us to render to the aforementioned texture
|
||||
glGenFramebuffers(1, &rv.fbo);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, rv.fbo);
|
||||
glGenFramebuffers(1, &gl.rtt.fbo);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, gl.rtt.fbo);
|
||||
|
||||
// Attach the texture to the FBO
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rv.tex, 0);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, gl.rtt.tex, 0);
|
||||
|
||||
// Attach the depth buffer we created earlier to our FBO.
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rv.depthb);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, gl.rtt.depthb);
|
||||
|
||||
#ifdef GLES
|
||||
if (gl.GL_OES_packed_depth_stencil_supported)
|
||||
#endif
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rv.depthb);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, gl.rtt.depthb);
|
||||
|
||||
// Check that our FBO creation was successful
|
||||
GLuint uStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
||||
|
@ -582,7 +577,7 @@ void ReadRTTBuffer() {
|
|||
|
||||
if (settings.rend.RenderToTextureBuffer)
|
||||
{
|
||||
u32 tex_addr = fb_rtt.TexAddr << 3;
|
||||
u32 tex_addr = gl.rtt.TexAddr << 3;
|
||||
|
||||
// Manually mark textures as dirty and remove all vram locks before calling glReadPixels
|
||||
// (deadlock on rpi)
|
||||
|
@ -673,12 +668,12 @@ void ReadRTTBuffer() {
|
|||
//dumpRtTexture(fb_rtt.TexAddr, w, h);
|
||||
|
||||
if (w > 1024 || h > 1024 || settings.rend.RenderToTextureBuffer) {
|
||||
glcache.DeleteTextures(1, &fb_rtt.tex);
|
||||
glcache.DeleteTextures(1, &gl.rtt.tex);
|
||||
}
|
||||
else
|
||||
{
|
||||
// TexAddr : fb_rtt.TexAddr, Reserved : 0, StrideSel : 0, ScanOrder : 1
|
||||
TCW tcw = { { fb_rtt.TexAddr, 0, 0, 1 } };
|
||||
TCW tcw = { { gl.rtt.TexAddr, 0, 0, 1 } };
|
||||
switch (fb_packmode) {
|
||||
case 0:
|
||||
case 3:
|
||||
|
@ -700,16 +695,15 @@ void ReadRTTBuffer() {
|
|||
glcache.DeleteTextures(1, &texture_data->texID);
|
||||
else
|
||||
texture_data->Create(false);
|
||||
texture_data->texID = fb_rtt.tex;
|
||||
texture_data->texID = gl.rtt.tex;
|
||||
texture_data->dirty = 0;
|
||||
if (texture_data->lock_block == NULL)
|
||||
texture_data->lock_block = libCore_vramlock_Lock(texture_data->sa_tex, texture_data->sa + texture_data->size - 1, texture_data);
|
||||
}
|
||||
fb_rtt.tex = 0;
|
||||
gl.rtt.tex = 0;
|
||||
|
||||
if (fb_rtt.fbo) { glDeleteFramebuffers(1,&fb_rtt.fbo); fb_rtt.fbo = 0; }
|
||||
if (fb_rtt.depthb) { glDeleteRenderbuffers(1,&fb_rtt.depthb); fb_rtt.depthb = 0; }
|
||||
if (fb_rtt.stencilb) { glDeleteRenderbuffers(1,&fb_rtt.stencilb); fb_rtt.stencilb = 0; }
|
||||
if (gl.rtt.fbo) { glDeleteFramebuffers(1,&gl.rtt.fbo); gl.rtt.fbo = 0; }
|
||||
if (gl.rtt.depthb) { glDeleteRenderbuffers(1,&gl.rtt.depthb); gl.rtt.depthb = 0; }
|
||||
|
||||
}
|
||||
|
||||
|
@ -1012,3 +1006,69 @@ void RenderFramebuffer()
|
|||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pb.data());
|
||||
}
|
||||
|
||||
void init_output_framebuffer(int width, int height)
|
||||
{
|
||||
if (width != gl.ofbo.width || height != gl.ofbo.height)
|
||||
{
|
||||
if (gl.ofbo.fbo != 0)
|
||||
{
|
||||
glDeleteFramebuffers(1, &gl.ofbo.fbo);
|
||||
gl.ofbo.fbo = 0;
|
||||
glDeleteRenderbuffers(1, &gl.ofbo.depthb);
|
||||
glcache.DeleteTextures(1, &gl.ofbo.tex);
|
||||
}
|
||||
gl.ofbo.width = width;
|
||||
gl.ofbo.height = height;
|
||||
}
|
||||
if (gl.ofbo.fbo == 0)
|
||||
{
|
||||
// Create the depth+stencil renderbuffer
|
||||
glGenRenderbuffers(1, &gl.ofbo.depthb);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, gl.ofbo.depthb);
|
||||
|
||||
#ifdef GLES
|
||||
if (gl.GL_OES_packed_depth_stencil_supported)
|
||||
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, width, height);
|
||||
else if (gl.GL_OES_depth24_supported)
|
||||
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24_OES, width, height);
|
||||
else
|
||||
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, width, height);
|
||||
#else
|
||||
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, width, height);
|
||||
#endif
|
||||
// Create a texture for rendering to
|
||||
gl.ofbo.tex = glcache.GenTexture();
|
||||
glcache.BindTexture(GL_TEXTURE_2D, gl.ofbo.tex);
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
|
||||
glcache.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glcache.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glcache.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glcache.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
|
||||
// Create the framebuffer
|
||||
glGenFramebuffers(1, &gl.ofbo.fbo);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, gl.ofbo.fbo);
|
||||
|
||||
// Attach the depth buffer to our FBO.
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, gl.ofbo.depthb);
|
||||
|
||||
#ifdef GLES
|
||||
if (gl.GL_OES_packed_depth_stencil_supported)
|
||||
#endif
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, gl.ofbo.depthb);
|
||||
|
||||
// Attach the texture to the FBO
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, gl.ofbo.tex, 0);
|
||||
|
||||
// Check that our FBO creation was successful
|
||||
GLuint uStatus = glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
||||
|
||||
verify(uStatus == GL_FRAMEBUFFER_COMPLETE);
|
||||
}
|
||||
else
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, gl.ofbo.fbo);
|
||||
|
||||
glViewport(0, 0, width, height);
|
||||
glCheck();
|
||||
}
|
||||
|
|
|
@ -799,6 +799,9 @@ static void gui_display_settings()
|
|||
ImGui::Checkbox("Show FPS Counter", &settings.rend.ShowFPS);
|
||||
ImGui::SameLine();
|
||||
ShowHelpMarker("Show on-screen frame/sec counter");
|
||||
ImGui::SliderInt("Scaling", (int *)&settings.rend.ScreenScaling, 1, 100);
|
||||
ImGui::SameLine();
|
||||
ShowHelpMarker("Downscaling factor relative to native screen resolution. Higher is better");
|
||||
ImGui::SliderInt("Frame Skipping", (int *)&settings.pvr.ta_skip, 0, 6);
|
||||
ImGui::SameLine();
|
||||
ShowHelpMarker("Number of frames to skip between two actually rendered frames");
|
||||
|
|
|
@ -726,6 +726,7 @@ struct settings_t
|
|||
f32 ExtraDepthScale;
|
||||
bool CustomTextures;
|
||||
bool DumpTextures;
|
||||
int ScreenScaling; // in percent. 50 means half the native resolution
|
||||
} rend;
|
||||
|
||||
struct
|
||||
|
|
Loading…
Reference in New Issue