Many more fixes for GLES2 mobile export. Also added ability to turn on OpenGL debugging on Android export.

This commit is contained in:
Juan Linietsky 2018-10-02 09:59:25 -03:00
parent 0b73a9e403
commit bad991ea83
8 changed files with 117 additions and 27 deletions

View File

@ -64,6 +64,16 @@
#define GLAPIENTRY
#endif
#ifndef GLES_OVER_GL
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
#include <GLES2/gl2platform.h>
#include <EGL/egl.h>
#include <EGL/eglext.h>
#endif
static void GLAPIENTRY _gl_debug_print(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, const GLvoid *userParam) {
if (type == _EXT_DEBUG_TYPE_OTHER_ARB)
@ -191,7 +201,7 @@ void RasterizerGLES2::initialize() {
print_verbose("Using GLES2 video driver");
#ifdef GLAD_ENABLED
if (true || OS::get_singleton()->is_stdout_verbose()) {
if (OS::get_singleton()->is_stdout_verbose()) {
if (GLAD_GL_ARB_debug_output) {
glEnable(_EXT_DEBUG_OUTPUT_SYNCHRONOUS_ARB);
glDebugMessageCallbackARB(_gl_debug_print, NULL);
@ -204,7 +214,7 @@ void RasterizerGLES2::initialize() {
// For debugging
#ifdef GLES_OVER_GL
if (GLAD_GL_ARB_debug_output) {
if (OS::get_singleton()->is_stdout_verbose() && GLAD_GL_ARB_debug_output) {
glDebugMessageControlARB(_EXT_DEBUG_SOURCE_API_ARB, _EXT_DEBUG_TYPE_ERROR_ARB, _EXT_DEBUG_SEVERITY_HIGH_ARB, 0, NULL, GL_TRUE);
glDebugMessageControlARB(_EXT_DEBUG_SOURCE_API_ARB, _EXT_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB, _EXT_DEBUG_SEVERITY_HIGH_ARB, 0, NULL, GL_TRUE);
glDebugMessageControlARB(_EXT_DEBUG_SOURCE_API_ARB, _EXT_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB, _EXT_DEBUG_SEVERITY_HIGH_ARB, 0, NULL, GL_TRUE);
@ -217,6 +227,22 @@ void RasterizerGLES2::initialize() {
GL_DEBUG_SEVERITY_HIGH_ARB, 5, "hello");
*/
}
#else
if (OS::get_singleton()->is_stdout_verbose()) {
DebugMessageCallbackARB callback = (DebugMessageCallbackARB)eglGetProcAddress("glDebugMessageCallback");
if (!callback) {
callback = (DebugMessageCallbackARB)eglGetProcAddress("glDebugMessageCallbackKHR");
}
if (callback) {
print_line("godot: ENABLING GL DEBUG");
glEnable(_EXT_DEBUG_OUTPUT_SYNCHRONOUS_ARB);
callback(_gl_debug_print, NULL);
glEnable(_EXT_DEBUG_OUTPUT);
}
}
#endif
const GLubyte *renderer = glGetString(GL_RENDERER);

View File

@ -42,6 +42,8 @@
#define glClearDepth glClearDepthf
#endif
#define _DEPTH_COMPONENT24_OES 0x81A6
static const GLenum _cube_side_enum[6] = {
GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
@ -461,7 +463,8 @@ RID RasterizerSceneGLES2::reflection_probe_instance_create(RID p_probe) {
glGenFramebuffers(1, &rpi->fbo_blur);
glGenRenderbuffers(1, &rpi->depth);
glGenTextures(1, &rpi->cubemap);
rpi->cubemap = 0;
//glGenTextures(1, &rpi->cubemap);
return rpi->self;
}
@ -502,14 +505,37 @@ bool RasterizerSceneGLES2::reflection_probe_instance_begin_render(RID p_instance
int size = rpi->probe_ptr->resolution;
rpi->current_resolution = size;
int lod = 0;
GLenum internal_format = GL_RGBA;
GLenum format = GL_RGBA;
GLenum internal_format = GL_RGB;
GLenum format = GL_RGB;
GLenum type = GL_UNSIGNED_BYTE;
glActiveTexture(GL_TEXTURE0);
if (rpi->cubemap != 0) {
glDeleteTextures(1, &rpi->cubemap);
}
glGenTextures(1, &rpi->cubemap);
glBindTexture(GL_TEXTURE_CUBE_MAP, rpi->cubemap);
#if 1
//Mobile hardware (PowerVR specially) prefers this approach, the other one kills the game
for (int i = 0; i < 6; i++) {
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, internal_format, size, size, 0, format, type, NULL);
}
glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
glBindRenderbuffer(GL_RENDERBUFFER, rpi->depth); //resize depth buffer
glRenderbufferStorage(GL_RENDERBUFFER, _DEPTH_COMPONENT24_OES, size, size);
for (int i = 0; i < 6; i++) {
glBindFramebuffer(GL_FRAMEBUFFER, rpi->fbo[i]);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, _cube_side_enum[i], rpi->cubemap, 0);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rpi->depth);
}
#else
int lod = 0;
//the approach below is fatal for powervr
// Set the initial (empty) mipmaps, all need to be set for this to work in GLES2, even if later wont be used.
while (size >= 1) {
@ -521,7 +547,7 @@ bool RasterizerSceneGLES2::reflection_probe_instance_begin_render(RID p_instance
glBindFramebuffer(GL_FRAMEBUFFER, rpi->fbo[i]);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, _cube_side_enum[i], rpi->cubemap, 0);
glBindRenderbuffer(GL_RENDERBUFFER, rpi->depth);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, size, size);
glRenderbufferStorage(GL_RENDERBUFFER, _DEPTH_COMPONENT24_OES, size, size);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rpi->depth);
#ifdef DEBUG_ENABLED
@ -535,7 +561,7 @@ bool RasterizerSceneGLES2::reflection_probe_instance_begin_render(RID p_instance
size >>= 1;
}
#endif
glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
@ -2540,7 +2566,6 @@ void RasterizerSceneGLES2::render_scene(const Transform &p_cam_transform, const
_render_render_list(&render_list.elements[render_list.max_elements - render_list.alpha_element_count], render_list.alpha_element_count, p_cam_transform, p_cam_projection, p_shadow_atlas, env, env_radiance_tex, 0.0, 0.0, false, true, false);
glDepthMask(GL_FALSE);
glDisable(GL_DEPTH_TEST);
//#define GLES2_SHADOW_ATLAS_DEBUG_VIEW
@ -2984,7 +3009,7 @@ void RasterizerSceneGLES2::initialize() {
glBindTexture(GL_TEXTURE_CUBE_MAP, cube.cubemap);
for (int i = 0; i < 6; i++) {
glTexImage2D(_cube_side_enum[i], 0, GL_DEPTH_COMPONENT, cube_size, cube_size, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, NULL);
glTexImage2D(_cube_side_enum[i], 0, GL_DEPTH_COMPONENT, cube_size, cube_size, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL);
}
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

View File

@ -901,26 +901,27 @@ void RasterizerStorageGLES2::sky_set_texture(RID p_sky, RID p_panorama, int p_ra
// attachements for it, so we can fill them by issuing draw calls.
GLuint tmp_fb;
glGenFramebuffers(1, &tmp_fb);
glBindFramebuffer(GL_FRAMEBUFFER, tmp_fb);
int size = p_radiance_size;
int lod = 0;
shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES2::USE_SOURCE_PANORAMA, texture->target == GL_TEXTURE_2D);
shaders.cubemap_filter.bind();
int mipmaps = 6;
int mm_level = mipmaps;
GLenum internal_format = GL_RGBA;
GLenum format = GL_RGBA;
GLenum type = GL_UNSIGNED_BYTE; // This is suboptimal... TODO other format for FBO?
GLenum internal_format = GL_RGB;
GLenum format = GL_RGB;
GLenum type = GL_UNSIGNED_BYTE;
// Set the initial (empty) mipmaps
#if 1
//Mobile hardware (PowerVR specially) prefers this approach, the other one kills the game
for (int i = 0; i < 6; i++) {
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, internal_format, size, size, 0, format, type, NULL);
}
glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
#else
while (size >= 1) {
for (int i = 0; i < 6; i++) {
@ -931,7 +932,14 @@ void RasterizerStorageGLES2::sky_set_texture(RID p_sky, RID p_panorama, int p_ra
size >>= 1;
}
#endif
//framebuffer
glGenFramebuffers(1, &tmp_fb);
glBindFramebuffer(GL_FRAMEBUFFER, tmp_fb);
shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES2::USE_SOURCE_PANORAMA, texture->target == GL_TEXTURE_2D);
shaders.cubemap_filter.bind();
lod = 0;
mm_level = mipmaps;

View File

@ -1085,6 +1085,7 @@ public:
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "screen/support_normal"), true));
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "screen/support_large"), true));
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "screen/support_xlarge"), true));
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "screen/opengl_debug"), false));
for (unsigned int i = 0; i < sizeof(launcher_icons) / sizeof(launcher_icons[0]); ++i) {
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, launcher_icons[i].option_id, PROPERTY_HINT_FILE, "*.png"), ""));
@ -1438,6 +1439,7 @@ public:
bool use_32_fb = p_preset->get("graphics/32_bits_framebuffer");
bool immersive = p_preset->get("screen/immersive_mode");
bool debug_opengl = p_preset->get("screen/opengl_debug");
bool _signed = p_preset->get("package/signed");
@ -1639,6 +1641,9 @@ public:
if (immersive)
cl.push_back("--use_immersive");
if (debug_opengl)
cl.push_back("--debug_opengl");
if (cl.size()) {
//add comandline
Vector<uint8_t> clf;

View File

@ -116,6 +116,7 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
private boolean use_32_bits = false;
private boolean use_immersive = false;
private boolean use_debug_opengl = false;
private boolean mStatePaused;
private int mState;
private boolean keep_screen_on = true;
@ -278,7 +279,7 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
// ...add to FrameLayout
layout.addView(edittext);
mView = new GodotView(getApplication(), io, use_gl3, use_32_bits, this);
mView = new GodotView(getApplication(), io, use_gl3, use_32_bits, use_debug_opengl,this);
layout.addView(mView, new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
edittext.setView(mView);
io.setEdit(edittext);
@ -471,6 +472,8 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
boolean has_extra = i < command_line.length - 1;
if (command_line[i].equals("--use_depth_32")) {
use_32_bits = true;
} else if (command_line[i].equals("--debug_opengl")) {
use_debug_opengl = true;
} else if (command_line[i].equals("--use_immersive")) {
use_immersive = true;
if (Build.VERSION.SDK_INT >= 19.0) { // check if the application runs on an android 4.4+

View File

@ -81,16 +81,18 @@ public class GodotView extends GLSurfaceView implements InputDeviceListener {
private static boolean firsttime = true;
private static boolean use_gl3 = false;
private static boolean use_32 = false;
private static boolean use_debug_opengl = false;
private Godot activity;
private InputManagerCompat mInputManager;
public GodotView(Context context, GodotIO p_io, boolean p_use_gl3, boolean p_use_32_bits, Godot p_activity) {
public GodotView(Context context, GodotIO p_io, boolean p_use_gl3, boolean p_use_32_bits, boolean p_use_debug_opengl,Godot p_activity) {
super(context);
ctx = context;
io = p_io;
use_gl3 = p_use_gl3;
use_32 = p_use_32_bits;
use_debug_opengl = p_use_debug_opengl;
activity = p_activity;
@ -406,6 +408,9 @@ public class GodotView extends GLSurfaceView implements InputDeviceListener {
setRenderer(new Renderer());
}
private static final int _EGL_CONTEXT_FLAGS_KHR = 0x30FC;
private static final int _EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR= 0x00000001;
private static class ContextFactory implements GLSurfaceView.EGLContextFactory {
private static int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
public EGLContext createContext(EGL10 egl, EGLDisplay display, EGLConfig eglConfig) {
@ -415,9 +420,16 @@ public class GodotView extends GLSurfaceView implements InputDeviceListener {
Log.w(TAG, "creating OpenGL ES 2.0 context :");
checkEglError("Before eglCreateContext", egl);
int[] attrib_list2 = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE };
int[] attrib_list3 = { EGL_CONTEXT_CLIENT_VERSION, 3, EGL10.EGL_NONE };
EGLContext context = egl.eglCreateContext(display, eglConfig, EGL10.EGL_NO_CONTEXT, use_gl3 ? attrib_list3 : attrib_list2);
EGLContext context;
if (use_debug_opengl) {
int[] attrib_list2 = { EGL_CONTEXT_CLIENT_VERSION, 2,_EGL_CONTEXT_FLAGS_KHR,_EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR, EGL10.EGL_NONE };
int[] attrib_list3 = { EGL_CONTEXT_CLIENT_VERSION, 3,_EGL_CONTEXT_FLAGS_KHR,_EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR, EGL10.EGL_NONE };
context = egl.eglCreateContext(display, eglConfig, EGL10.EGL_NO_CONTEXT, use_gl3 ? attrib_list3 : attrib_list2);
} else {
int[] attrib_list2 = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE };
int[] attrib_list3 = { EGL_CONTEXT_CLIENT_VERSION, 3, EGL10.EGL_NONE };
context = egl.eglCreateContext(display, eglConfig, EGL10.EGL_NO_CONTEXT, use_gl3 ? attrib_list3 : attrib_list2);
}
checkEglError("After eglCreateContext", egl);
return context;
}

View File

@ -734,7 +734,8 @@ void VoxelLightBaker::_check_init_light() {
leaf_voxel_count = 0;
_fixup_plot(0, 0); //pre fixup, so normal, albedo, emission, etc. work for lighting.
bake_light.resize(bake_cells.size());
zeromem(bake_light.ptrw(), bake_light.size() * sizeof(Light));
print_line("bake light size: " + itos(bake_light.size()));
//zeromem(bake_light.ptrw(), bake_light.size() * sizeof(Light));
first_leaf = -1;
_init_light_plot(0, 0, 0, 0, 0, CHILD_EMPTY);
}

View File

@ -92,6 +92,16 @@ private:
float accum[6][3]; //rgb anisotropic
float direct_accum[6][3]; //for direct bake
int next_leaf;
Light() {
x = y = z = 0;
for (int i = 0; i < 6; i++) {
for (int j = 0; j < 3; j++) {
accum[i][j] = 0;
direct_accum[i][j] = 0;
}
}
next_leaf = 0;
}
};
int first_leaf;