added MSAA to GLES backend
This commit is contained in:
parent
90cc1d3c1d
commit
a3d5aec68d
|
@ -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
|
||||
|
|
|
@ -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++;
|
||||
|
@ -2689,7 +2723,11 @@ void RasterizerSceneGLES2::render_scene(const Transform &p_cam_transform, const
|
|||
if (storage->frame.current_rt->external.fbo != 0) {
|
||||
current_fb = storage->frame.current_rt->external.fbo;
|
||||
} else {
|
||||
current_fb = storage->frame.current_rt->fbo;
|
||||
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);
|
||||
|
||||
|
@ -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
|
||||
|
|
|
@ -646,6 +646,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,
|
||||
|
|
|
@ -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);
|
||||
|
@ -4534,95 +4556,174 @@ void RasterizerStorageGLES2::_render_target_allocate(RenderTarget *rt) {
|
|||
if (rt->width <= 0 || rt->height <= 0)
|
||||
return;
|
||||
|
||||
Texture *texture = texture_owner.getornull(rt->texture);
|
||||
ERR_FAIL_COND(!texture);
|
||||
|
||||
// create fbo
|
||||
|
||||
glGenFramebuffers(1, &rt->fbo);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, rt->fbo);
|
||||
|
||||
// color
|
||||
|
||||
glGenTextures(1, &rt->color);
|
||||
glBindTexture(GL_TEXTURE_2D, rt->color);
|
||||
GLuint color_internal_format;
|
||||
GLuint color_format;
|
||||
GLuint color_type = GL_UNSIGNED_BYTE;
|
||||
|
||||
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);
|
||||
color_internal_format = GL_RGBA;
|
||||
color_format = GL_RGBA;
|
||||
} else {
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, rt->width, rt->height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
|
||||
color_internal_format = GL_RGB;
|
||||
color_format = GL_RGB;
|
||||
}
|
||||
|
||||
if (texture->flags & VS::TEXTURE_FLAG_FILTER) {
|
||||
{
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
} else {
|
||||
/* Front FBO */
|
||||
|
||||
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);
|
||||
Texture *texture = texture_owner.getornull(rt->texture);
|
||||
ERR_FAIL_COND(!texture);
|
||||
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->color, 0);
|
||||
// framebuffer
|
||||
glGenFramebuffers(1, &rt->fbo);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, rt->fbo);
|
||||
|
||||
// depth
|
||||
// color
|
||||
glGenTextures(1, &rt->color);
|
||||
glBindTexture(GL_TEXTURE_2D, rt->color);
|
||||
|
||||
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);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, color_internal_format, rt->width, rt->height, 0, color_format, color_type, NULL);
|
||||
|
||||
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);
|
||||
if (texture->flags & VS::TEXTURE_FLAG_FILTER) {
|
||||
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, rt->depth, 0);
|
||||
} else {
|
||||
glGenRenderbuffers(1, &rt->depth);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, rt->depth);
|
||||
|
||||
glRenderbufferStorage(GL_RENDERBUFFER, config.depth_internalformat, rt->width, rt->height);
|
||||
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rt->depth);
|
||||
}
|
||||
|
||||
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
||||
|
||||
if (status != GL_FRAMEBUFFER_COMPLETE) {
|
||||
|
||||
glDeleteFramebuffers(1, &rt->fbo);
|
||||
if (config.support_depth_texture) {
|
||||
glDeleteTextures(1, &rt->depth);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
} else {
|
||||
glDeleteRenderbuffers(1, &rt->depth);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
}
|
||||
glDeleteTextures(1, &rt->color);
|
||||
rt->fbo = 0;
|
||||
rt->width = 0;
|
||||
rt->height = 0;
|
||||
rt->color = 0;
|
||||
rt->depth = 0;
|
||||
texture->tex_id = 0;
|
||||
texture->active = false;
|
||||
WARN_PRINT("Could not create framebuffer!!");
|
||||
return;
|
||||
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->color, 0);
|
||||
|
||||
// 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);
|
||||
|
||||
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);
|
||||
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, rt->depth, 0);
|
||||
} else {
|
||||
|
||||
glGenRenderbuffers(1, &rt->depth);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, rt->depth);
|
||||
|
||||
glRenderbufferStorage(GL_RENDERBUFFER, config.depth_internalformat, rt->width, rt->height);
|
||||
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rt->depth);
|
||||
}
|
||||
|
||||
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
||||
|
||||
if (status != GL_FRAMEBUFFER_COMPLETE) {
|
||||
|
||||
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;
|
||||
rt->height = 0;
|
||||
rt->color = 0;
|
||||
rt->depth = 0;
|
||||
texture->tex_id = 0;
|
||||
texture->active = false;
|
||||
WARN_PRINT("Could not create framebuffer!!");
|
||||
return;
|
||||
}
|
||||
|
||||
texture->format = Image::FORMAT_RGBA8;
|
||||
texture->gl_format_cache = GL_RGBA;
|
||||
texture->gl_type_cache = GL_UNSIGNED_BYTE;
|
||||
texture->gl_internal_format_cache = GL_RGBA;
|
||||
texture->tex_id = rt->color;
|
||||
texture->width = rt->width;
|
||||
texture->alloc_width = rt->width;
|
||||
texture->height = rt->height;
|
||||
texture->alloc_height = rt->height;
|
||||
texture->active = true;
|
||||
|
||||
texture_set_flags(rt->texture, texture->flags);
|
||||
}
|
||||
|
||||
texture->format = Image::FORMAT_RGBA8;
|
||||
texture->gl_format_cache = GL_RGBA;
|
||||
texture->gl_type_cache = GL_UNSIGNED_BYTE;
|
||||
texture->gl_internal_format_cache = GL_RGBA;
|
||||
texture->tex_id = rt->color;
|
||||
texture->width = rt->width;
|
||||
texture->alloc_width = rt->width;
|
||||
texture->height = rt->height;
|
||||
texture->alloc_height = rt->height;
|
||||
texture->active = true;
|
||||
/* BACK FBO */
|
||||
/* For MSAA */
|
||||
|
||||
texture_set_flags(rt->texture, texture->flags);
|
||||
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);
|
||||
|
@ -4651,7 +4752,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);
|
||||
|
@ -4710,6 +4811,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() {
|
||||
|
@ -4911,6 +5026,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);
|
||||
|
@ -5434,6 +5554,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;
|
||||
|
|
|
@ -92,6 +92,8 @@ public:
|
|||
|
||||
bool support_shadow_cubemaps;
|
||||
|
||||
bool multisample_supported;
|
||||
|
||||
GLuint depth_internalformat;
|
||||
GLuint depth_type;
|
||||
|
||||
|
@ -1129,10 +1131,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?
|
||||
|
@ -1179,6 +1185,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),
|
||||
|
|
|
@ -301,7 +301,7 @@ def configure(env):
|
|||
|
||||
env.Append(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):
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue