mkxp-freebird/src/gl-fun.cpp

145 lines
2.6 KiB
C++

#include "gl-fun.h"
#include "boost-hash.h"
#include "exception.h"
#include <SDL_video.h>
#include <string>
GLFunctions gl;
typedef const GLubyte* (APIENTRYP PFNGLGETSTRINGIPROC) (GLenum, GLuint);
static void parseExtensionsCore(PFNGLGETINTEGERVPROC GetIntegerv, BoostSet<std::string> &out)
{
PFNGLGETSTRINGIPROC GetStringi =
(PFNGLGETSTRINGIPROC) SDL_GL_GetProcAddress("glGetStringi");
GLint extCount = 0;
GetIntegerv(GL_NUM_EXTENSIONS, &extCount);
for (GLint i = 0; i < extCount; ++i)
out.insert((const char*) GetStringi(GL_EXTENSIONS, i));
}
static void parseExtensionsCompat(PFNGLGETSTRINGPROC GetString, BoostSet<std::string> &out)
{
const char *ext = (const char*) GetString(GL_EXTENSIONS);
if (!ext)
return;
char buffer[0x100];
size_t bufferI;
while (*ext)
{
bufferI = 0;
while (*ext && *ext != ' ')
buffer[bufferI++] = *ext++;
buffer[bufferI] = '\0';
out.insert(buffer);
if (*ext == ' ')
++ext;
}
}
#define GL_FUN(name, type) \
gl.name = (type) SDL_GL_GetProcAddress("gl" #name EXT_SUFFIX);
#define EXC(msg) \
Exception(Exception::MKXPError, "%s", msg)
void initGLFunctions()
{
#define EXT_SUFFIX ""
GL_20_FUN;
/* Determine GL version */
const char *ver = (const char*) gl.GetString(GL_VERSION);
/* Assume single digit */
int glMajor = *ver - '0';
if (glMajor < 2)
throw EXC("At least OpenGL 2.0 is required");
BoostSet<std::string> ext;
if (glMajor >= 3)
parseExtensionsCore(gl.GetIntegerv, ext);
else
parseExtensionsCompat(gl.GetString, ext);
#define HAVE_EXT(_ext) ext.contains("GL_" #_ext)
if (!HAVE_EXT(ARB_framebuffer_object))
{
if (!(HAVE_EXT(EXT_framebuffer_object) && HAVE_EXT(EXT_framebuffer_blit)))
throw EXC("No FBO extensions available");
#undef EXT_SUFFIX
#define EXT_SUFFIX "EXT"
GL_FBO_FUN;
}
else
{
#undef EXT_SUFFIX
#define EXT_SUFFIX ""
GL_FBO_FUN;
}
if (!HAVE_EXT(ARB_vertex_array_object))
{
if (!HAVE_EXT(APPLE_vertex_array_object))
throw EXC("No VAO extensions available");
#undef EXT_SUFFIX
#define EXT_SUFFIX "APPLE"
GL_VAO_FUN;
}
else
{
#undef EXT_SUFFIX
#define EXT_SUFFIX ""
GL_VAO_FUN;
}
if (HAVE_EXT(ARB_timer_query))
{
gl.timerQuery = true;
#undef EXT_SUFFIX
#define EXT_SUFFIX ""
GL_TIMER_QUERY_FUN;
}
else if (HAVE_EXT(EXT_timer_query))
{
gl.timerQuery = true;
#undef EXT_SUFFIX
#define EXT_SUFFIX "EXT"
GL_TIMER_QUERY_FUN;
}
else
{
gl.timerQuery = false;
}
if (HAVE_EXT(KHR_debug))
{
#undef EXT_SUFFIX
#define EXT_SUFFIX ""
GL_DEBUG_KHR_FUN;
}
else if (HAVE_EXT(ARB_debug_output))
{
#undef EXT_SUFFIX
#define EXT_SUFFIX "ARB"
GL_DEBUG_KHR_FUN;
}
}