taisei/src/renderer/glcommon/opengl.c

620 lines
17 KiB
C
Raw Normal View History

/*
* This software is licensed under the terms of the MIT-License
* See COPYING for further information.
* ---
* Copyright (c) 2011-2019, Lukas Weber <laochailan@web.de>.
* Copyright (c) 2012-2019, Andrei Alexeyev <akari@alienslab.net>.
*/
#include "taisei.h"
#include "util.h"
#include "rwops/rwops_autobuf.h"
#include "opengl.h"
OpenGL ES 3.0 rendering backend (#148) * First steps towards shader transpilation Needs to be manually enabled via -Dshader_transpiler=true. Requires shaderc. https://github.com/google/shaderc Not yet functional due to missing SPIRV-Cross integration. SPIRV-Cross currently does not have an official C API, and crossc is too minimal to be useful. The current plan is to extend crossc and vendor it, while also sending PRs upstream. * Integrate crossc; shader transpilation for GLES now works * fix leak * gles30 backend now playable on Mesa with 3.2 context Some rendering issues are present. Identified so far: - Marisa's lasers are invisible - Death effect looks wrong Also, a small pixmap manipulation library has been written, and the texture uploading API redesigned around it. * fix marisa lasers in GLES (uniform name clashed with builtin) * fix player death effect in GLES (another name clash) * Dump ANGLE's translated shader code in debug log * fix screenshots * Drop support for triangle fans, switch to strips Fans offer no advantage over strips, and they've been removed in D3D10+, so ANGLE has to emulate them. * crude workaround for an ANGLE bug * Re-enable GL debug labels, fix an issue with them that affected ANGLE (but was always technically a bug) * fix race condition in shaderc initialization * New SDL_RWops interface for vertex buffers * Optimize VBO streaming via buffering updates Measurable performance improvement even with the main gl33 renderer, drastic improvement with ANGLE. * Fix the depth texture binding problem under ANGLE Apparently it hates GL_DEPTH_COMPONENT16 for some reason. Sized internal formats are not supported in GLES 2.0 anyway, so not using them is probably a good idea. * fix GLES2.0 segfault (the backend still doesn't work, though) * dump GL extensions at info log level, not debug * get around a Mesa bug; more correct texture format table for GLES2 * Correct GLES3 texture format table according to the spec Not a Mesa bug after all * require crossc>=1.5.0, fallback to subproject * Request at least 8bit per color channel in GL backends * Forbid lto for static windows builds with shader_transpiler=true * fix edge case segfault * Add basic ANGLE bundling support to the build system Windows only, and no NSIS support yet * Fix various windows-related build system and installer brokenness * Disable gles backends by default * update documentation
2018-10-02 00:36:10 +02:00
#include "debug.h"
#include "shaders.h"
struct glext_s glext;
typedef void (*glad_glproc_ptr)(void);
static const char *const ext_vendor_table[] = {
#define TSGL_EXT_VENDOR(v) [_TSGL_EXTVNUM_##v] = #v,
TSGL_EXT_VENDORS
#undef TSGL_EXT_VENDOR
NULL,
};
static ext_flag_t glcommon_ext_flag(const char *ext) {
assert(ext != NULL);
ext = strchr(ext, '_');
if(ext == NULL) {
log_fatal("Bad extension string: %s", ext);
}
const char *sep = strchr(++ext, '_');
if(sep == NULL) {
log_fatal("Bad extension string: %s", ext);
}
char vendor[sep - ext + 1];
strlcpy(vendor, ext, sizeof(vendor));
for(const char *const *p = ext_vendor_table; *p; ++p) {
if(!strcmp(*p, vendor)) {
return 1 << (p - ext_vendor_table);
}
}
log_fatal("Unknown vendor '%s' in extension string %s", vendor, ext);
}
ext_flag_t glcommon_check_extension(const char *ext) {
const char *overrides = env_get("TAISEI_GL_EXT_OVERRIDES", "");
ext_flag_t flag = glcommon_ext_flag(ext);
if(*overrides) {
char buf[strlen(overrides)+1], *save, *arg, *e;
strcpy(buf, overrides);
arg = buf;
while((e = strtok_r(arg, " ", &save))) {
bool r = true;
if(*e == '-') {
++e;
r = false;
}
if(!strcmp(e, ext)) {
return r ? flag : 0;
}
arg = NULL;
}
}
return SDL_GL_ExtensionSupported(ext) ? flag : 0;
}
ext_flag_t glcommon_require_extension(const char *ext) {
ext_flag_t val = glcommon_check_extension(ext);
if(!val) {
if(env_get("TAISEI_GL_REQUIRE_EXTENSION_FATAL", 0)) {
log_fatal("Required extension %s is not available", ext);
}
log_error("Required extension %s is not available, expect crashes or rendering errors", ext);
}
return val;
}
static void glcommon_ext_debug_output(void) {
if(
GL_ATLEAST(4, 3)
&& (glext.DebugMessageCallback = glad_glDebugMessageCallback)
&& (glext.DebugMessageControl = glad_glDebugMessageControl)
&& (glext.ObjectLabel = glad_glObjectLabel)
) {
glext.debug_output = TSGL_EXTFLAG_NATIVE;
log_info("Using core functionality");
return;
}
if(glext.version.is_es) {
if((glext.debug_output = glcommon_check_extension("GL_KHR_debug"))
&& (glext.DebugMessageCallback = glad_glDebugMessageCallbackKHR)
&& (glext.DebugMessageControl = glad_glDebugMessageControlKHR)
&& (glext.ObjectLabel = glad_glObjectLabelKHR)
) {
log_info("Using GL_KHR_debug");
return;
}
} else {
if((glext.debug_output = glcommon_check_extension("GL_KHR_debug"))
&& (glext.DebugMessageCallback = glad_glDebugMessageCallback)
&& (glext.DebugMessageControl = glad_glDebugMessageControl)
&& (glext.ObjectLabel = glad_glObjectLabel)
) {
log_info("Using GL_KHR_debug");
return;
}
}
if((glext.debug_output = glcommon_check_extension("GL_ARB_debug_output"))
&& (glext.DebugMessageCallback = glad_glDebugMessageCallbackARB)
&& (glext.DebugMessageControl = glad_glDebugMessageControlARB)
) {
log_info("Using GL_ARB_debug_output");
return;
}
glext.debug_output = 0;
log_warn("Extension not supported");
}
static void glcommon_ext_base_instance(void) {
if(
GL_ATLEAST(4, 2)
&& (glext.DrawArraysInstancedBaseInstance = glad_glDrawArraysInstancedBaseInstance)
&& (glext.DrawElementsInstancedBaseInstance = glad_glDrawElementsInstancedBaseInstance)
) {
glext.base_instance = TSGL_EXTFLAG_NATIVE;
log_info("Using core functionality");
return;
}
if((glext.base_instance = glcommon_check_extension("GL_ARB_base_instance"))
&& (glext.DrawArraysInstancedBaseInstance = glad_glDrawArraysInstancedBaseInstance)
&& (glext.DrawElementsInstancedBaseInstance = glad_glDrawElementsInstancedBaseInstance)
) {
log_info("Using GL_ARB_base_instance");
return;
}
if((glext.base_instance = glcommon_check_extension("GL_EXT_base_instance"))
&& (glext.DrawArraysInstancedBaseInstance = glad_glDrawArraysInstancedBaseInstanceEXT)
&& (glext.DrawElementsInstancedBaseInstance = glad_glDrawElementsInstancedBaseInstanceEXT)
) {
log_info("Using GL_EXT_base_instance");
return;
}
glext.base_instance = 0;
log_warn("Extension not supported");
}
static void glcommon_ext_pixel_buffer_object(void) {
// TODO: verify that these requirements are correct
if(GL_ATLEAST(2, 0) || GLES_ATLEAST(3, 0)) {
glext.pixel_buffer_object = TSGL_EXTFLAG_NATIVE;
log_info("Using core functionality");
return;
}
const char *exts[] = {
"GL_ARB_pixel_buffer_object",
"GL_EXT_pixel_buffer_object",
"GL_NV_pixel_buffer_object",
NULL
};
for(const char **p = exts; *p; ++p) {
if((glext.pixel_buffer_object = glcommon_check_extension(*p))) {
log_info("Using %s", *p);
return;
}
}
glext.pixel_buffer_object = 0;
log_warn("Extension not supported");
}
static void glcommon_ext_depth_texture(void) {
// TODO: detect this for core OpenGL properly
if(!glext.version.is_es || GLES_ATLEAST(3, 0)) {
glext.depth_texture = TSGL_EXTFLAG_NATIVE;
log_info("Using core functionality");
return;
}
const char *exts[] = {
"GL_OES_depth_texture",
"GL_ANGLE_depth_texture",
NULL
};
for(const char **p = exts; *p; ++p) {
if((glext.pixel_buffer_object = glcommon_check_extension(*p))) {
log_info("Using %s", *p);
return;
}
}
glext.depth_texture = 0;
log_warn("Extension not supported");
}
static void glcommon_ext_instanced_arrays(void) {
if(
(GL_ATLEAST(3, 3) || GLES_ATLEAST(3, 0))
&& (glext.DrawArraysInstanced = glad_glDrawArraysInstanced)
&& (glext.DrawElementsInstanced = glad_glDrawElementsInstanced)
&& (glext.VertexAttribDivisor = glad_glVertexAttribDivisor)
) {
glext.instanced_arrays = TSGL_EXTFLAG_NATIVE;
log_info("Using core functionality");
return;
}
if((glext.instanced_arrays = glcommon_check_extension("GL_ARB_instanced_arrays"))
&& (glext.DrawArraysInstanced = glad_glDrawArraysInstancedARB)
&& (glext.DrawElementsInstanced = glad_glDrawElementsInstancedARB)
&& (glext.VertexAttribDivisor = glad_glVertexAttribDivisorARB)
) {
log_info("Using GL_ARB_instanced_arrays (GL_ARB_draw_instanced assumed)");
return;
}
if((glext.instanced_arrays = glcommon_check_extension("GL_EXT_instanced_arrays"))
&& (glext.DrawArraysInstanced = glad_glDrawArraysInstancedEXT)
&& (glext.DrawElementsInstanced = glad_glDrawElementsInstancedEXT)
&& (glext.VertexAttribDivisor = glad_glVertexAttribDivisorEXT)
) {
log_info("Using GL_EXT_instanced_arrays");
return;
}
if((glext.instanced_arrays = glcommon_check_extension("GL_ANGLE_instanced_arrays"))
&& (glext.DrawArraysInstanced = glad_glDrawArraysInstancedANGLE)
&& (glext.DrawElementsInstanced = glad_glDrawElementsInstancedANGLE)
&& (glext.VertexAttribDivisor = glad_glVertexAttribDivisorANGLE)
) {
log_info("Using GL_ANGLE_instanced_arrays");
return;
}
if((glext.instanced_arrays = glcommon_check_extension("GL_NV_instanced_arrays"))
&& (glext.DrawArraysInstanced = glad_glDrawArraysInstancedNV)
&& (glext.DrawElementsInstanced = glad_glDrawElementsInstancedNV)
&& (glext.VertexAttribDivisor = glad_glVertexAttribDivisorNV)
) {
log_info("Using GL_NV_instanced_arrays (GL_NV_draw_instanced assumed)");
return;
}
glext.instanced_arrays = 0;
log_warn("Extension not supported");
}
static void glcommon_ext_draw_buffers(void) {
if(
(GL_ATLEAST(2, 0) || GLES_ATLEAST(3, 0))
&& (glext.DrawBuffers = glad_glDrawBuffers)
) {
glext.draw_buffers = TSGL_EXTFLAG_NATIVE;
log_info("Using core functionality");
return;
}
if((glext.instanced_arrays = glcommon_check_extension("GL_ARB_draw_buffers"))
&& (glext.DrawBuffers = glad_glDrawBuffersARB)
) {
log_info("Using GL_ARB_draw_buffers");
return;
}
if((glext.instanced_arrays = glcommon_check_extension("GL_EXT_draw_buffers"))
&& (glext.DrawBuffers = glad_glDrawBuffersEXT)
) {
log_info("Using GL_EXT_draw_buffers");
return;
}
glext.draw_buffers = 0;
log_warn("Extension not supported");
}
static void glcommon_ext_texture_filter_anisotropic(void) {
if(GL_ATLEAST(4, 6)) {
glext.texture_filter_anisotropic = TSGL_EXTFLAG_NATIVE;
log_info("Using core functionality");
return;
}
if((glext.texture_filter_anisotropic = glcommon_check_extension("GL_ARB_texture_filter_anisotropic"))) {
log_info("Using ARB_texture_filter_anisotropic");
return;
}
if((glext.texture_filter_anisotropic = glcommon_check_extension("GL_EXT_texture_filter_anisotropic"))) {
log_info("Using EXT_texture_filter_anisotropic");
return;
}
glext.texture_filter_anisotropic = 0;
log_warn("Extension not supported");
}
static void glcommon_ext_clear_texture(void) {
if(GL_ATLEAST(4, 4)) {
glext.clear_texture = TSGL_EXTFLAG_NATIVE;
log_info("Using core functionality");
return;
}
if((glext.clear_texture = glcommon_check_extension("GL_ARB_clear_texture"))) {
log_info("Using GL_ARB_clear_texture");
return;
}
glext.clear_texture = 0;
log_warn("Extension not supported");
}
static void glcommon_ext_texture_norm16(void) {
if(!glext.version.is_es) {
glext.texture_norm16 = TSGL_EXTFLAG_NATIVE;
log_info("Using core functionality");
return;
}
if((glext.texture_norm16 = glcommon_check_extension("GL_EXT_texture_norm16"))) {
log_info("Using GL_EXT_texture_norm16");
return;
}
glext.texture_norm16 = 0;
log_warn("Extension not supported");
}
static void glcommon_ext_texture_rg(void) {
if(!glext.version.is_es) {
glext.texture_rg = TSGL_EXTFLAG_NATIVE;
log_info("Using core functionality");
return;
}
if((glext.texture_rg = glcommon_check_extension("GL_EXT_texture_rg"))) {
log_info("Using GL_EXT_texture_rg");
return;
}
glext.texture_rg = 0;
log_warn("Extension not supported");
}
static void glcommon_ext_texture_float_linear(void) {
if(!glext.version.is_es) {
glext.texture_float_linear = TSGL_EXTFLAG_NATIVE;
log_info("Using core functionality");
return;
}
if((glext.texture_float_linear = glcommon_check_extension("GL_OES_texture_float_linear"))) {
log_info("Using GL_OES_texture_float_linear");
return;
}
glext.texture_float_linear = 0;
log_warn("Extension not supported");
}
static void glcommon_ext_texture_half_float_linear(void) {
if(!glext.version.is_es) {
glext.texture_half_float_linear = TSGL_EXTFLAG_NATIVE;
log_info("Using core functionality");
return;
}
if((glext.texture_half_float_linear = glcommon_check_extension("GL_OES_texture_half_float_linear"))) {
log_info("Using GL_OES_texture_half_float_linear");
return;
}
glext.texture_half_float_linear = 0;
log_warn("Extension not supported");
}
static void glcommon_ext_color_buffer_float(void) {
if(!glext.version.is_es) {
glext.color_buffer_float = TSGL_EXTFLAG_NATIVE;
log_info("Using core functionality");
return;
}
if((glext.color_buffer_float = glcommon_check_extension("GL_EXT_color_buffer_float"))) {
log_info("Using GL_EXT_color_buffer_float");
return;
}
glext.color_buffer_float = 0;
log_warn("Extension not supported");
}
static void glcommon_ext_float_blend(void) {
if(!glext.version.is_es) {
glext.float_blend = TSGL_EXTFLAG_NATIVE;
log_info("Using core functionality");
return;
}
if((glext.float_blend = glcommon_check_extension("GL_EXT_float_blend"))) {
log_info("Using GL_EXT_float_blend");
return;
}
glext.float_blend = 0;
log_warn("Extension not supported");
}
static void glcommon_ext_vertex_array_object(void) {
if((GL_ATLEAST(3, 0) || GLES_ATLEAST(3, 0))
&& (glext.BindVertexArray = glad_glBindVertexArray)
&& (glext.DeleteVertexArrays = glad_glDeleteVertexArrays)
&& (glext.GenVertexArrays = glad_glGenVertexArrays)
&& (glext.IsVertexArray = glad_glIsVertexArray)
) {
glext.vertex_array_object = TSGL_EXTFLAG_NATIVE;
log_info("Using core functionality");
return;
}
if((glext.vertex_array_object = glcommon_check_extension("GL_ARB_vertex_array_object"))
&& (glext.BindVertexArray = glad_glBindVertexArray)
&& (glext.DeleteVertexArrays = glad_glDeleteVertexArrays)
&& (glext.GenVertexArrays = glad_glGenVertexArrays)
&& (glext.IsVertexArray = glad_glIsVertexArray)
) {
log_info("Using GL_ARB_vertex_array_object");
return;
}
if((glext.vertex_array_object = glcommon_check_extension("GL_OES_vertex_array_object"))
&& (glext.BindVertexArray = glad_glBindVertexArrayOES)
&& (glext.DeleteVertexArrays = glad_glDeleteVertexArraysOES)
&& (glext.GenVertexArrays = glad_glGenVertexArraysOES)
&& (glext.IsVertexArray = glad_glIsVertexArrayOES)
) {
log_info("Using GL_OES_vertex_array_object");
return;
}
if((glext.vertex_array_object = glcommon_check_extension("GL_APPLE_vertex_array_object"))
&& (glext.BindVertexArray = glad_glBindVertexArrayAPPLE)
&& (glext.DeleteVertexArrays = glad_glDeleteVertexArraysAPPLE)
&& (glext.GenVertexArrays = glad_glGenVertexArraysAPPLE)
&& (glext.IsVertexArray = glad_glIsVertexArrayAPPLE)
) {
log_info("Using GL_APPLE_vertex_array_object");
return;
}
glext.vertex_array_object = 0;
log_warn("Extension not supported");
}
static APIENTRY GLvoid shim_glClearDepth(GLdouble depthval) {
glClearDepthf(depthval);
}
static APIENTRY GLvoid shim_glClearDepthf(GLfloat depthval) {
glClearDepth(depthval);
}
void glcommon_check_extensions(void) {
memset(&glext, 0, sizeof(glext));
glext.version.major = GLVersion.major;
glext.version.minor = GLVersion.minor;
const char *glslv = (const char*)glGetString(GL_SHADING_LANGUAGE_VERSION);
const char *glv = (const char*)glGetString(GL_VERSION);
if(!glslv) {
glslv = "None";
}
glext.version.is_es = strstartswith(glv, "OpenGL ES");
OpenGL ES 3.0 rendering backend (#148) * First steps towards shader transpilation Needs to be manually enabled via -Dshader_transpiler=true. Requires shaderc. https://github.com/google/shaderc Not yet functional due to missing SPIRV-Cross integration. SPIRV-Cross currently does not have an official C API, and crossc is too minimal to be useful. The current plan is to extend crossc and vendor it, while also sending PRs upstream. * Integrate crossc; shader transpilation for GLES now works * fix leak * gles30 backend now playable on Mesa with 3.2 context Some rendering issues are present. Identified so far: - Marisa's lasers are invisible - Death effect looks wrong Also, a small pixmap manipulation library has been written, and the texture uploading API redesigned around it. * fix marisa lasers in GLES (uniform name clashed with builtin) * fix player death effect in GLES (another name clash) * Dump ANGLE's translated shader code in debug log * fix screenshots * Drop support for triangle fans, switch to strips Fans offer no advantage over strips, and they've been removed in D3D10+, so ANGLE has to emulate them. * crude workaround for an ANGLE bug * Re-enable GL debug labels, fix an issue with them that affected ANGLE (but was always technically a bug) * fix race condition in shaderc initialization * New SDL_RWops interface for vertex buffers * Optimize VBO streaming via buffering updates Measurable performance improvement even with the main gl33 renderer, drastic improvement with ANGLE. * Fix the depth texture binding problem under ANGLE Apparently it hates GL_DEPTH_COMPONENT16 for some reason. Sized internal formats are not supported in GLES 2.0 anyway, so not using them is probably a good idea. * fix GLES2.0 segfault (the backend still doesn't work, though) * dump GL extensions at info log level, not debug * get around a Mesa bug; more correct texture format table for GLES2 * Correct GLES3 texture format table according to the spec Not a Mesa bug after all * require crossc>=1.5.0, fallback to subproject * Request at least 8bit per color channel in GL backends * Forbid lto for static windows builds with shader_transpiler=true * fix edge case segfault * Add basic ANGLE bundling support to the build system Windows only, and no NSIS support yet * Fix various windows-related build system and installer brokenness * Disable gles backends by default * update documentation
2018-10-02 00:36:10 +02:00
if(glext.version.is_es) {
glext.version.is_ANGLE = strstr(glv, "(ANGLE ");
Emscripten compatibility (#161) * Major refactoring of the main loop(s) and control flow (WIP) run_at_fps() is gone 🦀 Instead of nested blocking event loops, there is now an eventloop API that manages an explicit stack of scenes. This makes Taisei a lot more portable to async environments where spinning a loop forever without yielding control simply is not an option, and that is the entire point of this change. A prime example of such an environment is the Web (via emscripten). Taisei was able to run there through a terrible hack: inserting emscripten_sleep calls into the loop, which would yield to the browser. This has several major drawbacks: first of all, every function that could possibly call emscripten_sleep must be compiled into a special kind of bytecode, which then has to be interpreted at runtime, *much* slower than JITed WebAssembly. And that includes *everything* down the call stack, too! For more information, see https://emscripten.org/docs/porting/emterpreter.html Even though that method worked well enough for experimenting, despite suboptimal performance, there is another obvious drawback: emscripten_sleep is implemented via setTimeout(), which can be very imprecise and is generally not reliable for fluid animation. Browsers actually have an API specifically for that use case: window.requestAnimationFrame(), but Taisei's original blocking control flow style is simply not compatible with it. Emscripten exposes this API with its emscripten_set_main_loop(), which the eventloop backend now uses on that platform. Unfortunately, C is still C, with no fancy closures or coroutines. With blocking calls into menu/scene loops gone, the control flow is reimplemented via so-called (pun intended) "call chains". That is basically an euphemism for callback hell. With manual memory management and zero type-safety. Not that the menu system wasn't shitty enough already. I'll just keep telling myself that this is all temporary and will be replaced with scripts in v1.4. * improve build system for emscripten + various fixes * squish menu bugs * improve emscripten event loop; disable EMULATE_FUNCTION_POINTER_CASTS Note that stock freetype does not work without EMULATE_FUNCTION_POINTER_CASTS; use a patched version from the "emscripten" branch here: https://github.com/taisei-project/freetype2/tree/emscripten * Enable -Wcast-function-type Calling functions through incompatible pointers is nasal demons and doesn't work in WASM. * webgl: workaround a crash on some browsers * emscripten improvements: * Persist state (config, progress, replays, ...) in local IndexDB * Simpler HTML shell (temporary) * Enable more optimizations * fix build if validate_glsl=false * emscripten: improve asset packaging, with local cache Note that even though there are rules to build audio bundles, audio does *not* work yet. It looks like SDL2_mixer can not work without threads, which is a problem. Yet another reason to write an OpenAL backend - emscripten supports that natively. * emscripten: customize the html shell * emscripten: force "show log" checkbox unchecked initially * emscripten: remove quit shortcut from main menu (since there's no quit) * emscripten: log area fixes * emscripten/webgl: workaround for fullscreen viewport issue * emscripten: implement frameskip * emscripter: improve framerate limiter * align List to at least 8 bytes (shut up warnings) * fix non-emscripten builds * improve fullscreen handling, mainly for emscripten * Workaround to make audio work in chromium emscripten-core/emscripten#6511 * emscripten: better vsync handling; enable vsync & disable fxaa by default
2019-03-09 20:32:32 +01:00
glext.version.is_webgl = strstr(glv, "(WebGL ");
OpenGL ES 3.0 rendering backend (#148) * First steps towards shader transpilation Needs to be manually enabled via -Dshader_transpiler=true. Requires shaderc. https://github.com/google/shaderc Not yet functional due to missing SPIRV-Cross integration. SPIRV-Cross currently does not have an official C API, and crossc is too minimal to be useful. The current plan is to extend crossc and vendor it, while also sending PRs upstream. * Integrate crossc; shader transpilation for GLES now works * fix leak * gles30 backend now playable on Mesa with 3.2 context Some rendering issues are present. Identified so far: - Marisa's lasers are invisible - Death effect looks wrong Also, a small pixmap manipulation library has been written, and the texture uploading API redesigned around it. * fix marisa lasers in GLES (uniform name clashed with builtin) * fix player death effect in GLES (another name clash) * Dump ANGLE's translated shader code in debug log * fix screenshots * Drop support for triangle fans, switch to strips Fans offer no advantage over strips, and they've been removed in D3D10+, so ANGLE has to emulate them. * crude workaround for an ANGLE bug * Re-enable GL debug labels, fix an issue with them that affected ANGLE (but was always technically a bug) * fix race condition in shaderc initialization * New SDL_RWops interface for vertex buffers * Optimize VBO streaming via buffering updates Measurable performance improvement even with the main gl33 renderer, drastic improvement with ANGLE. * Fix the depth texture binding problem under ANGLE Apparently it hates GL_DEPTH_COMPONENT16 for some reason. Sized internal formats are not supported in GLES 2.0 anyway, so not using them is probably a good idea. * fix GLES2.0 segfault (the backend still doesn't work, though) * dump GL extensions at info log level, not debug * get around a Mesa bug; more correct texture format table for GLES2 * Correct GLES3 texture format table according to the spec Not a Mesa bug after all * require crossc>=1.5.0, fallback to subproject * Request at least 8bit per color channel in GL backends * Forbid lto for static windows builds with shader_transpiler=true * fix edge case segfault * Add basic ANGLE bundling support to the build system Windows only, and no NSIS support yet * Fix various windows-related build system and installer brokenness * Disable gles backends by default * update documentation
2018-10-02 00:36:10 +02:00
}
log_info("OpenGL version: %s", glv);
log_info("OpenGL vendor: %s", (const char*)glGetString(GL_VENDOR));
log_info("OpenGL renderer: %s", (const char*)glGetString(GL_RENDERER));
log_info("GLSL version: %s", glslv);
// XXX: this is the legacy way, maybe we shouldn't try this first
const char *exts = (const char*)glGetString(GL_EXTENSIONS);
if(exts) {
OpenGL ES 3.0 rendering backend (#148) * First steps towards shader transpilation Needs to be manually enabled via -Dshader_transpiler=true. Requires shaderc. https://github.com/google/shaderc Not yet functional due to missing SPIRV-Cross integration. SPIRV-Cross currently does not have an official C API, and crossc is too minimal to be useful. The current plan is to extend crossc and vendor it, while also sending PRs upstream. * Integrate crossc; shader transpilation for GLES now works * fix leak * gles30 backend now playable on Mesa with 3.2 context Some rendering issues are present. Identified so far: - Marisa's lasers are invisible - Death effect looks wrong Also, a small pixmap manipulation library has been written, and the texture uploading API redesigned around it. * fix marisa lasers in GLES (uniform name clashed with builtin) * fix player death effect in GLES (another name clash) * Dump ANGLE's translated shader code in debug log * fix screenshots * Drop support for triangle fans, switch to strips Fans offer no advantage over strips, and they've been removed in D3D10+, so ANGLE has to emulate them. * crude workaround for an ANGLE bug * Re-enable GL debug labels, fix an issue with them that affected ANGLE (but was always technically a bug) * fix race condition in shaderc initialization * New SDL_RWops interface for vertex buffers * Optimize VBO streaming via buffering updates Measurable performance improvement even with the main gl33 renderer, drastic improvement with ANGLE. * Fix the depth texture binding problem under ANGLE Apparently it hates GL_DEPTH_COMPONENT16 for some reason. Sized internal formats are not supported in GLES 2.0 anyway, so not using them is probably a good idea. * fix GLES2.0 segfault (the backend still doesn't work, though) * dump GL extensions at info log level, not debug * get around a Mesa bug; more correct texture format table for GLES2 * Correct GLES3 texture format table according to the spec Not a Mesa bug after all * require crossc>=1.5.0, fallback to subproject * Request at least 8bit per color channel in GL backends * Forbid lto for static windows builds with shader_transpiler=true * fix edge case segfault * Add basic ANGLE bundling support to the build system Windows only, and no NSIS support yet * Fix various windows-related build system and installer brokenness * Disable gles backends by default * update documentation
2018-10-02 00:36:10 +02:00
log_info("Supported extensions: %s", exts);
} else {
void *buf;
SDL_RWops *writer = SDL_RWAutoBuffer(&buf, 1024);
GLint num_extensions;
SDL_RWprintf(writer, "Supported extensions:");
glGetIntegerv(GL_NUM_EXTENSIONS, &num_extensions);
for(int i = 0; i < num_extensions; ++i) {
SDL_RWprintf(writer, " %s", (const char*)glGetStringi(GL_EXTENSIONS, i));
}
SDL_WriteU8(writer, 0);
OpenGL ES 3.0 rendering backend (#148) * First steps towards shader transpilation Needs to be manually enabled via -Dshader_transpiler=true. Requires shaderc. https://github.com/google/shaderc Not yet functional due to missing SPIRV-Cross integration. SPIRV-Cross currently does not have an official C API, and crossc is too minimal to be useful. The current plan is to extend crossc and vendor it, while also sending PRs upstream. * Integrate crossc; shader transpilation for GLES now works * fix leak * gles30 backend now playable on Mesa with 3.2 context Some rendering issues are present. Identified so far: - Marisa's lasers are invisible - Death effect looks wrong Also, a small pixmap manipulation library has been written, and the texture uploading API redesigned around it. * fix marisa lasers in GLES (uniform name clashed with builtin) * fix player death effect in GLES (another name clash) * Dump ANGLE's translated shader code in debug log * fix screenshots * Drop support for triangle fans, switch to strips Fans offer no advantage over strips, and they've been removed in D3D10+, so ANGLE has to emulate them. * crude workaround for an ANGLE bug * Re-enable GL debug labels, fix an issue with them that affected ANGLE (but was always technically a bug) * fix race condition in shaderc initialization * New SDL_RWops interface for vertex buffers * Optimize VBO streaming via buffering updates Measurable performance improvement even with the main gl33 renderer, drastic improvement with ANGLE. * Fix the depth texture binding problem under ANGLE Apparently it hates GL_DEPTH_COMPONENT16 for some reason. Sized internal formats are not supported in GLES 2.0 anyway, so not using them is probably a good idea. * fix GLES2.0 segfault (the backend still doesn't work, though) * dump GL extensions at info log level, not debug * get around a Mesa bug; more correct texture format table for GLES2 * Correct GLES3 texture format table according to the spec Not a Mesa bug after all * require crossc>=1.5.0, fallback to subproject * Request at least 8bit per color channel in GL backends * Forbid lto for static windows builds with shader_transpiler=true * fix edge case segfault * Add basic ANGLE bundling support to the build system Windows only, and no NSIS support yet * Fix various windows-related build system and installer brokenness * Disable gles backends by default * update documentation
2018-10-02 00:36:10 +02:00
log_info("%s", (char*)buf);
SDL_RWclose(writer);
}
glcommon_ext_base_instance();
glcommon_ext_clear_texture();
glcommon_ext_color_buffer_float();
glcommon_ext_debug_output();
glcommon_ext_depth_texture();
glcommon_ext_draw_buffers();
glcommon_ext_float_blend();
glcommon_ext_instanced_arrays();
glcommon_ext_pixel_buffer_object();
glcommon_ext_texture_filter_anisotropic();
glcommon_ext_texture_float_linear();
glcommon_ext_texture_half_float_linear();
glcommon_ext_texture_norm16();
glcommon_ext_texture_rg();
glcommon_ext_vertex_array_object();
// GLES has only glClearDepthf
// Core has only glClearDepth until GL 4.1
assert(glClearDepth || glClearDepthf);
if(!glClearDepth) {
glClearDepth = shim_glClearDepth;
}
if(!glClearDepthf) {
glClearDepthf = shim_glClearDepthf;
}
glcommon_build_shader_lang_table();
}
void glcommon_load_library(void) {
const char *lib = env_get("TAISEI_LIBGL", "");
if(!*lib) {
lib = NULL;
}
if(SDL_GL_LoadLibrary(lib) < 0) {
log_fatal("SDL_GL_LoadLibrary() failed: %s", SDL_GetError());
}
}
void glcommon_unload_library(void) {
SDL_GL_UnloadLibrary();
glcommon_free_shader_lang_table();
}
void glcommon_load_functions(void) {
int profile;
if(SDL_GL_GetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, &profile) < 0) {
log_fatal("SDL_GL_GetAttribute() failed: %s", SDL_GetError());
}
if(profile == SDL_GL_CONTEXT_PROFILE_ES) {
if(!gladLoadGLES2Loader(SDL_GL_GetProcAddress)) {
log_fatal("Failed to load OpenGL ES functions");
}
} else {
if(!gladLoadGLLoader(SDL_GL_GetProcAddress)) {
log_fatal("Failed to load OpenGL functions");
}
}
}
OpenGL ES 3.0 rendering backend (#148) * First steps towards shader transpilation Needs to be manually enabled via -Dshader_transpiler=true. Requires shaderc. https://github.com/google/shaderc Not yet functional due to missing SPIRV-Cross integration. SPIRV-Cross currently does not have an official C API, and crossc is too minimal to be useful. The current plan is to extend crossc and vendor it, while also sending PRs upstream. * Integrate crossc; shader transpilation for GLES now works * fix leak * gles30 backend now playable on Mesa with 3.2 context Some rendering issues are present. Identified so far: - Marisa's lasers are invisible - Death effect looks wrong Also, a small pixmap manipulation library has been written, and the texture uploading API redesigned around it. * fix marisa lasers in GLES (uniform name clashed with builtin) * fix player death effect in GLES (another name clash) * Dump ANGLE's translated shader code in debug log * fix screenshots * Drop support for triangle fans, switch to strips Fans offer no advantage over strips, and they've been removed in D3D10+, so ANGLE has to emulate them. * crude workaround for an ANGLE bug * Re-enable GL debug labels, fix an issue with them that affected ANGLE (but was always technically a bug) * fix race condition in shaderc initialization * New SDL_RWops interface for vertex buffers * Optimize VBO streaming via buffering updates Measurable performance improvement even with the main gl33 renderer, drastic improvement with ANGLE. * Fix the depth texture binding problem under ANGLE Apparently it hates GL_DEPTH_COMPONENT16 for some reason. Sized internal formats are not supported in GLES 2.0 anyway, so not using them is probably a good idea. * fix GLES2.0 segfault (the backend still doesn't work, though) * dump GL extensions at info log level, not debug * get around a Mesa bug; more correct texture format table for GLES2 * Correct GLES3 texture format table according to the spec Not a Mesa bug after all * require crossc>=1.5.0, fallback to subproject * Request at least 8bit per color channel in GL backends * Forbid lto for static windows builds with shader_transpiler=true * fix edge case segfault * Add basic ANGLE bundling support to the build system Windows only, and no NSIS support yet * Fix various windows-related build system and installer brokenness * Disable gles backends by default * update documentation
2018-10-02 00:36:10 +02:00
void glcommon_setup_attributes(SDL_GLprofile profile, uint major, uint minor, SDL_GLcontextFlag ctxflags) {
if(glcommon_debug_requested()) {
ctxflags |= SDL_GL_CONTEXT_DEBUG_FLAG;
}
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, profile);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, major);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, minor);
#ifndef __EMSCRIPTEN__
OpenGL ES 3.0 rendering backend (#148) * First steps towards shader transpilation Needs to be manually enabled via -Dshader_transpiler=true. Requires shaderc. https://github.com/google/shaderc Not yet functional due to missing SPIRV-Cross integration. SPIRV-Cross currently does not have an official C API, and crossc is too minimal to be useful. The current plan is to extend crossc and vendor it, while also sending PRs upstream. * Integrate crossc; shader transpilation for GLES now works * fix leak * gles30 backend now playable on Mesa with 3.2 context Some rendering issues are present. Identified so far: - Marisa's lasers are invisible - Death effect looks wrong Also, a small pixmap manipulation library has been written, and the texture uploading API redesigned around it. * fix marisa lasers in GLES (uniform name clashed with builtin) * fix player death effect in GLES (another name clash) * Dump ANGLE's translated shader code in debug log * fix screenshots * Drop support for triangle fans, switch to strips Fans offer no advantage over strips, and they've been removed in D3D10+, so ANGLE has to emulate them. * crude workaround for an ANGLE bug * Re-enable GL debug labels, fix an issue with them that affected ANGLE (but was always technically a bug) * fix race condition in shaderc initialization * New SDL_RWops interface for vertex buffers * Optimize VBO streaming via buffering updates Measurable performance improvement even with the main gl33 renderer, drastic improvement with ANGLE. * Fix the depth texture binding problem under ANGLE Apparently it hates GL_DEPTH_COMPONENT16 for some reason. Sized internal formats are not supported in GLES 2.0 anyway, so not using them is probably a good idea. * fix GLES2.0 segfault (the backend still doesn't work, though) * dump GL extensions at info log level, not debug * get around a Mesa bug; more correct texture format table for GLES2 * Correct GLES3 texture format table according to the spec Not a Mesa bug after all * require crossc>=1.5.0, fallback to subproject * Request at least 8bit per color channel in GL backends * Forbid lto for static windows builds with shader_transpiler=true * fix edge case segfault * Add basic ANGLE bundling support to the build system Windows only, and no NSIS support yet * Fix various windows-related build system and installer brokenness * Disable gles backends by default * update documentation
2018-10-02 00:36:10 +02:00
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 0);
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, ctxflags);
#endif
OpenGL ES 3.0 rendering backend (#148) * First steps towards shader transpilation Needs to be manually enabled via -Dshader_transpiler=true. Requires shaderc. https://github.com/google/shaderc Not yet functional due to missing SPIRV-Cross integration. SPIRV-Cross currently does not have an official C API, and crossc is too minimal to be useful. The current plan is to extend crossc and vendor it, while also sending PRs upstream. * Integrate crossc; shader transpilation for GLES now works * fix leak * gles30 backend now playable on Mesa with 3.2 context Some rendering issues are present. Identified so far: - Marisa's lasers are invisible - Death effect looks wrong Also, a small pixmap manipulation library has been written, and the texture uploading API redesigned around it. * fix marisa lasers in GLES (uniform name clashed with builtin) * fix player death effect in GLES (another name clash) * Dump ANGLE's translated shader code in debug log * fix screenshots * Drop support for triangle fans, switch to strips Fans offer no advantage over strips, and they've been removed in D3D10+, so ANGLE has to emulate them. * crude workaround for an ANGLE bug * Re-enable GL debug labels, fix an issue with them that affected ANGLE (but was always technically a bug) * fix race condition in shaderc initialization * New SDL_RWops interface for vertex buffers * Optimize VBO streaming via buffering updates Measurable performance improvement even with the main gl33 renderer, drastic improvement with ANGLE. * Fix the depth texture binding problem under ANGLE Apparently it hates GL_DEPTH_COMPONENT16 for some reason. Sized internal formats are not supported in GLES 2.0 anyway, so not using them is probably a good idea. * fix GLES2.0 segfault (the backend still doesn't work, though) * dump GL extensions at info log level, not debug * get around a Mesa bug; more correct texture format table for GLES2 * Correct GLES3 texture format table according to the spec Not a Mesa bug after all * require crossc>=1.5.0, fallback to subproject * Request at least 8bit per color channel in GL backends * Forbid lto for static windows builds with shader_transpiler=true * fix edge case segfault * Add basic ANGLE bundling support to the build system Windows only, and no NSIS support yet * Fix various windows-related build system and installer brokenness * Disable gles backends by default * update documentation
2018-10-02 00:36:10 +02:00
}