taisei/src/taiseigl.c
Andrei "Akari" Alexeyev 0091c7aca7 Refactored the gl loader into a polyglot macro monstrosity
We no longer link to libGL by default. All GL functions are loaded
dynamically through SDL apis. Use -DLINK_TO_LIBGL to enable linking, in
which case Taisei won't try to dynamically load any of the gl functions.

Previously we used a strange inconsistent setup where some functions
were loaded dynamically and others pulled from the linked library.

We also no longer link to libGLU even if LINK_TO_LIBGL is set. The only
function we used from that library was gluPerspective. taiseigl now
provides a simple substitute via glFrustum.

The SDL2 gl headers are now used instead of the system ones, this should
be more portable. The taiseigl.h header contains generated code
partially based on content from those headers. It also doubles as a
python3 script that actually generates that code and inserts it into
itself. It scans the Taisei source tree for gl* calls and generates code
only for the functions we use, and a few manually specified ones that
are called indirectly.

Assumptions such as "linux = glx" are no longer made. SDL takes care of
platform specifics, as it should.

The GL_EXT_draw_instanced/GL_ARB_draw_instanced extension detection has
been improved. Taisei should be able to figure out which one to use
without a compile-time check, and support for the ARB version has been
actually implemented for the laser snippet loader. I've tested it on
Windows 8 with Intel drivers that don't support the EXT version but do
support the ARB one, instanced drawing works and the lasers don't lag!
OSX should benefit from this change as well, although I've not yet
tested the OSX build, beyond simply compiling it.
2017-02-25 15:24:54 +02:00

122 lines
2.9 KiB
C

/*
* This software is licensed under the terms of the MIT-License
* See COPYING for further information.
* ---
* Copyright (C) 2011, Lukas Weber <laochailan@web.de>
*/
#include <assert.h>
#include "global.h"
#define TAISEIGL_NO_EXT_ABSTRACTION
#include "taiseigl.h"
#undef TAISEIGL_NO_EXT_ABSTRACTION
struct glext_s glext;
#ifndef LINK_TO_LIBGL
#define GLDEF(glname,tsname,typename) typename tsname;
GLDEFS
#undef GLDEF
#endif
#ifndef LINK_TO_LIBGL
static void* get_proc_address(const char *name) {
void *addr = SDL_GL_GetProcAddress(name);
if(!addr) {
warnx("load_gl_functions(): SDL_GL_GetProcAddress(\"%s\") failed: %s", name, SDL_GetError());
}
return addr;
}
#endif
static void get_gl_version(char *major, char *minor) {
// the glGetIntegerv way only works in >=3.0 contexts, so...
const char *vstr = (const char*)glGetString(GL_VERSION);
const char *dot = strchr(vstr, '.');
*major = atoi(vstr);
*minor = atoi(dot+1);
}
void check_gl_extensions(void) {
get_gl_version(&glext.version.major, &glext.version.minor);
const char *glslv = (const char*)glGetString(GL_SHADING_LANGUAGE_VERSION);
if(!glslv) {
glslv = "None";
}
printf("OpenGL version: %s\n", (const char*)glGetString(GL_VERSION));
printf("OpenGL vendor: %s\n", (const char*)glGetString(GL_VENDOR));
printf("OpenGL renderer: %s\n", (const char*)glGetString(GL_RENDERER));
printf("GLSL version: %s\n", glslv);
glext.draw_instanced = false;
glext.DrawArraysInstanced = NULL;
glext.EXT_draw_instanced = SDL_GL_ExtensionSupported("GL_EXT_draw_instanced");
glext.ARB_draw_instanced = SDL_GL_ExtensionSupported("GL_ARB_draw_instanced");
glext.draw_instanced = glext.EXT_draw_instanced;
if(glext.draw_instanced) {
glext.DrawArraysInstanced = tsglDrawArraysInstancedEXT;
if(!glext.DrawArraysInstanced) {
glext.draw_instanced = false;
}
}
if(!glext.draw_instanced) {
glext.draw_instanced = glext.ARB_draw_instanced;
if(glext.draw_instanced) {
glext.DrawArraysInstanced = tsglDrawArraysInstancedARB;
if(!glext.DrawArraysInstanced) {
glext.draw_instanced = false;
}
}
}
if(!glext.draw_instanced) {
warnx(
"glDrawArraysInstanced is not supported. "
"Your video driver is probably bad, or very old, or both. "
"Expect terrible performance."
);
}
}
void load_gl_library(void) {
#ifndef LINK_TO_LIBGL
char *lib = getenv("TAISEI_LIBGL");
if(lib && !*lib) {
lib = NULL;
}
if(SDL_GL_LoadLibrary(lib) < 0) {
errx(-1, "load_gl_library(): SDL_GL_LoadLibrary() failed: %s", SDL_GetError());
return;
}
#endif
}
void load_gl_functions(void) {
#ifndef LINK_TO_LIBGL
#define GLDEF(glname,tsname,typename) tsname = (typename)get_proc_address(#glname);
GLDEFS
#undef GLDEF
#endif
}
void gluPerspective(GLdouble fovY, GLdouble aspect, GLdouble zNear, GLdouble zFar) {
GLdouble fW, fH;
fH = tan(fovY / 360 * M_PI) * zNear;
fW = fH * aspect;
glFrustum(-fW, fW, -fH, fH, zNear, zFar);
}