mirror of
https://github.com/CTCaer/RetroArch.git
synced 2025-01-31 08:33:40 +00:00
FBO seems to work! :D
This commit is contained in:
parent
41b2af66d5
commit
b541c27226
150
gfx/gl.c
150
gfx/gl.c
@ -25,6 +25,7 @@
|
||||
#include <string.h>
|
||||
#include "general.h"
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
@ -85,12 +86,16 @@ typedef struct gl
|
||||
GLuint texture;
|
||||
GLuint tex_filter;
|
||||
|
||||
// Render-to-texture
|
||||
// Render-to-texture, multipass shaders
|
||||
GLuint fbo;
|
||||
GLuint fbo_texture;
|
||||
bool render_to_tex;
|
||||
unsigned fbo_width;
|
||||
unsigned fbo_height;
|
||||
bool fbo_inited;
|
||||
bool fbo_tex_filter;
|
||||
double fbo_scale_x;
|
||||
double fbo_scale_y;
|
||||
|
||||
bool should_resize;
|
||||
bool quitting;
|
||||
@ -106,6 +111,7 @@ typedef struct gl
|
||||
unsigned last_height;
|
||||
unsigned tex_w, tex_h;
|
||||
GLfloat tex_coords[8];
|
||||
GLfloat fbo_tex_coords[8];
|
||||
|
||||
#ifdef HAVE_FREETYPE
|
||||
font_renderer_t *font;
|
||||
@ -159,25 +165,14 @@ static bool gl_shader_init(void)
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline void gl_shader_deactivate(void)
|
||||
static inline void gl_shader_use(unsigned index)
|
||||
{
|
||||
#ifdef HAVE_CG
|
||||
gl_cg_deactivate();
|
||||
gl_cg_use(index);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_XML
|
||||
gl_glsl_deactivate();
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void gl_shader_activate(void)
|
||||
{
|
||||
#ifdef HAVE_CG
|
||||
gl_cg_activate();
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_XML
|
||||
gl_glsl_activate();
|
||||
gl_glsl_use(index);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -240,17 +235,40 @@ static inline void gl_init_font(gl_t *gl, const char *font_path, unsigned font_s
|
||||
#endif
|
||||
}
|
||||
|
||||
static bool gl_init_fbo(gl_t *gl, unsigned fbo_width, unsigned fbo_height)
|
||||
static inline unsigned next_pow_2(unsigned v)
|
||||
{
|
||||
gl->fbo_width = fbo_width;
|
||||
gl->fbo_height = fbo_height;
|
||||
v--;
|
||||
v |= v >> 1;
|
||||
v |= v >> 2;
|
||||
v |= v >> 4;
|
||||
v |= v >> 8;
|
||||
v |= v >> 16;
|
||||
v++;
|
||||
return v;
|
||||
}
|
||||
|
||||
static void gl_init_fbo(gl_t *gl, unsigned width, unsigned height)
|
||||
{
|
||||
if (!g_settings.video.render_to_texture)
|
||||
return;
|
||||
|
||||
float scale_x = g_settings.video.fbo_scale_x;
|
||||
float scale_y = g_settings.video.fbo_scale_y;
|
||||
unsigned xscale = next_pow_2(ceil(scale_x));
|
||||
unsigned yscale = next_pow_2(ceil(scale_y));
|
||||
SSNES_LOG("Internal FBO scale: (%u, %u)\n", xscale, yscale);
|
||||
|
||||
gl->fbo_width = width * xscale;
|
||||
gl->fbo_height = height * yscale;
|
||||
gl->fbo_scale_x = scale_x;
|
||||
gl->fbo_scale_y = scale_y;
|
||||
|
||||
glGenTextures(1, &gl->fbo_texture);
|
||||
glBindTexture(GL_TEXTURE_2D, gl->fbo_texture);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, g_settings.video.second_pass_smooth ? GL_LINEAR : GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, g_settings.video.second_pass_smooth ? GL_LINEAR : GL_NEAREST);
|
||||
|
||||
void *tmp = calloc(gl->fbo_width * gl->fbo_height, sizeof(uint32_t));
|
||||
glTexImage2D(GL_TEXTURE_2D,
|
||||
@ -264,8 +282,17 @@ static bool gl_init_fbo(gl_t *gl, unsigned fbo_width, unsigned fbo_height)
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, gl->fbo_texture, 0);
|
||||
|
||||
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
||||
assert(status == GL_FRAMEBUFFER_COMPLETE);
|
||||
return true;
|
||||
if (status == GL_FRAMEBUFFER_COMPLETE)
|
||||
{
|
||||
gl->fbo_inited = true;
|
||||
SSNES_LOG("Set up FBO @ %ux%u\n", gl->fbo_width, gl->fbo_height);
|
||||
}
|
||||
else
|
||||
{
|
||||
glDeleteTextures(1, &gl->fbo_texture);
|
||||
glDeleteFramebuffers(1, &gl->fbo);
|
||||
SSNES_WARN("Failed to set up FBO. Two-pass shading will not work.\n");
|
||||
}
|
||||
}
|
||||
|
||||
static inline void gl_deinit_font(gl_t *gl)
|
||||
@ -299,7 +326,7 @@ static void gl_render_msg(gl_t *gl, const char *msg)
|
||||
GLfloat font_vertex[12];
|
||||
|
||||
// Deactivate custom shaders. Enable the font texture.
|
||||
gl_shader_deactivate();
|
||||
gl_shader_use(0);
|
||||
glBindTexture(GL_TEXTURE_2D, gl->font_tex);
|
||||
glVertexPointer(3, GL_FLOAT, 3 * sizeof(GLfloat), font_vertex);
|
||||
glTexCoordPointer(2, GL_FLOAT, 2 * sizeof(GLfloat), tex_coords); // Use the static one (uses whole texture).
|
||||
@ -346,19 +373,17 @@ static void gl_render_msg(gl_t *gl, const char *msg)
|
||||
glVertexPointer(3, GL_FLOAT, 3 * sizeof(GLfloat), vertexes);
|
||||
glBindTexture(GL_TEXTURE_2D, gl->texture);
|
||||
glDisable(GL_BLEND);
|
||||
gl_shader_activate();
|
||||
#endif
|
||||
}
|
||||
//////////////
|
||||
|
||||
static void set_viewport(gl_t *gl)
|
||||
static void set_viewport(gl_t *gl, unsigned width, unsigned height, bool force_full)
|
||||
{
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
GLuint out_width = gl->render_to_tex ? gl->fbo_width : gl->win_width;
|
||||
GLuint out_height = gl->render_to_tex ? gl->fbo_height : gl->win_height;
|
||||
GLuint out_width = width;
|
||||
GLuint out_height = height;
|
||||
|
||||
if (gl->keep_aspect && !gl->render_to_tex)
|
||||
if (gl->keep_aspect && !force_full)
|
||||
{
|
||||
float desired_aspect = g_settings.video.aspect_ratio;
|
||||
float device_aspect = (float)gl->win_width / gl->win_height;
|
||||
@ -429,21 +454,27 @@ static bool gl_frame(void *data, const uint16_t* frame, unsigned width, unsigned
|
||||
{
|
||||
gl_t *gl = data;
|
||||
|
||||
// Render to texture in first pass.
|
||||
glBindTexture(GL_TEXTURE_2D, gl->texture);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, gl->fbo);
|
||||
gl->render_to_tex = true;
|
||||
gl_shader_use(1);
|
||||
|
||||
// Render to texture in first pass.
|
||||
if (gl->fbo_inited)
|
||||
{
|
||||
glBindTexture(GL_TEXTURE_2D, gl->texture);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, gl->fbo);
|
||||
gl->render_to_tex = true;
|
||||
set_viewport(gl, width * gl->fbo_scale_x, height * gl->fbo_scale_y, true);
|
||||
}
|
||||
if (gl->should_resize)
|
||||
{
|
||||
gl->should_resize = false;
|
||||
SDL_SetVideoMode(gl->win_width, gl->win_height, 0, SDL_OPENGL | SDL_RESIZABLE | (g_settings.video.fullscreen ? SDL_FULLSCREEN : 0));
|
||||
|
||||
if (!gl->render_to_tex)
|
||||
set_viewport(gl, gl->win_width, gl->win_height, false);
|
||||
}
|
||||
set_viewport(gl);
|
||||
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
gl_shader_set_params(width, height, gl->tex_w, gl->tex_h, gl->fbo_width, gl->fbo_height);
|
||||
gl_shader_set_params(width, height, gl->tex_w, gl->tex_h, gl->vp_width, gl->vp_height);
|
||||
|
||||
if (width != gl->last_width || height != gl->last_height) // res change. need to clear out texture.
|
||||
{
|
||||
@ -476,17 +507,29 @@ static bool gl_frame(void *data, const uint16_t* frame, unsigned width, unsigned
|
||||
glFlush();
|
||||
glDrawArrays(GL_QUADS, 0, 4);
|
||||
|
||||
// Render our FBO texture to back buffer.
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
gl->render_to_tex = false;
|
||||
gl_shader_set_params(gl->fbo_width, gl->fbo_height, gl->fbo_width, gl->fbo_height, gl->vp_width, gl->vp_height);
|
||||
set_viewport(gl);
|
||||
glBindTexture(GL_TEXTURE_2D, gl->fbo_texture);
|
||||
if (gl->fbo_inited)
|
||||
{
|
||||
// Render our FBO texture to back buffer.
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
gl_shader_use(2);
|
||||
|
||||
glTexCoordPointer(2, GL_FLOAT, 2 * sizeof(GLfloat), fbo_tex_coords);
|
||||
glDrawArrays(GL_QUADS, 0, 4);
|
||||
glTexCoordPointer(2, GL_FLOAT, 2 * sizeof(GLfloat), gl->tex_coords);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
gl->render_to_tex = false;
|
||||
set_viewport(gl, gl->win_width, gl->win_height, false);
|
||||
gl_shader_set_params(width * gl->fbo_scale_x, height * gl->fbo_scale_y, gl->fbo_width, gl->fbo_height, gl->vp_width, gl->vp_height);
|
||||
glBindTexture(GL_TEXTURE_2D, gl->fbo_texture);
|
||||
|
||||
glTexCoordPointer(2, GL_FLOAT, 2 * sizeof(GLfloat), gl->fbo_tex_coords);
|
||||
GLfloat xamt = (GLfloat)width * gl->fbo_scale_x / gl->fbo_width;
|
||||
GLfloat yamt = (GLfloat)height * gl->fbo_scale_y / gl->fbo_height;
|
||||
gl->fbo_tex_coords[3] = yamt;
|
||||
gl->fbo_tex_coords[4] = xamt;
|
||||
gl->fbo_tex_coords[5] = yamt;
|
||||
gl->fbo_tex_coords[6] = xamt;
|
||||
|
||||
glDrawArrays(GL_QUADS, 0, 4);
|
||||
glTexCoordPointer(2, GL_FLOAT, 2 * sizeof(GLfloat), gl->tex_coords);
|
||||
}
|
||||
|
||||
if (msg)
|
||||
gl_render_msg(gl, msg);
|
||||
@ -506,8 +549,11 @@ static void gl_free(void *data)
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glDeleteTextures(1, &gl->texture);
|
||||
glDeleteTextures(1, &gl->fbo_texture);
|
||||
glDeleteFramebuffers(1, &gl->fbo);
|
||||
if (gl->fbo_inited)
|
||||
{
|
||||
glDeleteTextures(1, &gl->fbo_texture);
|
||||
glDeleteFramebuffers(1, &gl->fbo);
|
||||
}
|
||||
SDL_QuitSubSystem(SDL_INIT_VIDEO);
|
||||
}
|
||||
|
||||
@ -575,14 +621,14 @@ static void* gl_init(video_info_t *video, const input_driver_t **input, void **i
|
||||
gl->win_height = video->height;
|
||||
}
|
||||
|
||||
// Set up render to texture.
|
||||
gl_init_fbo(gl, 2 * 256 * video->input_scale, 2 * 256 * video->input_scale);
|
||||
|
||||
SSNES_LOG("GL: Using resolution %ux%u\n", gl->win_width, gl->win_height);
|
||||
|
||||
// Set up render to texture.
|
||||
gl_init_fbo(gl, 256 * video->input_scale, 256 * video->input_scale);
|
||||
|
||||
gl->vsync = video->vsync;
|
||||
gl->keep_aspect = video->force_aspect;
|
||||
set_viewport(gl);
|
||||
set_viewport(gl, gl->win_width, gl->win_height, false);
|
||||
|
||||
if (!gl_shader_init())
|
||||
{
|
||||
|
131
gfx/shader_cg.c
131
gfx/shader_cg.c
@ -19,6 +19,7 @@
|
||||
#include <Cg/cg.h>
|
||||
#include <Cg/cgGL.h>
|
||||
#include "general.h"
|
||||
#include <string.h>
|
||||
|
||||
// Used when we call deactivate() since just unbinding the program didn't seem to work... :(
|
||||
static const char* stock_cg_program =
|
||||
@ -55,21 +56,29 @@ static const char* stock_cg_program =
|
||||
|
||||
|
||||
static CGcontext cgCtx;
|
||||
static CGprogram cgFPrg;
|
||||
static CGprogram cgVPrg;
|
||||
static CGprogram cgSFPrg;
|
||||
static CGprogram cgSVPrg;
|
||||
static CGprofile cgFProf;
|
||||
static CGprofile cgVProf;
|
||||
static CGparameter cg_video_size, cg_texture_size, cg_output_size;
|
||||
static CGparameter cg_Vvideo_size, cg_Vtexture_size, cg_Voutput_size; // Vertexes
|
||||
static CGparameter cg_mvp_matrix;
|
||||
struct cg_program
|
||||
{
|
||||
CGprogram prg;
|
||||
CGprogram vprg;
|
||||
CGprogram fprg;
|
||||
CGparameter vid_size_f;
|
||||
CGparameter tex_size_f;
|
||||
CGparameter out_size_f;
|
||||
CGparameter vid_size_v;
|
||||
CGparameter tex_size_v;
|
||||
CGparameter out_size_v;
|
||||
CGparameter mvp;
|
||||
};
|
||||
|
||||
static struct cg_program prg[3];
|
||||
static bool cg_active = false;
|
||||
static CGprofile cgVProf, cgFProf;
|
||||
static unsigned active_index = 0;
|
||||
|
||||
void gl_cg_set_proj_matrix(void)
|
||||
{
|
||||
if (cg_active)
|
||||
cgGLSetStateMatrixParameter(cg_mvp_matrix, CG_GL_MODELVIEW_PROJECTION_MATRIX, CG_GL_MATRIX_IDENTITY);
|
||||
cgGLSetStateMatrixParameter(prg[active_index].mvp, CG_GL_MODELVIEW_PROJECTION_MATRIX, CG_GL_MATRIX_IDENTITY);
|
||||
}
|
||||
|
||||
void gl_cg_set_params(unsigned width, unsigned height,
|
||||
@ -78,13 +87,13 @@ void gl_cg_set_params(unsigned width, unsigned height,
|
||||
{
|
||||
if (cg_active)
|
||||
{
|
||||
cgGLSetParameter2f(cg_video_size, width, height);
|
||||
cgGLSetParameter2f(cg_texture_size, tex_width, tex_height);
|
||||
cgGLSetParameter2f(cg_output_size, out_width, out_height);
|
||||
cgGLSetParameter2f(prg[active_index].vid_size_f, width, height);
|
||||
cgGLSetParameter2f(prg[active_index].tex_size_f, tex_width, tex_height);
|
||||
cgGLSetParameter2f(prg[active_index].out_size_f, out_width, out_height);
|
||||
|
||||
cgGLSetParameter2f(cg_Vvideo_size, width, height);
|
||||
cgGLSetParameter2f(cg_Vtexture_size, tex_width, tex_height);
|
||||
cgGLSetParameter2f(cg_Voutput_size, out_width, out_height);
|
||||
cgGLSetParameter2f(prg[active_index].vid_size_v, width, height);
|
||||
cgGLSetParameter2f(prg[active_index].tex_size_v, tex_width, tex_height);
|
||||
cgGLSetParameter2f(prg[active_index].out_size_v, out_width, out_height);
|
||||
}
|
||||
}
|
||||
|
||||
@ -97,12 +106,16 @@ void gl_cg_deinit(void)
|
||||
bool gl_cg_init(const char *path)
|
||||
{
|
||||
SSNES_LOG("Loading Cg file: %s\n", path);
|
||||
if (strlen(g_settings.video.second_pass_shader) > 0)
|
||||
SSNES_LOG("Loading 2nd pass: %s\n", g_settings.video.second_pass_shader);
|
||||
|
||||
cgCtx = cgCreateContext();
|
||||
if (cgCtx == NULL)
|
||||
{
|
||||
SSNES_ERR("Failed to create Cg context\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
cgFProf = cgGLGetLatestProfile(CG_GL_FRAGMENT);
|
||||
cgVProf = cgGLGetLatestProfile(CG_GL_VERTEX);
|
||||
if (cgFProf == CG_PROFILE_UNKNOWN || cgVProf == CG_PROFILE_UNKNOWN)
|
||||
@ -112,54 +125,66 @@ bool gl_cg_init(const char *path)
|
||||
}
|
||||
cgGLSetOptimalOptions(cgFProf);
|
||||
cgGLSetOptimalOptions(cgVProf);
|
||||
cgFPrg = cgCreateProgramFromFile(cgCtx, CG_SOURCE, path, cgFProf, "main_fragment", 0);
|
||||
cgVPrg = cgCreateProgramFromFile(cgCtx, CG_SOURCE, path, cgVProf, "main_vertex", 0);
|
||||
cgSFPrg = cgCreateProgram(cgCtx, CG_SOURCE, stock_cg_program, cgFProf, "main_fragment", 0);
|
||||
cgSVPrg = cgCreateProgram(cgCtx, CG_SOURCE, stock_cg_program, cgVProf, "main_vertex", 0);
|
||||
if (cgFPrg == NULL || cgVPrg == NULL || cgSFPrg == NULL || cgSVPrg == NULL)
|
||||
|
||||
|
||||
prg[0].fprg = cgCreateProgram(cgCtx, CG_SOURCE, stock_cg_program, cgFProf, "main_fragment", 0);
|
||||
prg[0].vprg = cgCreateProgram(cgCtx, CG_SOURCE, stock_cg_program, cgVProf, "main_vertex", 0);
|
||||
|
||||
prg[1].fprg = cgCreateProgramFromFile(cgCtx, CG_SOURCE, path, cgFProf, "main_fragment", 0);
|
||||
prg[1].vprg = cgCreateProgramFromFile(cgCtx, CG_SOURCE, path, cgVProf, "main_vertex", 0);
|
||||
|
||||
if (strlen(g_settings.video.second_pass_shader) > 0)
|
||||
{
|
||||
CGerror err = cgGetError();
|
||||
SSNES_ERR("CG error: %s\n", cgGetErrorString(err));
|
||||
return false;
|
||||
prg[2].fprg = cgCreateProgramFromFile(cgCtx, CG_SOURCE, g_settings.video.second_pass_shader, cgFProf, "main_fragment", 0);
|
||||
prg[2].vprg = cgCreateProgramFromFile(cgCtx, CG_SOURCE, g_settings.video.second_pass_shader, cgVProf, "main_vertex", 0);
|
||||
}
|
||||
cgGLLoadProgram(cgFPrg);
|
||||
cgGLLoadProgram(cgVPrg);
|
||||
cgGLLoadProgram(cgSFPrg);
|
||||
cgGLLoadProgram(cgSVPrg);
|
||||
else
|
||||
prg[2] = prg[0];
|
||||
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
if (prg[i].fprg == NULL || prg[i].vprg == NULL)
|
||||
{
|
||||
CGerror err = cgGetError();
|
||||
SSNES_ERR("CG error: %s\n", cgGetErrorString(err));
|
||||
return false;
|
||||
}
|
||||
|
||||
cgGLLoadProgram(prg[i].fprg);
|
||||
cgGLLoadProgram(prg[i].vprg);
|
||||
}
|
||||
|
||||
cgGLEnableProfile(cgFProf);
|
||||
cgGLEnableProfile(cgVProf);
|
||||
cgGLBindProgram(cgFPrg);
|
||||
cgGLBindProgram(cgVPrg);
|
||||
|
||||
cg_video_size = cgGetNamedParameter(cgFPrg, "IN.video_size");
|
||||
cg_texture_size = cgGetNamedParameter(cgFPrg, "IN.texture_size");
|
||||
cg_output_size = cgGetNamedParameter(cgFPrg, "IN.output_size");
|
||||
cg_Vvideo_size = cgGetNamedParameter(cgVPrg, "IN.video_size");
|
||||
cg_Vtexture_size = cgGetNamedParameter(cgVPrg, "IN.texture_size");
|
||||
cg_Voutput_size = cgGetNamedParameter(cgVPrg, "IN.output_size");
|
||||
cg_mvp_matrix = cgGetNamedParameter(cgVPrg, "modelViewProj");
|
||||
cgGLSetStateMatrixParameter(cg_mvp_matrix, CG_GL_MODELVIEW_PROJECTION_MATRIX, CG_GL_MATRIX_IDENTITY);
|
||||
cg_mvp_matrix = cgGetNamedParameter(cgSVPrg, "modelViewProj");
|
||||
cgGLSetStateMatrixParameter(cg_mvp_matrix, CG_GL_MODELVIEW_PROJECTION_MATRIX, CG_GL_MATRIX_IDENTITY);
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
cgGLBindProgram(prg[i].fprg);
|
||||
cgGLBindProgram(prg[i].vprg);
|
||||
|
||||
prg[i].vid_size_f = cgGetNamedParameter(prg[i].fprg, "IN.video_size");
|
||||
prg[i].tex_size_f = cgGetNamedParameter(prg[i].fprg, "IN.texture_size");
|
||||
prg[i].out_size_f = cgGetNamedParameter(prg[i].fprg, "IN.output_size");
|
||||
prg[i].vid_size_v = cgGetNamedParameter(prg[i].vprg, "IN.video_size");
|
||||
prg[i].tex_size_v = cgGetNamedParameter(prg[i].vprg, "IN.texture_size");
|
||||
prg[i].out_size_v = cgGetNamedParameter(prg[i].vprg, "IN.output_size");
|
||||
prg[i].mvp = cgGetNamedParameter(prg[i].vprg, "modelViewProj");
|
||||
cgGLSetStateMatrixParameter(prg[i].mvp, CG_GL_MODELVIEW_PROJECTION_MATRIX, CG_GL_MATRIX_IDENTITY);
|
||||
}
|
||||
|
||||
cgGLBindProgram(prg[1].fprg);
|
||||
cgGLBindProgram(prg[1].vprg);
|
||||
|
||||
cg_active = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
void gl_cg_activate(void)
|
||||
void gl_cg_use(unsigned index)
|
||||
{
|
||||
if (cg_active)
|
||||
{
|
||||
cgGLBindProgram(cgFPrg);
|
||||
cgGLBindProgram(cgVPrg);
|
||||
}
|
||||
}
|
||||
|
||||
// Just load a dummy shader.
|
||||
void gl_cg_deactivate(void)
|
||||
{
|
||||
if (cg_active)
|
||||
{
|
||||
cgGLBindProgram(cgSFPrg);
|
||||
cgGLBindProgram(cgSVPrg);
|
||||
active_index = index;
|
||||
cgGLBindProgram(prg[index].vprg);
|
||||
cgGLBindProgram(prg[index].fprg);
|
||||
}
|
||||
}
|
||||
|
@ -31,7 +31,6 @@ void gl_cg_set_params(unsigned width, unsigned height,
|
||||
unsigned tex_width, unsigned tex_height,
|
||||
unsigned out_width, unsigned out_height);
|
||||
|
||||
void gl_cg_activate(void);
|
||||
void gl_cg_deactivate(void);
|
||||
void gl_cg_use(unsigned index);
|
||||
|
||||
#endif
|
||||
|
@ -80,9 +80,10 @@ static PFNGLGETPROGRAMINFOLOGPROC pglGetProgramInfoLog = NULL;
|
||||
#endif
|
||||
|
||||
static bool glsl_enable = false;
|
||||
static GLuint gl_program;
|
||||
static GLuint gl_program[3] = {0};
|
||||
static GLuint fragment_shader;
|
||||
static GLuint vertex_shader;
|
||||
static unsigned active_index = 0;
|
||||
|
||||
static bool get_xml_shaders(const char *path, char **vertex_shader, char **fragment_shader)
|
||||
{
|
||||
@ -238,42 +239,51 @@ bool gl_glsl_init(const char *path)
|
||||
return false;
|
||||
}
|
||||
|
||||
gl_program = pglCreateProgram();
|
||||
const char *paths[] = {NULL, path,
|
||||
(strlen(g_settings.video.second_pass_shader) > 0) ? g_settings.video.second_pass_shader : NULL};
|
||||
|
||||
char *vertex_prog = NULL;
|
||||
char *fragment_prog = NULL;
|
||||
if (!get_xml_shaders(path, &vertex_prog, &fragment_prog))
|
||||
return false;
|
||||
|
||||
if (vertex_prog)
|
||||
for (int i = 1; i < 3; i++)
|
||||
{
|
||||
vertex_shader = pglCreateShader(GL_VERTEX_SHADER);
|
||||
pglShaderSource(vertex_shader, 1, (const char**)&vertex_prog, 0);
|
||||
pglCompileShader(vertex_shader);
|
||||
print_shader_log(vertex_shader);
|
||||
if (paths[i] == NULL)
|
||||
continue;
|
||||
|
||||
pglAttachShader(gl_program, vertex_shader);
|
||||
free(vertex_prog);
|
||||
}
|
||||
if (fragment_prog)
|
||||
{
|
||||
fragment_shader = pglCreateShader(GL_FRAGMENT_SHADER);
|
||||
pglShaderSource(fragment_shader, 1, (const char**)&fragment_prog, 0);
|
||||
pglCompileShader(fragment_shader);
|
||||
print_shader_log(fragment_shader);
|
||||
gl_program[i] = pglCreateProgram();
|
||||
|
||||
pglAttachShader(gl_program, fragment_shader);
|
||||
free(fragment_prog);
|
||||
}
|
||||
char *vertex_prog = NULL;
|
||||
char *fragment_prog = NULL;
|
||||
if (!get_xml_shaders(paths[i], &vertex_prog, &fragment_prog))
|
||||
return false;
|
||||
|
||||
if (vertex_prog || fragment_prog)
|
||||
{
|
||||
pglLinkProgram(gl_program);
|
||||
pglUseProgram(gl_program);
|
||||
print_linker_log(gl_program);
|
||||
if (vertex_prog)
|
||||
{
|
||||
vertex_shader = pglCreateShader(GL_VERTEX_SHADER);
|
||||
pglShaderSource(vertex_shader, 1, (const char**)&vertex_prog, 0);
|
||||
pglCompileShader(vertex_shader);
|
||||
print_shader_log(vertex_shader);
|
||||
|
||||
GLint location = pglGetUniformLocation(gl_program, "rubyTexture");
|
||||
pglUniform1i(location, 0);
|
||||
pglAttachShader(gl_program[i], vertex_shader);
|
||||
free(vertex_prog);
|
||||
}
|
||||
if (fragment_prog)
|
||||
{
|
||||
fragment_shader = pglCreateShader(GL_FRAGMENT_SHADER);
|
||||
pglShaderSource(fragment_shader, 1, (const char**)&fragment_prog, 0);
|
||||
pglCompileShader(fragment_shader);
|
||||
print_shader_log(fragment_shader);
|
||||
|
||||
pglAttachShader(gl_program[i], fragment_shader);
|
||||
free(fragment_prog);
|
||||
}
|
||||
|
||||
if (vertex_prog || fragment_prog)
|
||||
{
|
||||
pglLinkProgram(gl_program[i]);
|
||||
pglUseProgram(gl_program[i]);
|
||||
print_linker_log(gl_program[i]);
|
||||
|
||||
GLint location = pglGetUniformLocation(gl_program[i], "rubyTexture");
|
||||
pglUniform1i(location, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (!gl_check_error())
|
||||
@ -290,20 +300,20 @@ void gl_glsl_set_params(unsigned width, unsigned height,
|
||||
unsigned tex_width, unsigned tex_height,
|
||||
unsigned out_width, unsigned out_height)
|
||||
{
|
||||
if (glsl_enable)
|
||||
if (glsl_enable && gl_program[active_index] > 0)
|
||||
{
|
||||
GLint location;
|
||||
|
||||
float inputSize[2] = {width, height};
|
||||
location = pglGetUniformLocation(gl_program, "rubyInputSize");
|
||||
location = pglGetUniformLocation(gl_program[active_index], "rubyInputSize");
|
||||
pglUniform2fv(location, 1, inputSize);
|
||||
|
||||
float outputSize[2] = {out_width, out_height};
|
||||
location = pglGetUniformLocation(gl_program, "rubyOutputSize");
|
||||
location = pglGetUniformLocation(gl_program[active_index], "rubyOutputSize");
|
||||
pglUniform2fv(location, 1, outputSize);
|
||||
|
||||
float textureSize[2] = {tex_width, tex_height};
|
||||
location = pglGetUniformLocation(gl_program, "rubyTextureSize");
|
||||
location = pglGetUniformLocation(gl_program[active_index], "rubyTextureSize");
|
||||
pglUniform2fv(location, 1, textureSize);
|
||||
|
||||
}
|
||||
@ -312,14 +322,11 @@ void gl_glsl_set_params(unsigned width, unsigned height,
|
||||
void gl_glsl_set_proj_matrix(void)
|
||||
{}
|
||||
|
||||
void gl_glsl_activate(void)
|
||||
void gl_glsl_use(unsigned index)
|
||||
{
|
||||
if (glsl_enable)
|
||||
pglUseProgram(gl_program);
|
||||
}
|
||||
|
||||
void gl_glsl_deactivate(void)
|
||||
{
|
||||
if (glsl_enable)
|
||||
pglUseProgram(0);
|
||||
{
|
||||
active_index = index;
|
||||
pglUseProgram(gl_program[index]);
|
||||
}
|
||||
}
|
||||
|
@ -31,7 +31,6 @@ void gl_glsl_set_params(unsigned width, unsigned height,
|
||||
unsigned tex_width, unsigned tex_height,
|
||||
unsigned out_width, unsigned out_height);
|
||||
|
||||
void gl_glsl_activate(void);
|
||||
void gl_glsl_deactivate(void);
|
||||
void gl_glsl_use(unsigned index);
|
||||
|
||||
#endif
|
||||
|
@ -290,7 +290,7 @@ static void parse_config_file(void)
|
||||
CONFIG_GET_STRING(video.second_pass_shader, "video_second_pass_shader");
|
||||
CONFIG_GET_BOOL(video.render_to_texture, "video_render_to_texture");
|
||||
CONFIG_GET_DOUBLE(video.fbo_scale_x, "video_fbo_scale_x");
|
||||
CONFIG_GET_DOUBLE(video.fbo_scale_x, "video_fbo_scale_y");
|
||||
CONFIG_GET_DOUBLE(video.fbo_scale_y, "video_fbo_scale_y");
|
||||
CONFIG_GET_BOOL(video.second_pass_smooth, "video_second_pass_smooth");
|
||||
|
||||
#ifdef HAVE_FREETYPE
|
||||
|
Loading…
x
Reference in New Issue
Block a user