2018-04-12 16:08:48 +02:00
|
|
|
/*
|
2019-08-03 19:43:48 +02:00
|
|
|
* This software is licensed under the terms of the MIT License.
|
2018-04-12 16:08:48 +02:00
|
|
|
* See COPYING for further information.
|
|
|
|
* ---
|
2019-01-23 21:10:43 +01:00
|
|
|
* Copyright (c) 2011-2019, Lukas Weber <laochailan@web.de>.
|
2019-07-03 20:00:56 +02:00
|
|
|
* Copyright (c) 2012-2019, Andrei Alexeyev <akari@taisei-project.org>.
|
2018-04-12 16:08:48 +02:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include "taisei.h"
|
|
|
|
|
2018-09-14 09:37:20 +02:00
|
|
|
#include "util.h"
|
|
|
|
#include "rwops/rwops_autobuf.h"
|
2018-04-12 16:08:48 +02:00
|
|
|
#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"
|
2018-09-14 09:37:20 +02:00
|
|
|
#include "shaders.h"
|
2018-04-12 16:08:48 +02:00
|
|
|
|
2019-09-09 03:32:22 +02:00
|
|
|
// undef extension abstraction macros
|
|
|
|
#undef glDebugMessageControl
|
|
|
|
#undef glDebugMessageCallback
|
|
|
|
#undef glObjectLabel
|
|
|
|
#undef glDrawArraysInstanced
|
|
|
|
#undef glDrawElementsInstanced
|
|
|
|
#undef glVertexAttribDivisor
|
|
|
|
#undef glDrawArraysInstancedBaseInstance
|
|
|
|
#undef glDrawElementsInstancedBaseInstance
|
|
|
|
#undef glDrawBuffers
|
|
|
|
#undef glClearTexImage
|
|
|
|
// #undef glClearTexSubImage
|
|
|
|
#undef glBindVertexArray
|
|
|
|
#undef glDeleteVertexArrays
|
|
|
|
#undef glGenVertexArrays
|
|
|
|
#undef glIsVertexArray
|
|
|
|
#undef glGetFloati_v
|
|
|
|
#undef glViewportIndexedfv
|
|
|
|
|
2018-04-12 16:08:48 +02:00
|
|
|
struct glext_s glext;
|
|
|
|
|
2018-06-30 22:11:54 +02:00
|
|
|
typedef void (*glad_glproc_ptr)(void);
|
2018-04-12 16:08:48 +02:00
|
|
|
|
2020-02-15 19:58:15 +01:00
|
|
|
#ifndef STATIC_GLES3
|
|
|
|
//
|
|
|
|
// Extension not yet handled by glad
|
|
|
|
//
|
|
|
|
|
|
|
|
// GL_ANGLE_base_vertex_base_instance
|
|
|
|
typedef void (APIENTRYP PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEANGLEPROC)(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount, GLuint baseInstance);
|
|
|
|
static PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEANGLEPROC glad_glDrawArraysInstancedBaseInstanceANGLE;
|
|
|
|
typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEANGLEPROC)(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex, GLuint baseinstance);
|
|
|
|
static PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEANGLEPROC glad_glDrawElementsInstancedBaseVertexBaseInstanceANGLE;
|
|
|
|
|
2020-03-19 04:04:11 +01:00
|
|
|
APIENTRY
|
2020-02-15 19:58:15 +01:00
|
|
|
static void glad_glDrawElementsInstancedBaseInstanceANGLE(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLuint baseinstance) {
|
|
|
|
// shim
|
|
|
|
glad_glDrawElementsInstancedBaseVertexBaseInstanceANGLE(mode, count, type, indices, instancecount, 0, baseinstance);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2020-02-18 04:56:36 +01:00
|
|
|
// WEBGL_debug_renderer_info
|
|
|
|
const GLenum GL_UNMASKED_VENDOR_WEBGL = 0x9245;
|
|
|
|
const GLenum GL_UNMASKED_RENDERER_WEBGL = 0x9246;
|
|
|
|
|
2018-04-12 16:08:48 +02:00
|
|
|
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) {
|
2020-03-19 07:58:51 +01:00
|
|
|
assert(*ext != 0);
|
|
|
|
assert(strchr(ext, ' ') == NULL);
|
|
|
|
|
2018-04-18 00:34:41 +02:00
|
|
|
const char *overrides = env_get("TAISEI_GL_EXT_OVERRIDES", "");
|
2018-04-12 16:08:48 +02:00
|
|
|
ext_flag_t flag = glcommon_ext_flag(ext);
|
|
|
|
|
2018-04-18 00:34:41 +02:00
|
|
|
if(*overrides) {
|
2018-04-12 16:08:48 +02:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-03-19 07:58:51 +01:00
|
|
|
// SDL_GL_ExtensionSupported is stupid and requires dlopen() with emscripten.
|
|
|
|
// Let's reinvent it!
|
|
|
|
|
|
|
|
// SDL does this
|
|
|
|
if(env_get_int(ext, 1) == 0) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifndef STATIC_GLES3
|
|
|
|
if(GL_ATLEAST(3, 0) || GLES_ATLEAST(3, 0))
|
|
|
|
#endif
|
|
|
|
{
|
|
|
|
GLint num_exts = 0;
|
|
|
|
glGetIntegerv(GL_NUM_EXTENSIONS, &num_exts);
|
|
|
|
for(GLint i = 0; i < num_exts; ++i) {
|
|
|
|
const char *e = (const char*)glGetStringi(GL_EXTENSIONS, i);
|
|
|
|
if(!strcmp(ext, e)) {
|
|
|
|
return flag;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifndef STATIC_GLES3
|
|
|
|
// The legacy way
|
|
|
|
const char *extensions = (const char*)glGetString(GL_EXTENSIONS);
|
|
|
|
|
|
|
|
if(!extensions) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
const char *start = extensions;
|
|
|
|
size_t ext_len = strlen(ext);
|
|
|
|
|
|
|
|
for(;;) {
|
|
|
|
const char *where = strstr(start, ext);
|
|
|
|
if(!where) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
const char *term = where + ext_len;
|
|
|
|
|
|
|
|
if(
|
|
|
|
(where == extensions || where[-1] == ' ') &&
|
|
|
|
(*term == ' ' || *term == ' ')
|
|
|
|
) {
|
|
|
|
return flag;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
2018-04-12 16:08:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
ext_flag_t glcommon_require_extension(const char *ext) {
|
|
|
|
ext_flag_t val = glcommon_check_extension(ext);
|
|
|
|
|
|
|
|
if(!val) {
|
2018-04-18 00:34:41 +02:00
|
|
|
if(env_get("TAISEI_GL_REQUIRE_EXTENSION_FATAL", 0)) {
|
2018-04-12 16:08:48 +02:00
|
|
|
log_fatal("Required extension %s is not available", ext);
|
|
|
|
}
|
|
|
|
|
2019-02-14 22:11:27 +01:00
|
|
|
log_error("Required extension %s is not available, expect crashes or rendering errors", ext);
|
2018-04-12 16:08:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return val;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void glcommon_ext_debug_output(void) {
|
2019-09-09 03:32:22 +02:00
|
|
|
#ifndef STATIC_GLES3
|
2018-04-12 16:08:48 +02:00
|
|
|
if(
|
|
|
|
GL_ATLEAST(4, 3)
|
2019-09-09 03:32:22 +02:00
|
|
|
&& (glext.DebugMessageCallback = GL_FUNC(DebugMessageCallback))
|
|
|
|
&& (glext.DebugMessageControl = GL_FUNC(DebugMessageControl))
|
|
|
|
&& (glext.ObjectLabel = GL_FUNC(ObjectLabel))
|
2018-04-12 16:08:48 +02:00
|
|
|
) {
|
|
|
|
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"))
|
2019-09-09 03:32:22 +02:00
|
|
|
&& (glext.DebugMessageCallback = GL_FUNC(DebugMessageCallbackKHR))
|
|
|
|
&& (glext.DebugMessageControl = GL_FUNC(DebugMessageControlKHR))
|
|
|
|
&& (glext.ObjectLabel = GL_FUNC(ObjectLabelKHR))
|
2018-04-12 16:08:48 +02:00
|
|
|
) {
|
|
|
|
log_info("Using GL_KHR_debug");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if((glext.debug_output = glcommon_check_extension("GL_KHR_debug"))
|
2019-09-09 03:32:22 +02:00
|
|
|
&& (glext.DebugMessageCallback = GL_FUNC(DebugMessageCallback))
|
|
|
|
&& (glext.DebugMessageControl = GL_FUNC(DebugMessageControl))
|
|
|
|
&& (glext.ObjectLabel = GL_FUNC(ObjectLabel))
|
2018-04-12 16:08:48 +02:00
|
|
|
) {
|
|
|
|
log_info("Using GL_KHR_debug");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if((glext.debug_output = glcommon_check_extension("GL_ARB_debug_output"))
|
2019-09-09 03:32:22 +02:00
|
|
|
&& (glext.DebugMessageCallback = GL_FUNC(DebugMessageCallbackARB))
|
|
|
|
&& (glext.DebugMessageControl = GL_FUNC(DebugMessageControlARB))
|
2018-04-12 16:08:48 +02:00
|
|
|
) {
|
|
|
|
log_info("Using GL_ARB_debug_output");
|
|
|
|
return;
|
|
|
|
}
|
2019-09-09 03:32:22 +02:00
|
|
|
#endif
|
2018-04-12 16:08:48 +02:00
|
|
|
|
|
|
|
glext.debug_output = 0;
|
|
|
|
log_warn("Extension not supported");
|
|
|
|
}
|
|
|
|
|
|
|
|
static void glcommon_ext_base_instance(void) {
|
2019-09-09 03:32:22 +02:00
|
|
|
#ifndef STATIC_GLES3
|
2018-04-12 16:08:48 +02:00
|
|
|
if(
|
|
|
|
GL_ATLEAST(4, 2)
|
2019-09-09 03:32:22 +02:00
|
|
|
&& (glext.DrawArraysInstancedBaseInstance = GL_FUNC(DrawArraysInstancedBaseInstance))
|
|
|
|
&& (glext.DrawElementsInstancedBaseInstance = GL_FUNC(DrawElementsInstancedBaseInstance))
|
2018-04-12 16:08:48 +02:00
|
|
|
) {
|
|
|
|
glext.base_instance = TSGL_EXTFLAG_NATIVE;
|
|
|
|
log_info("Using core functionality");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if((glext.base_instance = glcommon_check_extension("GL_ARB_base_instance"))
|
2019-09-09 03:32:22 +02:00
|
|
|
&& (glext.DrawArraysInstancedBaseInstance = GL_FUNC(DrawArraysInstancedBaseInstance))
|
|
|
|
&& (glext.DrawElementsInstancedBaseInstance = GL_FUNC(DrawElementsInstancedBaseInstance))
|
2018-04-12 16:08:48 +02:00
|
|
|
) {
|
|
|
|
log_info("Using GL_ARB_base_instance");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if((glext.base_instance = glcommon_check_extension("GL_EXT_base_instance"))
|
2019-09-09 03:32:22 +02:00
|
|
|
&& (glext.DrawArraysInstancedBaseInstance = GL_FUNC(DrawArraysInstancedBaseInstanceEXT))
|
|
|
|
&& (glext.DrawElementsInstancedBaseInstance = GL_FUNC(DrawElementsInstancedBaseInstanceEXT))
|
2018-04-12 16:08:48 +02:00
|
|
|
) {
|
|
|
|
log_info("Using GL_EXT_base_instance");
|
|
|
|
return;
|
|
|
|
}
|
2020-02-15 19:58:15 +01:00
|
|
|
|
|
|
|
if((glext.base_instance = glcommon_check_extension("GL_ANGLE_base_vertex_base_instance"))
|
|
|
|
&& (glext.DrawArraysInstancedBaseInstance = GL_FUNC(DrawArraysInstancedBaseInstanceANGLE))
|
|
|
|
&& (glext.DrawElementsInstancedBaseInstance = GL_FUNC(DrawElementsInstancedBaseInstanceANGLE))
|
|
|
|
) {
|
|
|
|
log_info("Using GL_ANGLE_base_vertex_base_instance");
|
|
|
|
return;
|
|
|
|
}
|
2019-09-09 03:32:22 +02:00
|
|
|
#endif
|
2018-04-12 16:08:48 +02:00
|
|
|
|
|
|
|
glext.base_instance = 0;
|
|
|
|
log_warn("Extension not supported");
|
|
|
|
}
|
|
|
|
|
|
|
|
static void glcommon_ext_pixel_buffer_object(void) {
|
2019-09-09 03:32:22 +02:00
|
|
|
#ifdef STATIC_GLES3
|
|
|
|
glext.pixel_buffer_object = TSGL_EXTFLAG_NATIVE;
|
|
|
|
log_info("Using core functionality");
|
|
|
|
return;
|
|
|
|
#else
|
2018-04-12 16:08:48 +02:00
|
|
|
// 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");
|
2019-09-09 03:32:22 +02:00
|
|
|
#endif
|
2018-04-12 16:08:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static void glcommon_ext_depth_texture(void) {
|
2019-09-09 03:32:22 +02:00
|
|
|
#ifdef STATIC_GLES3
|
|
|
|
glext.depth_texture = TSGL_EXTFLAG_NATIVE;
|
|
|
|
log_info("Using core functionality");
|
|
|
|
return;
|
|
|
|
#else
|
2018-04-12 16:08:48 +02:00
|
|
|
// 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");
|
2019-09-09 03:32:22 +02:00
|
|
|
#endif
|
2018-04-12 16:08:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static void glcommon_ext_instanced_arrays(void) {
|
2019-09-09 03:32:22 +02:00
|
|
|
#ifdef STATIC_GLES3
|
|
|
|
glext.instanced_arrays = TSGL_EXTFLAG_NATIVE;
|
|
|
|
log_info("Using core functionality");
|
|
|
|
return;
|
|
|
|
#else
|
2018-04-12 16:08:48 +02:00
|
|
|
if(
|
2018-09-14 09:37:20 +02:00
|
|
|
(GL_ATLEAST(3, 3) || GLES_ATLEAST(3, 0))
|
2019-09-09 03:32:22 +02:00
|
|
|
&& (glext.DrawArraysInstanced = GL_FUNC(DrawArraysInstanced))
|
|
|
|
&& (glext.DrawElementsInstanced = GL_FUNC(DrawElementsInstanced))
|
|
|
|
&& (glext.VertexAttribDivisor = GL_FUNC(VertexAttribDivisor))
|
2018-04-12 16:08:48 +02:00
|
|
|
) {
|
|
|
|
glext.instanced_arrays = TSGL_EXTFLAG_NATIVE;
|
|
|
|
log_info("Using core functionality");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if((glext.instanced_arrays = glcommon_check_extension("GL_ARB_instanced_arrays"))
|
2019-09-09 03:32:22 +02:00
|
|
|
&& (glext.DrawArraysInstanced = GL_FUNC(DrawArraysInstancedARB))
|
|
|
|
&& (glext.DrawElementsInstanced = GL_FUNC(DrawElementsInstancedARB))
|
|
|
|
&& (glext.VertexAttribDivisor = GL_FUNC(VertexAttribDivisorARB))
|
2018-04-12 16:08:48 +02:00
|
|
|
) {
|
2018-06-30 22:11:54 +02:00
|
|
|
log_info("Using GL_ARB_instanced_arrays (GL_ARB_draw_instanced assumed)");
|
2018-04-12 16:08:48 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if((glext.instanced_arrays = glcommon_check_extension("GL_EXT_instanced_arrays"))
|
2019-09-09 03:32:22 +02:00
|
|
|
&& (glext.DrawArraysInstanced = GL_FUNC(DrawArraysInstancedEXT))
|
|
|
|
&& (glext.DrawElementsInstanced = GL_FUNC(DrawElementsInstancedEXT))
|
|
|
|
&& (glext.VertexAttribDivisor = GL_FUNC(VertexAttribDivisorEXT))
|
2018-04-12 16:08:48 +02:00
|
|
|
) {
|
|
|
|
log_info("Using GL_EXT_instanced_arrays");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if((glext.instanced_arrays = glcommon_check_extension("GL_ANGLE_instanced_arrays"))
|
2019-09-09 03:32:22 +02:00
|
|
|
&& (glext.DrawArraysInstanced = GL_FUNC(DrawArraysInstancedANGLE))
|
|
|
|
&& (glext.DrawElementsInstanced = GL_FUNC(DrawElementsInstancedANGLE))
|
|
|
|
&& (glext.VertexAttribDivisor = GL_FUNC(VertexAttribDivisorANGLE))
|
2018-04-12 16:08:48 +02:00
|
|
|
) {
|
|
|
|
log_info("Using GL_ANGLE_instanced_arrays");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if((glext.instanced_arrays = glcommon_check_extension("GL_NV_instanced_arrays"))
|
2019-09-09 03:32:22 +02:00
|
|
|
&& (glext.DrawArraysInstanced = GL_FUNC(DrawArraysInstancedNV))
|
|
|
|
&& (glext.DrawElementsInstanced = GL_FUNC(DrawElementsInstancedNV))
|
|
|
|
&& (glext.VertexAttribDivisor = GL_FUNC(VertexAttribDivisorNV))
|
2018-04-12 16:08:48 +02:00
|
|
|
) {
|
2018-06-30 22:11:54 +02:00
|
|
|
log_info("Using GL_NV_instanced_arrays (GL_NV_draw_instanced assumed)");
|
2018-04-12 16:08:48 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
glext.instanced_arrays = 0;
|
|
|
|
log_warn("Extension not supported");
|
2019-09-09 03:32:22 +02:00
|
|
|
#endif
|
2018-04-12 16:08:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static void glcommon_ext_draw_buffers(void) {
|
2019-09-09 03:32:22 +02:00
|
|
|
#ifdef STATIC_GLES3
|
|
|
|
glext.draw_buffers = TSGL_EXTFLAG_NATIVE;
|
|
|
|
log_info("Using core functionality");
|
|
|
|
return;
|
|
|
|
#else
|
2018-04-12 16:08:48 +02:00
|
|
|
if(
|
|
|
|
(GL_ATLEAST(2, 0) || GLES_ATLEAST(3, 0))
|
2019-09-09 03:32:22 +02:00
|
|
|
&& (glext.DrawBuffers = GL_FUNC(DrawBuffers))
|
2018-04-12 16:08:48 +02:00
|
|
|
) {
|
|
|
|
glext.draw_buffers = TSGL_EXTFLAG_NATIVE;
|
|
|
|
log_info("Using core functionality");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if((glext.instanced_arrays = glcommon_check_extension("GL_ARB_draw_buffers"))
|
2019-09-09 03:32:22 +02:00
|
|
|
&& (glext.DrawBuffers = GL_FUNC(DrawBuffersARB))
|
2018-04-12 16:08:48 +02:00
|
|
|
) {
|
|
|
|
log_info("Using GL_ARB_draw_buffers");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if((glext.instanced_arrays = glcommon_check_extension("GL_EXT_draw_buffers"))
|
2019-09-09 03:32:22 +02:00
|
|
|
&& (glext.DrawBuffers = GL_FUNC(DrawBuffersEXT))
|
2018-04-12 16:08:48 +02:00
|
|
|
) {
|
|
|
|
log_info("Using GL_EXT_draw_buffers");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
glext.draw_buffers = 0;
|
|
|
|
log_warn("Extension not supported");
|
2019-09-09 03:32:22 +02:00
|
|
|
#endif
|
2018-04-12 16:08:48 +02:00
|
|
|
}
|
|
|
|
|
2018-07-10 11:14:29 +02:00
|
|
|
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");
|
|
|
|
}
|
|
|
|
|
2018-09-14 09:37:20 +02:00
|
|
|
static void glcommon_ext_clear_texture(void) {
|
2019-09-09 03:32:22 +02:00
|
|
|
#ifdef STATIC_GLES3
|
|
|
|
if((glext.clear_texture = glcommon_check_extension("GL_EXT_clear_texture"))) {
|
|
|
|
log_info("Using GL_EXT_clear_texture");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
if(
|
|
|
|
GL_ATLEAST(4, 4)
|
|
|
|
&& (glext.ClearTexImage = GL_FUNC(ClearTexImage))
|
|
|
|
) {
|
2018-09-14 09:37:20 +02:00
|
|
|
glext.clear_texture = TSGL_EXTFLAG_NATIVE;
|
|
|
|
log_info("Using core functionality");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-09-09 03:32:22 +02:00
|
|
|
if((glext.clear_texture = glcommon_check_extension("GL_ARB_clear_texture"))
|
|
|
|
&& (glext.ClearTexImage = GL_FUNC(ClearTexImage))
|
|
|
|
) {
|
2018-09-14 09:37:20 +02:00
|
|
|
log_info("Using GL_ARB_clear_texture");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-09-09 03:32:22 +02:00
|
|
|
if((glext.clear_texture = glcommon_check_extension("GL_EXT_clear_texture"))
|
|
|
|
&& (glext.ClearTexImage = GL_FUNC(ClearTexImageEXT))
|
|
|
|
) {
|
|
|
|
log_info("Using GL_EXT_clear_texture");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2018-09-14 09:37:20 +02:00
|
|
|
glext.clear_texture = 0;
|
|
|
|
log_warn("Extension not supported");
|
|
|
|
}
|
|
|
|
|
2018-10-22 09:20:52 +02:00
|
|
|
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"))) {
|
2018-10-23 09:51:56 +02:00
|
|
|
log_info("Using GL_EXT_texture_norm16");
|
2018-10-22 09:20:52 +02:00
|
|
|
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"))) {
|
2018-10-23 09:51:56 +02:00
|
|
|
log_info("Using GL_EXT_texture_rg");
|
2018-10-22 09:20:52 +02:00
|
|
|
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"))) {
|
2018-10-23 09:51:56 +02:00
|
|
|
log_info("Using GL_OES_texture_float_linear");
|
2018-10-22 09:20:52 +02:00
|
|
|
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"))) {
|
2018-10-23 09:51:56 +02:00
|
|
|
log_info("Using GL_OES_texture_half_float_linear");
|
2018-10-22 09:20:52 +02:00
|
|
|
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"))) {
|
2018-10-23 09:51:56 +02:00
|
|
|
log_info("Using GL_EXT_color_buffer_float");
|
2018-10-22 09:20:52 +02:00
|
|
|
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"))) {
|
2018-10-23 09:51:56 +02:00
|
|
|
log_info("Using GL_EXT_float_blend");
|
2018-10-22 09:20:52 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
glext.float_blend = 0;
|
|
|
|
log_warn("Extension not supported");
|
|
|
|
}
|
|
|
|
|
2018-10-23 09:51:56 +02:00
|
|
|
static void glcommon_ext_vertex_array_object(void) {
|
2019-09-09 03:32:22 +02:00
|
|
|
#ifdef STATIC_GLES3
|
|
|
|
glext.vertex_array_object = TSGL_EXTFLAG_NATIVE;
|
|
|
|
log_info("Using core functionality");
|
|
|
|
return;
|
|
|
|
#else
|
2018-10-23 09:51:56 +02:00
|
|
|
if((GL_ATLEAST(3, 0) || GLES_ATLEAST(3, 0))
|
2019-09-09 03:32:22 +02:00
|
|
|
&& (glext.BindVertexArray = GL_FUNC(BindVertexArray))
|
|
|
|
&& (glext.DeleteVertexArrays = GL_FUNC(DeleteVertexArrays))
|
|
|
|
&& (glext.GenVertexArrays = GL_FUNC(GenVertexArrays))
|
|
|
|
&& (glext.IsVertexArray = GL_FUNC(IsVertexArray))
|
2018-10-23 09:51:56 +02:00
|
|
|
) {
|
|
|
|
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"))
|
2019-09-09 03:32:22 +02:00
|
|
|
&& (glext.BindVertexArray = GL_FUNC(BindVertexArray))
|
|
|
|
&& (glext.DeleteVertexArrays = GL_FUNC(DeleteVertexArrays))
|
|
|
|
&& (glext.GenVertexArrays = GL_FUNC(GenVertexArrays))
|
|
|
|
&& (glext.IsVertexArray = GL_FUNC(IsVertexArray))
|
2018-10-23 09:51:56 +02:00
|
|
|
) {
|
|
|
|
log_info("Using GL_ARB_vertex_array_object");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if((glext.vertex_array_object = glcommon_check_extension("GL_OES_vertex_array_object"))
|
2019-09-09 03:32:22 +02:00
|
|
|
&& (glext.BindVertexArray = GL_FUNC(BindVertexArrayOES))
|
|
|
|
&& (glext.DeleteVertexArrays = GL_FUNC(DeleteVertexArraysOES))
|
|
|
|
&& (glext.GenVertexArrays = GL_FUNC(GenVertexArraysOES))
|
|
|
|
&& (glext.IsVertexArray = GL_FUNC(IsVertexArrayOES))
|
2018-10-23 09:51:56 +02:00
|
|
|
) {
|
|
|
|
log_info("Using GL_OES_vertex_array_object");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if((glext.vertex_array_object = glcommon_check_extension("GL_APPLE_vertex_array_object"))
|
2019-09-09 03:32:22 +02:00
|
|
|
&& (glext.BindVertexArray = GL_FUNC(BindVertexArrayAPPLE))
|
|
|
|
&& (glext.DeleteVertexArrays = GL_FUNC(DeleteVertexArraysAPPLE))
|
|
|
|
&& (glext.GenVertexArrays = GL_FUNC(GenVertexArraysAPPLE))
|
|
|
|
&& (glext.IsVertexArray = GL_FUNC(IsVertexArrayAPPLE))
|
2018-10-23 09:51:56 +02:00
|
|
|
) {
|
|
|
|
log_info("Using GL_APPLE_vertex_array_object");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
glext.vertex_array_object = 0;
|
|
|
|
log_warn("Extension not supported");
|
2019-09-09 03:32:22 +02:00
|
|
|
#endif
|
2018-10-23 09:51:56 +02:00
|
|
|
}
|
|
|
|
|
2019-04-04 01:43:03 +02:00
|
|
|
static void glcommon_ext_viewport_array(void) {
|
2019-09-09 03:32:22 +02:00
|
|
|
#ifndef STATIC_GLES3
|
2019-04-04 01:43:03 +02:00
|
|
|
if((GL_ATLEAST(4, 1))
|
2019-09-09 03:32:22 +02:00
|
|
|
&& (glext.GetFloati_v = GL_FUNC(GetFloati_v))
|
|
|
|
&& (glext.ViewportIndexedfv = GL_FUNC(ViewportIndexedfv))
|
2019-04-04 01:43:03 +02:00
|
|
|
) {
|
|
|
|
glext.viewport_array = TSGL_EXTFLAG_NATIVE;
|
|
|
|
log_info("Using core functionality");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if((glext.viewport_array = glcommon_check_extension("GL_ARB_viewport_array"))
|
2019-09-09 03:32:22 +02:00
|
|
|
&& (glext.GetFloati_v = GL_FUNC(GetFloati_v))
|
|
|
|
&& (glext.ViewportIndexedfv = GL_FUNC(ViewportIndexedfv))
|
2019-04-04 01:43:03 +02:00
|
|
|
) {
|
|
|
|
log_info("Using GL_ARB_viewport_array");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if((glext.viewport_array = glcommon_check_extension("GL_OES_viewport_array"))
|
2019-09-09 03:32:22 +02:00
|
|
|
&& (glext.GetFloati_v = GL_FUNC(GetFloati_vOES))
|
|
|
|
&& (glext.ViewportIndexedfv = GL_FUNC(ViewportIndexedfvOES))
|
2019-04-04 01:43:03 +02:00
|
|
|
) {
|
|
|
|
log_info("Using GL_OES_viewport_array");
|
|
|
|
return;
|
|
|
|
}
|
2019-09-09 03:32:22 +02:00
|
|
|
#endif
|
2019-04-04 01:43:03 +02:00
|
|
|
|
|
|
|
glext.viewport_array = 0;
|
|
|
|
log_warn("Extension not supported");
|
|
|
|
}
|
|
|
|
|
2019-09-09 03:32:22 +02:00
|
|
|
#ifndef STATIC_GLES3
|
2019-02-02 12:25:06 +01:00
|
|
|
static APIENTRY GLvoid shim_glClearDepth(GLdouble depthval) {
|
2018-09-14 09:37:20 +02:00
|
|
|
glClearDepthf(depthval);
|
|
|
|
}
|
|
|
|
|
2019-02-02 12:25:06 +01:00
|
|
|
static APIENTRY GLvoid shim_glClearDepthf(GLfloat depthval) {
|
2018-09-14 09:37:20 +02:00
|
|
|
glClearDepth(depthval);
|
|
|
|
}
|
2019-09-09 03:32:22 +02:00
|
|
|
#endif
|
2018-09-14 09:37:20 +02:00
|
|
|
|
2020-02-18 04:56:36 +01:00
|
|
|
static const char *get_unmasked_property(GLenum prop, bool fallback) {
|
|
|
|
const char *val = NULL;
|
|
|
|
|
|
|
|
if(glext.version.is_webgl) {
|
|
|
|
if(glcommon_check_extension("GL_WEBGL_debug_renderer_info")) {
|
|
|
|
GLenum prop_unmasked;
|
|
|
|
|
|
|
|
switch(prop) {
|
|
|
|
case GL_VENDOR: prop_unmasked = GL_UNMASKED_VENDOR_WEBGL; break;
|
|
|
|
case GL_RENDERER: prop_unmasked = GL_UNMASKED_RENDERER_WEBGL; break;
|
|
|
|
default: UNREACHABLE;
|
|
|
|
}
|
|
|
|
|
|
|
|
val = (const char*)glGetString(prop_unmasked);
|
|
|
|
|
|
|
|
if(!*val) {
|
|
|
|
val = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(val == NULL && fallback) {
|
|
|
|
val = (const char*)glGetString(prop);
|
|
|
|
}
|
|
|
|
|
|
|
|
return val;
|
|
|
|
}
|
|
|
|
|
2019-09-21 15:39:05 +02:00
|
|
|
static void detect_broken_intel_driver(void) {
|
2020-02-20 03:16:28 +01:00
|
|
|
#ifdef TAISEI_BUILDCONF_WINDOWS_ANGLE_INTEL
|
2019-09-21 15:39:05 +02:00
|
|
|
extern DECLSPEC int SDLCALL SDL_ShowMessageBox(const SDL_MessageBoxData *messageboxdata, int *buttonid);
|
|
|
|
|
|
|
|
bool is_broken_intel_driver = (
|
|
|
|
!glext.version.is_es &&
|
|
|
|
strstartswith((const char*)glGetString(GL_VENDOR), "Intel") &&
|
|
|
|
strstr((const char*)glGetString(GL_SHADING_LANGUAGE_VERSION), " - Build ")
|
|
|
|
);
|
|
|
|
|
|
|
|
if(!is_broken_intel_driver) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
int button;
|
|
|
|
SDL_MessageBoxData mbdata = { 0 };
|
|
|
|
|
|
|
|
mbdata.flags = SDL_MESSAGEBOX_WARNING;
|
|
|
|
mbdata.title = "Taisei Project";
|
|
|
|
|
|
|
|
char *msg = strfmt(
|
|
|
|
"Looks like you have a broken OpenGL driver.\n"
|
|
|
|
"Taisei will probably not work correctly, if at all.\n\n"
|
|
|
|
"Starting the game in ANGLE mode should fix the problem, but may introduce slowdown.\n\n"
|
|
|
|
"Restart in ANGLE mode now? (If unsure, press YES)"
|
|
|
|
);
|
|
|
|
|
|
|
|
mbdata.message = msg;
|
|
|
|
mbdata.numbuttons = 3;
|
|
|
|
mbdata.buttons = (SDL_MessageBoxButtonData[]) {
|
|
|
|
{ SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT, 2, "Abort" },
|
|
|
|
{ 0, 1, "No" },
|
|
|
|
{ SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT, 0, "Yes (safe)" },
|
|
|
|
};
|
|
|
|
|
|
|
|
int mbresult = SDL_ShowMessageBox(&mbdata, &button);
|
|
|
|
free(msg);
|
|
|
|
|
|
|
|
if(mbresult < 0) {
|
|
|
|
log_sdl_error(LOG_ERROR, "SDL_ShowMessageBox");
|
|
|
|
} else if(button == 1) {
|
|
|
|
return;
|
|
|
|
} else if(button == 2) {
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
const WCHAR *cmdline = GetCommandLine();
|
|
|
|
const WCHAR renderer_args[] = L" --renderer gles30";
|
|
|
|
WCHAR new_cmdline[wcslen(cmdline) + wcslen(renderer_args) + 1];
|
|
|
|
memcpy(new_cmdline, cmdline, sizeof(WCHAR) * wcslen(cmdline));
|
|
|
|
memcpy(new_cmdline + wcslen(cmdline), renderer_args, sizeof(renderer_args));
|
|
|
|
|
|
|
|
PROCESS_INFORMATION pi;
|
|
|
|
STARTUPINFO si = { sizeof(si) };
|
|
|
|
|
|
|
|
CreateProcessW(
|
|
|
|
NULL,
|
|
|
|
new_cmdline,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
false,
|
|
|
|
0,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
&si,
|
|
|
|
&pi
|
|
|
|
);
|
|
|
|
|
|
|
|
exit(0);
|
2020-02-20 03:16:28 +01:00
|
|
|
|
2019-09-21 15:39:05 +02:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2020-02-18 04:56:36 +01:00
|
|
|
static bool glcommon_check_workaround(const char *name, const char *envvar, const char *(*detect)(void)) {
|
|
|
|
int env_setting = env_get_int(envvar, -1);
|
|
|
|
glext.issues.avoid_sampler_uniform_updates = false;
|
|
|
|
|
|
|
|
if(env_setting > 0) {
|
|
|
|
log_warn("Enabled workaround `%s` (forced by environment)", name);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(env_setting == 0) {
|
|
|
|
log_warn("Disabled workaround `%s` (forced by environment)", name);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
const char *reason = detect();
|
|
|
|
if(reason != NULL) {
|
|
|
|
log_warn("Enabled workaround `%s` (%s)", name, reason);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
log_info("Workaround `%s` not needed", name);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
#if defined(__EMSCRIPTEN__)
|
|
|
|
#include <emscripten.h>
|
|
|
|
EM_JS(bool, webgl_is_mac, (void), {
|
|
|
|
try {
|
|
|
|
return !!navigator.platform.match(/mac/i);
|
|
|
|
} catch(e) {
|
|
|
|
// whatever...
|
|
|
|
return false;
|
|
|
|
}
|
2020-02-18 04:58:08 +01:00
|
|
|
})
|
2020-02-18 04:56:36 +01:00
|
|
|
#endif
|
|
|
|
|
|
|
|
static const char *detect_slow_sampler_update(void) {
|
|
|
|
#if defined(__MACOSX__) || defined(__EMSCRIPTEN__)
|
|
|
|
const char *gl_vendor = get_unmasked_property(GL_VENDOR, true);
|
|
|
|
const char *gl_renderer = get_unmasked_property(GL_RENDERER, true);
|
|
|
|
|
|
|
|
if(
|
|
|
|
#if defined(__EMSCRIPTEN__)
|
|
|
|
webgl_is_mac() &&
|
|
|
|
#endif
|
|
|
|
strstr(gl_renderer, "Radeon") && ( // This looks like an AMD Radeon card...
|
|
|
|
(strstr(gl_vendor, "ATI") || strstr(gl_vendor, "AMD")) || // ...and AMD's official driver...
|
|
|
|
(strstr(gl_vendor, "Google") && strstr(gl_renderer, "OpenGL")) // ...or ANGLE, backed by OpenGL.
|
|
|
|
)
|
|
|
|
) {
|
|
|
|
return "buggy AMD driver on macOS; see https://github.com/taisei-project/taisei/issues/182";
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void glcommon_check_issues(void) {
|
|
|
|
glext.issues.avoid_sampler_uniform_updates = glcommon_check_workaround(
|
|
|
|
"avoid sampler uniform updates",
|
|
|
|
"TAISEI_GL_WORKAROUND_AVOID_SAMPLER_UNIFORM_UPDATES",
|
|
|
|
detect_slow_sampler_update
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2019-09-09 03:32:22 +02:00
|
|
|
void glcommon_check_capabilities(void) {
|
2018-04-12 16:08:48 +02:00
|
|
|
memset(&glext, 0, sizeof(glext));
|
|
|
|
|
|
|
|
const char *glslv = (const char*)glGetString(GL_SHADING_LANGUAGE_VERSION);
|
|
|
|
const char *glv = (const char*)glGetString(GL_VERSION);
|
|
|
|
|
2019-09-09 03:32:22 +02:00
|
|
|
#ifdef STATIC_GLES3
|
|
|
|
GLint major, minor;
|
|
|
|
glGetIntegerv(GL_MAJOR_VERSION, &major);
|
|
|
|
glGetIntegerv(GL_MINOR_VERSION, &minor);
|
|
|
|
glext.version.major = major;
|
|
|
|
glext.version.minor = minor;
|
|
|
|
#else
|
|
|
|
glext.version.major = GLVersion.major;
|
|
|
|
glext.version.minor = GLVersion.minor;
|
|
|
|
#endif
|
|
|
|
|
2018-04-12 16:08:48 +02:00
|
|
|
if(!glslv) {
|
|
|
|
glslv = "None";
|
|
|
|
}
|
|
|
|
|
|
|
|
glext.version.is_es = strstartswith(glv, "OpenGL ES");
|
|
|
|
|
2019-09-09 03:32:22 +02:00
|
|
|
#ifdef STATIC_GLES3
|
|
|
|
if(!GLES_ATLEAST(3, 0)) {
|
|
|
|
log_fatal("Compiled with STATIC_GLES3, but got a non-GLES3 context. Can't work with this");
|
|
|
|
}
|
|
|
|
#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
|
|
|
if(glext.version.is_es) {
|
2019-02-22 07:37:52 +01:00
|
|
|
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
|
|
|
}
|
|
|
|
|
2018-04-12 16:08:48 +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));
|
2020-02-18 04:56:36 +01:00
|
|
|
|
|
|
|
if(glext.version.is_webgl) {
|
|
|
|
const char *unmasked_vendor = get_unmasked_property(GL_VENDOR, false);
|
|
|
|
const char *unmasked_renderer = get_unmasked_property(GL_RENDERER, false);
|
|
|
|
log_info("OpenGL unmasked vendor: %s", unmasked_vendor ? unmasked_vendor : "Unknown");
|
|
|
|
log_info("OpenGL unmasked renderer: %s", unmasked_renderer ? unmasked_renderer : "Unknown");
|
|
|
|
}
|
|
|
|
|
2018-04-12 16:08:48 +02:00
|
|
|
log_info("GLSL version: %s", glslv);
|
|
|
|
|
2019-09-21 15:39:05 +02:00
|
|
|
detect_broken_intel_driver();
|
|
|
|
|
2018-04-12 16:08:48 +02:00
|
|
|
// 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);
|
2018-04-12 16:08:48 +02:00
|
|
|
} 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);
|
2018-04-12 16:08:48 +02:00
|
|
|
SDL_RWclose(writer);
|
|
|
|
}
|
|
|
|
|
|
|
|
glcommon_ext_base_instance();
|
2018-09-14 09:37:20 +02:00
|
|
|
glcommon_ext_clear_texture();
|
2018-10-22 09:20:52 +02:00
|
|
|
glcommon_ext_color_buffer_float();
|
2018-04-12 16:08:48 +02:00
|
|
|
glcommon_ext_debug_output();
|
|
|
|
glcommon_ext_depth_texture();
|
|
|
|
glcommon_ext_draw_buffers();
|
2018-10-22 09:20:52 +02:00
|
|
|
glcommon_ext_float_blend();
|
2018-04-12 16:08:48 +02:00
|
|
|
glcommon_ext_instanced_arrays();
|
|
|
|
glcommon_ext_pixel_buffer_object();
|
2018-07-10 11:14:29 +02:00
|
|
|
glcommon_ext_texture_filter_anisotropic();
|
2018-10-22 09:20:52 +02:00
|
|
|
glcommon_ext_texture_float_linear();
|
|
|
|
glcommon_ext_texture_half_float_linear();
|
|
|
|
glcommon_ext_texture_norm16();
|
|
|
|
glcommon_ext_texture_rg();
|
2018-10-23 09:51:56 +02:00
|
|
|
glcommon_ext_vertex_array_object();
|
2019-04-04 01:43:03 +02:00
|
|
|
glcommon_ext_viewport_array();
|
2018-09-14 09:37:20 +02:00
|
|
|
|
|
|
|
// GLES has only glClearDepthf
|
|
|
|
// Core has only glClearDepth until GL 4.1
|
2019-09-09 03:32:22 +02:00
|
|
|
#ifndef STATIC_GLES3
|
2018-09-14 09:37:20 +02:00
|
|
|
assert(glClearDepth || glClearDepthf);
|
|
|
|
|
|
|
|
if(!glClearDepth) {
|
|
|
|
glClearDepth = shim_glClearDepth;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!glClearDepthf) {
|
|
|
|
glClearDepthf = shim_glClearDepthf;
|
|
|
|
}
|
2019-09-09 03:32:22 +02:00
|
|
|
#endif
|
2018-09-14 09:37:20 +02:00
|
|
|
|
|
|
|
glcommon_build_shader_lang_table();
|
2020-02-18 04:56:36 +01:00
|
|
|
glcommon_check_issues();
|
2018-04-12 16:08:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void glcommon_load_library(void) {
|
2019-09-09 03:32:22 +02:00
|
|
|
#ifndef STATIC_GLES3
|
2018-04-18 00:34:41 +02:00
|
|
|
const char *lib = env_get("TAISEI_LIBGL", "");
|
2018-04-12 16:08:48 +02:00
|
|
|
|
2018-04-18 00:34:41 +02:00
|
|
|
if(!*lib) {
|
2018-04-12 16:08:48 +02:00
|
|
|
lib = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(SDL_GL_LoadLibrary(lib) < 0) {
|
|
|
|
log_fatal("SDL_GL_LoadLibrary() failed: %s", SDL_GetError());
|
|
|
|
}
|
2019-09-09 03:32:22 +02:00
|
|
|
#endif
|
2018-04-12 16:08:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void glcommon_unload_library(void) {
|
2019-09-09 03:32:22 +02:00
|
|
|
#ifndef STATIC_GLES3
|
2018-04-12 16:08:48 +02:00
|
|
|
SDL_GL_UnloadLibrary();
|
2019-09-09 03:32:22 +02:00
|
|
|
#endif
|
2018-09-14 09:37:20 +02:00
|
|
|
glcommon_free_shader_lang_table();
|
2018-04-12 16:08:48 +02:00
|
|
|
}
|
|
|
|
|
2020-03-19 07:58:51 +01:00
|
|
|
attr_unused
|
2020-03-08 17:55:46 +01:00
|
|
|
static inline void (*load_func(const char *name))(void) {
|
|
|
|
union {
|
|
|
|
void *vp;
|
|
|
|
void (*fp)(void);
|
|
|
|
} c_sucks;
|
|
|
|
c_sucks.vp = SDL_GL_GetProcAddress(name);
|
|
|
|
return c_sucks.fp;
|
|
|
|
}
|
|
|
|
|
2018-04-12 16:08:48 +02:00
|
|
|
void glcommon_load_functions(void) {
|
2019-09-09 03:32:22 +02:00
|
|
|
#ifndef STATIC_GLES3
|
2018-06-30 22:11:54 +02:00
|
|
|
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");
|
|
|
|
}
|
|
|
|
}
|
2020-02-15 19:58:15 +01:00
|
|
|
|
2020-03-08 17:55:46 +01:00
|
|
|
glad_glDrawArraysInstancedBaseInstanceANGLE = (PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEANGLEPROC)load_func("glDrawArraysInstancedBaseInstanceANGLE");
|
|
|
|
glad_glDrawElementsInstancedBaseVertexBaseInstanceANGLE = (PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEANGLEPROC)load_func("glDrawElementsInstancedBaseVertexBaseInstanceANGLE");
|
2019-09-09 03:32:22 +02:00
|
|
|
#endif
|
2018-04-12 16:08:48 +02:00
|
|
|
}
|
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;
|
|
|
|
}
|
|
|
|
|
2019-02-22 00:56:48 +01:00
|
|
|
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);
|
2019-02-22 00:56:48 +01:00
|
|
|
#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
|
|
|
}
|