diff --git a/src/efb.h b/src/efb.h index 1fa8ab1..d6e5a99 100644 --- a/src/efb.h +++ b/src/efb.h @@ -85,8 +85,7 @@ void _ogx_efb_set_content_type_real(OgxEfbContentType content_type); /* We inline this part since most of the times the desired content type will be * the one already active */ static inline void _ogx_efb_set_content_type(OgxEfbContentType content_type) { - if (content_type == _ogx_efb_content_type && - (content_type != OGX_EFB_SCENE || _ogx_fbo_state.dirty.all == 0)) + if (content_type == _ogx_efb_content_type) return; _ogx_efb_set_content_type_real(content_type); } diff --git a/src/fbo.c b/src/fbo.c index 3eb4314..d64fc4b 100644 --- a/src/fbo.c +++ b/src/fbo.c @@ -367,3 +367,28 @@ void glFramebufferTexture3D(GLenum target, GLenum attachment, GLenum textarget, warning("glFramebufferTexture3D is unsupported"); set_error(GL_INVALID_OPERATION); } + +void ogx_enable_module_fbo() { + _ogx_add_extension("GL_EXT_framebuffer_object"); +} + +/* FBOs are in OpenGL 3.0, and in older versions as an extension */ +#define PROC(name) \ + { #name, name }, \ + { #name "EXT", name } +static const OgxProcMap s_proc_map[] = { + PROC(glBindFramebuffer), + PROC(glCheckFramebufferStatus), + PROC(glDeleteFramebuffers), + PROC(glFramebufferTexture1D), + PROC(glFramebufferTexture2D), + PROC(glFramebufferTexture3D), + PROC(glGenFramebuffers), + PROC(glIsFramebuffer), +}; +#define NUM_PROCS (sizeof(s_proc_map) / sizeof(s_proc_map[0])) + +OgxFunctions _ogx_fbo_functions = { + NUM_PROCS, + s_proc_map, +}; diff --git a/src/fbo.h b/src/fbo.h index 50b1492..1c35c70 100644 --- a/src/fbo.h +++ b/src/fbo.h @@ -87,7 +87,11 @@ bool _ogx_fbo_get_integerv(GLenum pname, GLint *params); void _ogx_fbo_scene_save_from_efb(OgxEfbContentType next_content_type); void _ogx_fbo_scene_load_into_efb(void); -#ifndef BUILDING_FBO_CODE +#ifdef BUILDING_FBO_CODE + +extern OgxFunctions _ogx_fbo_functions; + +#else /* BUILDING_FBO_CODE not defined */ OgxFboState _ogx_fbo_state __attribute__((weak)) = { 0, 0 }; @@ -106,6 +110,8 @@ void __attribute__((weak)) _ogx_fbo_scene_load_into_efb() _ogx_scene_load_into_efb(); } +OgxFunctions _ogx_fbo_functions __attribute__((weak)) = { 0, NULL }; + #endif /* BUILDING_FBO_CODE */ #ifdef __cplusplus diff --git a/src/functions.c b/src/functions.c index 457dfed..4715e1c 100644 --- a/src/functions.c +++ b/src/functions.c @@ -29,6 +29,7 @@ POSSIBILITY OF SUCH DAMAGE. *****************************************************************************/ #define GL_GLEXT_PROTOTYPES 1 +#include "fbo.h" #include "opengx.h" #include "shader.h" #include "types.h" @@ -51,7 +52,9 @@ static const OgxProcMap s_proc_map[] = { PROC(glBindBuffer), /* OpenGL 1.5 */ PROC(glBindTexture), PROC(glBitmap), + PROC(glBlendEquation), PROC(glBlendFunc), + PROC(glBlendFuncSeparate), PROC(glBufferData), /* OpenGL 1.5 */ PROC(glBufferSubData), /* OpenGL 1.5 */ PROC(glCallList), @@ -470,5 +473,12 @@ void *ogx_get_proc_address(const char *proc) proc); if (ret) return ret; } + + if (_ogx_fbo_functions.num_functions > 0) { + ret = search_in_functions(_ogx_fbo_functions.functions, + _ogx_fbo_functions.num_functions, + proc); + if (ret) return ret; + } return search_in_functions(s_proc_map, NUM_PROCS, proc); } diff --git a/src/gc_gl.c b/src/gc_gl.c index 2af568e..ee51c39 100644 --- a/src/gc_gl.c +++ b/src/gc_gl.c @@ -1670,6 +1670,13 @@ void glBlendFunc(GLenum sfactor, GLenum dfactor) glparamstate.dirty.bits.dirty_blend = 1; } +void glBlendFuncSeparate(GLenum sfactor_rgb, GLenum dfactor_rgb, + GLenum sfactor_alpha, GLenum dfactor_alpha) +{ + /* This is not correct, but better than nothing */ + glBlendFunc(sfactor_rgb, dfactor_rgb); +} + void glPointSize(GLfloat size) { unsigned int gxsize = size; diff --git a/src/getters.c b/src/getters.c index 23b8468..cfe38ce 100644 --- a/src/getters.c +++ b/src/getters.c @@ -40,8 +40,9 @@ POSSIBILITY OF SUCH DAMAGE. #include static const GLubyte gl_null_string[1] = { 0 }; -/* This is not static because we might modify it in place */ -static GLubyte s_extension_string[] = +/* This is not const because we might modify it in place. + * Make sure that this buffer is large enough to fit all added extensions. */ +static GLubyte s_extension_string[256] = "GL_ARB_multitexture " "GL_ARB_vertex_buffer_object "; @@ -72,6 +73,11 @@ static GLubyte *get_extension_string(int index) return ptr; } +void _ogx_add_extension(const GLubyte *name) +{ + strcat(s_extension_string, name); +} + GLenum glGetError(void) { GLenum error = glparamstate.error; diff --git a/src/opengx.h b/src/opengx.h index 9a16111..4aa7ce1 100644 --- a/src/opengx.h +++ b/src/opengx.h @@ -254,6 +254,9 @@ static inline void ogx_shader_set_modelview_gl(const GLfloat *matrix) * matrices, and uploads them separately to GX. */ void ogx_shader_set_mvp_gl(const GLfloat *matrix); +/* Force the inclusion of the FBO code into the program */ +void ogx_enable_module_fbo(); + #ifdef __cplusplus } // extern C #endif diff --git a/src/utils.h b/src/utils.h index dc414d4..0143e40 100644 --- a/src/utils.h +++ b/src/utils.h @@ -355,6 +355,8 @@ void _ogx_set_projection(const Mtx44 matrix); bool _ogx_setup_render_stages(void); void _ogx_update_vertex_array_readers(OgxDrawMode mode); +void _ogx_add_extension(const GLubyte *name); + #ifdef __cplusplus } // extern C #endif