Merge pull request #28518 from clayjohn/GLES2-MSAA

Added MSAA to GLES2 backend
This commit is contained in:
Rémi Verschelde 2019-05-13 17:46:11 +02:00 committed by GitHub
commit e0517a12c5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 363 additions and 82 deletions

View file

@ -202,6 +202,10 @@ Error RasterizerGLES2::is_viable() {
return ERR_UNAVAILABLE;
}
}
if (GLAD_GL_EXT_framebuffer_multisample) {
glRenderbufferStorageMultisample = glRenderbufferStorageMultisampleEXT;
}
#endif // GLES_OVER_GL
#endif // GLAD_ENABLED

View file

@ -42,6 +42,16 @@
#define glClearDepth glClearDepthf
#endif
#ifndef GLES_OVER_GL
#ifdef IPHONE_ENABLED
#include <OpenGLES/ES2/glext.h>
//void *glResolveMultisampleFramebufferAPPLE;
#define GL_READ_FRAMEBUFFER 0x8CA8
#define GL_DRAW_FRAMEBUFFER 0x8CA9
#endif
#endif
static const GLenum _cube_side_enum[6] = {
GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
@ -1148,6 +1158,30 @@ void RasterizerSceneGLES2::_add_geometry_with_material(RasterizerStorageGLES2::G
}
}
void RasterizerSceneGLES2::_copy_texture_to_front_buffer(GLuint p_texture) {
//copy to front buffer
glBindFramebuffer(GL_FRAMEBUFFER, storage->frame.current_rt->fbo);
glDepthMask(GL_FALSE);
glDisable(GL_DEPTH_TEST);
glDisable(GL_CULL_FACE);
glDisable(GL_BLEND);
glDepthFunc(GL_LEQUAL);
glColorMask(1, 1, 1, 1);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, p_texture);
glViewport(0, 0, storage->frame.current_rt->width, storage->frame.current_rt->height);
storage->shaders.copy.bind();
storage->bind_quad_array();
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
void RasterizerSceneGLES2::_fill_render_list(InstanceBase **p_cull_result, int p_cull_count, bool p_depth_pass, bool p_shadow_pass) {
render_pass++;
@ -2688,9 +2722,13 @@ void RasterizerSceneGLES2::render_scene(const Transform &p_cam_transform, const
state.render_no_shadows = false;
if (storage->frame.current_rt->external.fbo != 0) {
current_fb = storage->frame.current_rt->external.fbo;
} else {
if (storage->frame.current_rt->multisample_active) {
current_fb = storage->frame.current_rt->multisample_fbo;
} else {
current_fb = storage->frame.current_rt->fbo;
}
}
env = environment_owner.getornull(p_environment);
viewport_width = storage->frame.current_rt->width;
@ -2838,7 +2876,38 @@ void RasterizerSceneGLES2::render_scene(const Transform &p_cam_transform, const
if (storage->frame.current_rt && state.used_screen_texture) {
//copy screen texture
if (storage->frame.current_rt && storage->frame.current_rt->multisample_active) {
// Resolve framebuffer to front buffer before copying
#ifdef GLES_OVER_GL
glBindFramebuffer(GL_READ_FRAMEBUFFER, storage->frame.current_rt->multisample_fbo);
glReadBuffer(GL_COLOR_ATTACHMENT0);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, storage->frame.current_rt->fbo);
glBlitFramebuffer(0, 0, storage->frame.current_rt->width, storage->frame.current_rt->height, 0, 0, storage->frame.current_rt->width, storage->frame.current_rt->height, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT, GL_NEAREST);
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
#elif IPHONE_ENABLED
glBindFramebuffer(GL_READ_FRAMEBUFFER, storage->frame.current_rt->multisample_fbo);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, storage->frame.current_rt->fbo);
glResolveMultisampleFramebufferAPPLE();
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
#else
// In GLES2 Blit is not available, so just copy color texture manually
_copy_texture_to_front_buffer(storage->frame.current_rt->multisample_color);
#endif
}
storage->canvas->_copy_screen(Rect2());
if (storage->frame.current_rt && storage->frame.current_rt->multisample_active) {
// Rebind the current framebuffer
glBindFramebuffer(GL_FRAMEBUFFER, current_fb);
glViewport(0, 0, viewport_width, viewport_height);
}
}
// alpha pass
@ -2851,6 +2920,22 @@ void RasterizerSceneGLES2::render_scene(const Transform &p_cam_transform, const
glDisable(GL_DEPTH_TEST);
if (storage->frame.current_rt && storage->frame.current_rt->multisample_active) {
#ifdef GLES_OVER_GL
glBindFramebuffer(GL_READ_FRAMEBUFFER, storage->frame.current_rt->multisample_fbo);
glReadBuffer(GL_COLOR_ATTACHMENT0);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, storage->frame.current_rt->fbo);
glBlitFramebuffer(0, 0, storage->frame.current_rt->width, storage->frame.current_rt->height, 0, 0, storage->frame.current_rt->width, storage->frame.current_rt->height, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT, GL_NEAREST);
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
#else
// In GLES2 Blit is not available, so just copy color texture manually
_copy_texture_to_front_buffer(storage->frame.current_rt->multisample_color);
#endif
}
//#define GLES2_SHADOW_ATLAS_DEBUG_VIEW
#ifdef GLES2_SHADOW_ATLAS_DEBUG_VIEW

View file

@ -670,6 +670,7 @@ public:
void _add_geometry(RasterizerStorageGLES2::Geometry *p_geometry, InstanceBase *p_instance, RasterizerStorageGLES2::GeometryOwner *p_owner, int p_material, bool p_depth_pass, bool p_shadow_pass);
void _add_geometry_with_material(RasterizerStorageGLES2::Geometry *p_geometry, InstanceBase *p_instance, RasterizerStorageGLES2::GeometryOwner *p_owner, RasterizerStorageGLES2::Material *p_material, bool p_depth_pass, bool p_shadow_pass);
void _copy_texture_to_front_buffer(GLuint texture);
void _fill_render_list(InstanceBase **p_cull_result, int p_cull_count, bool p_depth_pass, bool p_shadow_pass);
void _render_render_list(RenderList::Element **p_elements, int p_element_count,
const Transform &p_view_transform,

View file

@ -81,6 +81,28 @@ GLuint RasterizerStorageGLES2::system_fbo = 0;
#define _DEPTH_COMPONENT24_OES 0x81A6
#ifndef GLES_OVER_GL
// enable extensions manually for android and ios
#include <dlfcn.h> // needed to load extensions
#ifdef IPHONE_ENABLED
#include <OpenGLES/ES2/glext.h>
//void *glRenderbufferStorageMultisampleAPPLE;
//void *glResolveMultisampleFramebufferAPPLE;
#define glRenderbufferStorageMultisample glRenderbufferStorageMultisampleAPPLE
#else
#include <GLES2/gl2ext.h>
PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC glRenderbufferStorageMultisampleEXT;
PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEEXTPROC glFramebufferTexture2DMultisampleEXT;
#define glRenderbufferStorageMultisample glRenderbufferStorageMultisampleEXT
#define glFramebufferTexture2DMultisample glFramebufferTexture2DMultisampleEXT
#endif
#define GL_MAX_SAMPLES 0x8D57
#endif //!GLES_OVER_GL
void RasterizerStorageGLES2::bind_quad_array() const {
glBindBuffer(GL_ARRAY_BUFFER, resources.quadie);
glVertexAttribPointer(VS::ARRAY_VERTEX, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 4, 0);
@ -4549,24 +4571,34 @@ void RasterizerStorageGLES2::_render_target_allocate(RenderTarget *rt) {
if (rt->width <= 0 || rt->height <= 0)
return;
GLuint color_internal_format;
GLuint color_format;
GLuint color_type = GL_UNSIGNED_BYTE;
if (rt->flags[RasterizerStorage::RENDER_TARGET_TRANSPARENT]) {
color_internal_format = GL_RGBA;
color_format = GL_RGBA;
} else {
color_internal_format = GL_RGB;
color_format = GL_RGB;
}
{
/* Front FBO */
Texture *texture = texture_owner.getornull(rt->texture);
ERR_FAIL_COND(!texture);
// create fbo
// framebuffer
glGenFramebuffers(1, &rt->fbo);
glBindFramebuffer(GL_FRAMEBUFFER, rt->fbo);
// color
glGenTextures(1, &rt->color);
glBindTexture(GL_TEXTURE_2D, rt->color);
if (rt->flags[RasterizerStorage::RENDER_TARGET_TRANSPARENT]) {
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, rt->width, rt->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
} else {
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, rt->width, rt->height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
}
glTexImage2D(GL_TEXTURE_2D, 0, color_internal_format, rt->width, rt->height, 0, color_format, color_type, NULL);
if (texture->flags & VS::TEXTURE_FLAG_FILTER) {
@ -4577,6 +4609,7 @@ void RasterizerStorageGLES2::_render_target_allocate(RenderTarget *rt) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
}
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
@ -4585,6 +4618,7 @@ void RasterizerStorageGLES2::_render_target_allocate(RenderTarget *rt) {
// depth
if (config.support_depth_texture) {
glGenTextures(1, &rt->depth);
glBindTexture(GL_TEXTURE_2D, rt->depth);
glTexImage2D(GL_TEXTURE_2D, 0, config.depth_internalformat, rt->width, rt->height, 0, GL_DEPTH_COMPONENT, config.depth_type, NULL);
@ -4596,6 +4630,7 @@ void RasterizerStorageGLES2::_render_target_allocate(RenderTarget *rt) {
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, rt->depth, 0);
} else {
glGenRenderbuffers(1, &rt->depth);
glBindRenderbuffer(GL_RENDERBUFFER, rt->depth);
@ -4610,10 +4645,13 @@ void RasterizerStorageGLES2::_render_target_allocate(RenderTarget *rt) {
glDeleteFramebuffers(1, &rt->fbo);
if (config.support_depth_texture) {
glDeleteTextures(1, &rt->depth);
} else {
glDeleteRenderbuffers(1, &rt->depth);
}
glDeleteTextures(1, &rt->color);
rt->fbo = 0;
rt->width = 0;
@ -4638,6 +4676,69 @@ void RasterizerStorageGLES2::_render_target_allocate(RenderTarget *rt) {
texture->active = true;
texture_set_flags(rt->texture, texture->flags);
}
/* BACK FBO */
/* For MSAA */
if (rt->msaa != VS::VIEWPORT_MSAA_DISABLED && config.multisample_supported) {
rt->multisample_active = true;
static const int msaa_value[] = { 0, 2, 4, 8, 16 };
int msaa = msaa_value[rt->msaa];
int max_samples = 0;
glGetIntegerv(GL_MAX_SAMPLES, &max_samples);
if (msaa > max_samples) {
WARN_PRINTS("MSAA must be <= GL_MAX_SAMPLES, falling-back to GL_MAX_SAMPLES = " + itos(max_samples));
msaa = max_samples;
}
//regular fbo
glGenFramebuffers(1, &rt->multisample_fbo);
glBindFramebuffer(GL_FRAMEBUFFER, rt->multisample_fbo);
glGenRenderbuffers(1, &rt->multisample_depth);
glBindRenderbuffer(GL_RENDERBUFFER, rt->multisample_depth);
glRenderbufferStorageMultisample(GL_RENDERBUFFER, msaa, config.depth_internalformat, rt->width, rt->height);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rt->multisample_depth);
#if defined(GLES_OVER_GL) || defined(IPHONE_ENABLED)
glGenRenderbuffers(1, &rt->multisample_color);
glBindRenderbuffer(GL_RENDERBUFFER, rt->multisample_color);
glRenderbufferStorageMultisample(GL_RENDERBUFFER, msaa, color_internal_format, rt->width, rt->height);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rt->multisample_color);
#else
// Render to a texture in android
glGenTextures(1, &rt->multisample_color);
glBindTexture(GL_TEXTURE_2D, rt->multisample_color);
glTexImage2D(GL_TEXTURE_2D, 0, color_internal_format, rt->width, rt->height, 0, color_format, color_type, NULL);
// multisample buffer is same size as front buffer, so just use nearest
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glFramebufferTexture2DMultisample(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->color, 0, msaa);
#endif
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (status != GL_FRAMEBUFFER_COMPLETE) {
printf("err status: %x\n", status);
_render_target_clear(rt);
ERR_FAIL_COND(status != GL_FRAMEBUFFER_COMPLETE);
}
glBindRenderbuffer(GL_RENDERBUFFER, 0);
} else {
rt->multisample_active = false;
}
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
@ -4666,7 +4767,7 @@ void RasterizerStorageGLES2::_render_target_allocate(RenderTarget *rt) {
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT);
status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (status != GL_FRAMEBUFFER_COMPLETE) {
_render_target_clear(rt);
ERR_FAIL_COND(status != GL_FRAMEBUFFER_COMPLETE);
@ -4725,6 +4826,20 @@ void RasterizerStorageGLES2::_render_target_clear(RenderTarget *rt) {
glDeleteTextures(1, &rt->copy_screen_effect.color);
rt->copy_screen_effect.color = 0;
}
if (rt->multisample_active) {
glDeleteFramebuffers(1, &rt->multisample_fbo);
rt->multisample_fbo = 0;
glDeleteRenderbuffers(1, &rt->multisample_depth);
rt->multisample_depth = 0;
#ifdef GLES_OVER_GL
glDeleteRenderbuffers(1, &rt->multisample_color);
#else
glDeleteTextures(1, &rt->multisample_color);
#endif
rt->multisample_color = 0;
}
}
RID RasterizerStorageGLES2::render_target_create() {
@ -4926,6 +5041,11 @@ void RasterizerStorageGLES2::render_target_set_msaa(RID p_render_target, VS::Vie
if (rt->msaa == p_msaa)
return;
if (!config.multisample_supported) {
ERR_PRINT("MSAA not supported on this hardware.");
return;
}
_render_target_clear(rt);
rt->msaa = p_msaa;
_render_target_allocate(rt);
@ -5449,6 +5569,26 @@ void RasterizerStorageGLES2::initialize() {
config.support_npot_repeat_mipmap = config.extensions.has("GL_OES_texture_npot");
#endif
#ifndef GLES_OVER_GL
//Manually load extensions for android and ios
#ifdef IPHONE_ENABLED
//void *gles2_lib = dlopen(NULL, RTLD_LAZY);
//glRenderbufferStorageMultisampleAPPLE = dlsym(gles2_lib, "glRenderbufferStorageMultisampleAPPLE");
//glResolveMultisampleFramebufferAPPLE = dlsym(gles2_lib, "glResolveMultisampleFramebufferAPPLE");
#else
void *gles2_lib = dlopen("libGLESv2.so", RTLD_LAZY);
glRenderbufferStorageMultisampleEXT = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC)dlsym(gles2_lib, "glRenderbufferStorageMultisampleEXT");
glFramebufferTexture2DMultisampleEXT = (PFNGLFRAMEBUFFERTEXTURE2DMULTISAMPLEEXTPROC)dlsym(gles2_lib, "glFramebufferTexture2DMultisampleEXT");
#endif
#endif
// Check for multisample support
config.multisample_supported = config.extensions.has("GL_EXT_framebuffer_multisample") || config.extensions.has("GL_EXT_multisampled_render_to_texture") || config.extensions.has("GL_APPLE_framebuffer_multisample");
#ifdef GLES_OVER_GL
config.use_rgba_2d_shadows = false;
config.support_depth_texture = true;

View file

@ -92,6 +92,8 @@ public:
bool support_shadow_cubemaps;
bool multisample_supported;
GLuint depth_internalformat;
GLuint depth_type;
@ -1132,10 +1134,14 @@ public:
struct RenderTarget : public RID_Data {
GLuint fbo;
GLuint color;
GLuint depth;
GLuint multisample_fbo;
GLuint multisample_color;
GLuint multisample_depth;
bool multisample_active;
// TODO post processing effects?
// TODO HDR?
@ -1182,6 +1188,10 @@ public:
fbo(0),
color(0),
depth(0),
multisample_fbo(0),
multisample_color(0),
multisample_depth(0),
multisample_active(false),
width(0),
height(0),
used_in_frame(false),

View file

@ -301,7 +301,7 @@ def configure(env):
env.Prepend(CPPPATH=['#platform/android'])
env.Append(CPPFLAGS=['-DANDROID_ENABLED', '-DUNIX_ENABLED', '-DNO_FCNTL'])
env.Append(LIBS=['OpenSLES', 'EGL', 'GLESv3', 'android', 'log', 'z', 'dl'])
env.Append(LIBS=['OpenSLES', 'EGL', 'GLESv3', 'GLESv2', 'android', 'log', 'z', 'dl'])
# Return NDK version string in source.properties (adapted from the Chromium project).
def get_ndk_version(path):

View file

@ -1,6 +1,6 @@
/*
OpenGL loader generated by glad 0.1.29 on Mon Mar 4 12:47:22 2019.
OpenGL loader generated by glad 0.1.29 on Wed May 1 23:16:34 2019.
Language/Generator: C/C++
Specification: gl
@ -9,6 +9,8 @@
Extensions:
GL_ARB_debug_output,
GL_ARB_framebuffer_object,
GL_EXT_framebuffer_blit,
GL_EXT_framebuffer_multisample,
GL_EXT_framebuffer_object
Loader: True
Local files: False
@ -16,9 +18,9 @@
Reproducible: False
Commandline:
--profile="compatibility" --api="gl=3.3" --generator="c" --spec="gl" --extensions="GL_ARB_debug_output,GL_ARB_framebuffer_object,GL_EXT_framebuffer_object"
--profile="compatibility" --api="gl=3.3" --generator="c" --spec="gl" --extensions="GL_ARB_debug_output,GL_ARB_framebuffer_object,GL_EXT_framebuffer_blit,GL_EXT_framebuffer_multisample,GL_EXT_framebuffer_object"
Online:
https://glad.dav1d.de/#profile=compatibility&language=c&specification=gl&loader=on&api=gl%3D3.3&extensions=GL_ARB_debug_output&extensions=GL_ARB_framebuffer_object&extensions=GL_EXT_framebuffer_object
https://glad.dav1d.de/#profile=compatibility&language=c&specification=gl&loader=on&api=gl%3D3.3&extensions=GL_ARB_debug_output&extensions=GL_ARB_framebuffer_object&extensions=GL_EXT_framebuffer_blit&extensions=GL_EXT_framebuffer_multisample&extensions=GL_EXT_framebuffer_object
*/
#include <stdio.h>
@ -992,11 +994,15 @@ PFNGLWINDOWPOS3SPROC glad_glWindowPos3s = NULL;
PFNGLWINDOWPOS3SVPROC glad_glWindowPos3sv = NULL;
int GLAD_GL_ARB_debug_output = 0;
int GLAD_GL_ARB_framebuffer_object = 0;
int GLAD_GL_EXT_framebuffer_blit = 0;
int GLAD_GL_EXT_framebuffer_multisample = 0;
int GLAD_GL_EXT_framebuffer_object = 0;
PFNGLDEBUGMESSAGECONTROLARBPROC glad_glDebugMessageControlARB = NULL;
PFNGLDEBUGMESSAGEINSERTARBPROC glad_glDebugMessageInsertARB = NULL;
PFNGLDEBUGMESSAGECALLBACKARBPROC glad_glDebugMessageCallbackARB = NULL;
PFNGLGETDEBUGMESSAGELOGARBPROC glad_glGetDebugMessageLogARB = NULL;
PFNGLBLITFRAMEBUFFEREXTPROC glad_glBlitFramebufferEXT = NULL;
PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC glad_glRenderbufferStorageMultisampleEXT = NULL;
PFNGLISRENDERBUFFEREXTPROC glad_glIsRenderbufferEXT = NULL;
PFNGLBINDRENDERBUFFEREXTPROC glad_glBindRenderbufferEXT = NULL;
PFNGLDELETERENDERBUFFERSEXTPROC glad_glDeleteRenderbuffersEXT = NULL;
@ -1807,6 +1813,14 @@ static void load_GL_ARB_framebuffer_object(GLADloadproc load) {
glad_glRenderbufferStorageMultisample = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC)load("glRenderbufferStorageMultisample");
glad_glFramebufferTextureLayer = (PFNGLFRAMEBUFFERTEXTURELAYERPROC)load("glFramebufferTextureLayer");
}
static void load_GL_EXT_framebuffer_blit(GLADloadproc load) {
if(!GLAD_GL_EXT_framebuffer_blit) return;
glad_glBlitFramebufferEXT = (PFNGLBLITFRAMEBUFFEREXTPROC)load("glBlitFramebufferEXT");
}
static void load_GL_EXT_framebuffer_multisample(GLADloadproc load) {
if(!GLAD_GL_EXT_framebuffer_multisample) return;
glad_glRenderbufferStorageMultisampleEXT = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC)load("glRenderbufferStorageMultisampleEXT");
}
static void load_GL_EXT_framebuffer_object(GLADloadproc load) {
if(!GLAD_GL_EXT_framebuffer_object) return;
glad_glIsRenderbufferEXT = (PFNGLISRENDERBUFFEREXTPROC)load("glIsRenderbufferEXT");
@ -1831,6 +1845,8 @@ static int find_extensionsGL(void) {
if (!get_exts()) return 0;
GLAD_GL_ARB_debug_output = has_ext("GL_ARB_debug_output");
GLAD_GL_ARB_framebuffer_object = has_ext("GL_ARB_framebuffer_object");
GLAD_GL_EXT_framebuffer_blit = has_ext("GL_EXT_framebuffer_blit");
GLAD_GL_EXT_framebuffer_multisample = has_ext("GL_EXT_framebuffer_multisample");
GLAD_GL_EXT_framebuffer_object = has_ext("GL_EXT_framebuffer_object");
free_exts();
return 1;
@ -1912,6 +1928,8 @@ int gladLoadGLLoader(GLADloadproc load) {
if (!find_extensionsGL()) return 0;
load_GL_ARB_debug_output(load);
load_GL_ARB_framebuffer_object(load);
load_GL_EXT_framebuffer_blit(load);
load_GL_EXT_framebuffer_multisample(load);
load_GL_EXT_framebuffer_object(load);
return GLVersion.major != 0 || GLVersion.minor != 0;
}

View file

@ -1,6 +1,6 @@
/*
OpenGL loader generated by glad 0.1.29 on Mon Mar 4 12:47:22 2019.
OpenGL loader generated by glad 0.1.29 on Wed May 1 23:16:34 2019.
Language/Generator: C/C++
Specification: gl
@ -9,6 +9,8 @@
Extensions:
GL_ARB_debug_output,
GL_ARB_framebuffer_object,
GL_EXT_framebuffer_blit,
GL_EXT_framebuffer_multisample,
GL_EXT_framebuffer_object
Loader: True
Local files: False
@ -16,9 +18,9 @@
Reproducible: False
Commandline:
--profile="compatibility" --api="gl=3.3" --generator="c" --spec="gl" --extensions="GL_ARB_debug_output,GL_ARB_framebuffer_object,GL_EXT_framebuffer_object"
--profile="compatibility" --api="gl=3.3" --generator="c" --spec="gl" --extensions="GL_ARB_debug_output,GL_ARB_framebuffer_object,GL_EXT_framebuffer_blit,GL_EXT_framebuffer_multisample,GL_EXT_framebuffer_object"
Online:
https://glad.dav1d.de/#profile=compatibility&language=c&specification=gl&loader=on&api=gl%3D3.3&extensions=GL_ARB_debug_output&extensions=GL_ARB_framebuffer_object&extensions=GL_EXT_framebuffer_object
https://glad.dav1d.de/#profile=compatibility&language=c&specification=gl&loader=on&api=gl%3D3.3&extensions=GL_ARB_debug_output&extensions=GL_ARB_framebuffer_object&extensions=GL_EXT_framebuffer_blit&extensions=GL_EXT_framebuffer_multisample&extensions=GL_EXT_framebuffer_object
*/
@ -3633,6 +3635,13 @@ GLAPI PFNGLSECONDARYCOLORP3UIVPROC glad_glSecondaryColorP3uiv;
#define GL_DEBUG_SEVERITY_HIGH_ARB 0x9146
#define GL_DEBUG_SEVERITY_MEDIUM_ARB 0x9147
#define GL_DEBUG_SEVERITY_LOW_ARB 0x9148
#define GL_READ_FRAMEBUFFER_EXT 0x8CA8
#define GL_DRAW_FRAMEBUFFER_EXT 0x8CA9
#define GL_DRAW_FRAMEBUFFER_BINDING_EXT 0x8CA6
#define GL_READ_FRAMEBUFFER_BINDING_EXT 0x8CAA
#define GL_RENDERBUFFER_SAMPLES_EXT 0x8CAB
#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT 0x8D56
#define GL_MAX_SAMPLES_EXT 0x8D57
#define GL_INVALID_FRAMEBUFFER_OPERATION_EXT 0x0506
#define GL_MAX_RENDERBUFFER_SIZE_EXT 0x84E8
#define GL_FRAMEBUFFER_BINDING_EXT 0x8CA6
@ -3704,6 +3713,20 @@ GLAPI PFNGLGETDEBUGMESSAGELOGARBPROC glad_glGetDebugMessageLogARB;
#define GL_ARB_framebuffer_object 1
GLAPI int GLAD_GL_ARB_framebuffer_object;
#endif
#ifndef GL_EXT_framebuffer_blit
#define GL_EXT_framebuffer_blit 1
GLAPI int GLAD_GL_EXT_framebuffer_blit;
typedef void (APIENTRYP PFNGLBLITFRAMEBUFFEREXTPROC)(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
GLAPI PFNGLBLITFRAMEBUFFEREXTPROC glad_glBlitFramebufferEXT;
#define glBlitFramebufferEXT glad_glBlitFramebufferEXT
#endif
#ifndef GL_EXT_framebuffer_multisample
#define GL_EXT_framebuffer_multisample 1
GLAPI int GLAD_GL_EXT_framebuffer_multisample;
typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
GLAPI PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC glad_glRenderbufferStorageMultisampleEXT;
#define glRenderbufferStorageMultisampleEXT glad_glRenderbufferStorageMultisampleEXT
#endif
#ifndef GL_EXT_framebuffer_object
#define GL_EXT_framebuffer_object 1
GLAPI int GLAD_GL_EXT_framebuffer_object;