Many more fixes for GLES2 mobile export. Also added ability to turn on OpenGL debugging on Android export.
This commit is contained in:
parent
0b73a9e403
commit
bad991ea83
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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+
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue