bool app_init(int argc, char **argv)
{
+ set_log_file("demo.log");
+
+ if(init_opengl() == -1) {
+ return false;
+ }
+
if(!init_options(argc, argv, "demo.conf")) {
return false;
}
enum { LOG_INFO, LOG_WARNING, LOG_ERROR, LOG_FATAL, LOG_DEBUG };
static int typecolor(int type);
+static const char *typeprefix(int type);
static FILE *fp = stdout;
+static FILE *logfile;
static void logmsg(int type, const char *fmt, va_list ap)
{
+ va_list ap_orig;
+
+ va_copy(ap_orig, ap);
+
#if defined(unix) || defined(__unix__) || (defined(__APPLE__) && !defined(TARGET_IPHONE))
if(isatty(fileno(fp)) && type != LOG_INFO) {
int c = typecolor(type);
} else
#endif
{
+ fprintf(fp, "%s", typeprefix(type));
vfprintf(fp, fmt, ap);
}
if(type == LOG_ERROR || type == LOG_FATAL || type == LOG_DEBUG) {
fflush(fp);
}
+ if(logfile) {
+ va_end(ap);
+ va_copy(ap, ap_orig);
+ fprintf(logfile, "%s", typeprefix(type));
+ vfprintf(logfile, fmt, ap);
+ }
+
#ifdef WIN32
if(type == LOG_FATAL) {
static char msgbuf[1024];
- vsnprintf(msgbuf, sizeof msgbuf - 1, fmt, ap);
+ vsnprintf(msgbuf, sizeof msgbuf - 1, fmt, ap_orig);
msgbuf[sizeof msgbuf - 1] = 0;
MessageBox(0, msgbuf, "Fatal error", MB_OK | MB_ICONSTOP);
}
#endif
+
+ va_end(ap_orig);
+}
+
+static void close_logfile(void)
+{
+ if(logfile) fclose(logfile);
+}
+
+extern "C" void set_log_file(const char *fname)
+{
+ static int init_once;
+
+ close_logfile();
+ logfile = fopen(fname, "w");
+
+ if(!init_once) {
+ atexit(close_logfile);
+ init_once = 1;
+ }
}
extern "C" void info_log(const char *fmt, ...)
}
return 37;
}
+
+static const char *typeprefix(int type)
+{
+ switch(type) {
+ case LOG_ERROR:
+ return "E: ";
+ case LOG_FATAL:
+ return "F: ";
+ case LOG_WARNING:
+ return "W: ";
+ case LOG_DEBUG:
+ return "D: ";
+ default:
+ break;
+ }
+ return "";
+}
#ifndef LOGGER_H_
#define LOGGER_H_
+#include <stdio.h>
+
#ifdef __cplusplus
extern "C" {
#endif
+void set_log_file(const char *fname);
+
void info_log(const char *fmt, ...);
void warning_log(const char *fmt, ...);
void error_log(const char *fmt, ...);
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 8);
SDL_GL_SetAttribute(SDL_GL_FRAMEBUFFER_SRGB_CAPABLE, 1);
+#ifndef NDEBUG
+ SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_DEBUG_FLAG);
+#endif
int defpos = SDL_WINDOWPOS_UNDEFINED;
unsigned int sdlflags = SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI;
static bool init(int argc, char **argv)
{
- glewInit();
-
if(!app_init(argc, argv)) {
return false;
}
--- /dev/null
+#include "opengl.h"
+#include "logger.h"
+
+static void gldebug_logger(unsigned int src, unsigned int type, unsigned int id,
+ unsigned int severity, int len, const char *msg, const void *cls);
+static const char *gldebug_srcstr(unsigned int src);
+static const char *gldebug_typestr(unsigned int type);
+static const char *gldebug_sevstr(unsigned int sev);
+
+struct GLCaps glcaps;
+
+int init_opengl(void)
+{
+ glewInit();
+
+ glcaps.debug = GLEW_ARB_debug_output;
+
+#ifndef NDEBUG
+ if(glcaps.debug) {
+ info_log("Installing OpenGL debug callback\n");
+ glDebugMessageCallback(gldebug_logger, 0);
+ }
+#endif
+
+ return 0;
+}
+
+
+static void gldebug_logger(unsigned int src, unsigned int type, unsigned int id,
+ unsigned int severity, int len, const char *msg, const void *cls)
+{
+ static const char *fmt = "[GLDEBUG] (%s) %s: %s\n";
+ switch(type) {
+ case GL_DEBUG_TYPE_ERROR:
+ error_log(fmt, gldebug_srcstr(src), gldebug_typestr(type), msg);
+ break;
+
+ case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
+ case GL_DEBUG_TYPE_PORTABILITY:
+ case GL_DEBUG_TYPE_PERFORMANCE:
+ warning_log(fmt, gldebug_srcstr(src), gldebug_typestr(type), msg);
+ break;
+
+ default:
+ debug_log(fmt, gldebug_srcstr(src), gldebug_typestr(type), msg);
+ }
+}
+
+static const char *gldebug_srcstr(unsigned int src)
+{
+ switch(src) {
+ case GL_DEBUG_SOURCE_API:
+ return "api";
+ case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
+ return "wsys";
+ case GL_DEBUG_SOURCE_SHADER_COMPILER:
+ return "sdrc";
+ case GL_DEBUG_SOURCE_THIRD_PARTY:
+ return "3rdparty";
+ case GL_DEBUG_SOURCE_APPLICATION:
+ return "app";
+ case GL_DEBUG_SOURCE_OTHER:
+ return "other";
+ default:
+ break;
+ }
+ return "unknown";
+}
+
+static const char *gldebug_typestr(unsigned int type)
+{
+ switch(type) {
+ case GL_DEBUG_TYPE_ERROR:
+ return "error";
+ case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
+ return "deprecated";
+ case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
+ return "undefined behavior";
+ case GL_DEBUG_TYPE_PORTABILITY:
+ return "portability warning";
+ case GL_DEBUG_TYPE_PERFORMANCE:
+ return "performance warning";
+ case GL_DEBUG_TYPE_OTHER:
+ return "other";
+ default:
+ break;
+ }
+ return "unknown";
+}
+
+static const char *gldebug_sevstr(unsigned int sev)
+{
+ switch(sev) {
+ case GL_DEBUG_SEVERITY_HIGH:
+ return "high";
+ case GL_DEBUG_SEVERITY_MEDIUM:
+ return "medium";
+ case GL_DEBUG_SEVERITY_LOW:
+ return "low";
+ default:
+ break;
+ }
+ return "unknown";
+}
#include <GL/glew.h>
-#endif // OPENGL_H_
+struct GLCaps {
+ int debug; /* ARB_debug_output */
+};
+
+extern struct GLCaps glcaps;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int init_opengl(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* OPENGL_H_ */