fixed crash when glDebugCallbackARB is available but glDebugCallback isn't
[laserbrain_demo] / src / opengl.c
1 #include <stdlib.h>
2 #include "opengl.h"
3 #include "logger.h"
4
5
6 static void GLAPIENTRY gldebug_logger(GLenum src, GLenum type, GLuint id, GLenum severity,
7                 GLsizei len, const char *msg, const void *cls);
8
9 static const char *gldebug_srcstr(unsigned int src);
10 static const char *gldebug_typestr(unsigned int type);
11 static const char *gldebug_sevstr(unsigned int sev);
12
13 struct GLCaps glcaps;
14
15 int init_opengl(void)
16 {
17         glewInit();
18
19         glcaps.debug = GLEW_ARB_debug_output;
20
21 #ifndef NDEBUG
22         if(glcaps.debug) {
23                 info_log("Installing OpenGL debug callback\n");
24                 glDebugMessageCallbackARB(gldebug_logger, 0);
25         }
26 #endif
27
28         return 0;
29 }
30
31 void dump_gl_texture(unsigned int tex, const char *fname)
32 {
33         FILE *fp;
34         int i, width, height;
35         unsigned char *pixels;
36
37         glBindTexture(GL_TEXTURE_2D, tex);
38         glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &width);
39         glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &height);
40
41         if(!(pixels = malloc(width * height * 3))) {
42                 return;
43         }
44         glGetTexImage(GL_TEXTURE_2D, 0, GL_RGB, GL_UNSIGNED_BYTE, pixels);
45
46         if(!(fp = fopen(fname, "wb"))) {
47                 free(pixels);
48                 return;
49         }
50         fprintf(fp, "P6\n%d %d\n255\n", width, height);
51         for(i=0; i<width * height * 3; i++) {
52                 fputc(pixels[i], fp);
53         }
54         fclose(fp);
55         free(pixels);
56 }
57
58
59 static void GLAPIENTRY gldebug_logger(GLenum src, GLenum type, GLuint id, GLenum severity,
60                 GLsizei len, const char *msg, const void *cls)
61 {
62         static const char *fmt = "[GLDEBUG] (%s) %s: %s\n";
63         switch(type) {
64         case GL_DEBUG_TYPE_ERROR:
65                 error_log(fmt, gldebug_srcstr(src), gldebug_typestr(type), msg);
66                 break;
67
68         case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
69         case GL_DEBUG_TYPE_PORTABILITY:
70         case GL_DEBUG_TYPE_PERFORMANCE:
71                 warning_log(fmt, gldebug_srcstr(src), gldebug_typestr(type), msg);
72                 break;
73
74         default:
75                 debug_log(fmt, gldebug_srcstr(src), gldebug_typestr(type), msg);
76         }
77 }
78
79 static const char *gldebug_srcstr(unsigned int src)
80 {
81         switch(src) {
82         case GL_DEBUG_SOURCE_API:
83                 return "api";
84         case GL_DEBUG_SOURCE_WINDOW_SYSTEM:
85                 return "wsys";
86         case GL_DEBUG_SOURCE_SHADER_COMPILER:
87                 return "sdrc";
88         case GL_DEBUG_SOURCE_THIRD_PARTY:
89                 return "3rdparty";
90         case GL_DEBUG_SOURCE_APPLICATION:
91                 return "app";
92         case GL_DEBUG_SOURCE_OTHER:
93                 return "other";
94         default:
95                 break;
96         }
97         return "unknown";
98 }
99
100 static const char *gldebug_typestr(unsigned int type)
101 {
102         switch(type) {
103         case GL_DEBUG_TYPE_ERROR:
104                 return "error";
105         case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR:
106                 return "deprecated";
107         case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR:
108                 return "undefined behavior";
109         case GL_DEBUG_TYPE_PORTABILITY:
110                 return "portability warning";
111         case GL_DEBUG_TYPE_PERFORMANCE:
112                 return "performance warning";
113         case GL_DEBUG_TYPE_OTHER:
114                 return "other";
115         default:
116                 break;
117         }
118         return "unknown";
119 }
120
121 static const char *gldebug_sevstr(unsigned int sev)
122 {
123         switch(sev) {
124         case GL_DEBUG_SEVERITY_HIGH:
125                 return "high";
126         case GL_DEBUG_SEVERITY_MEDIUM:
127                 return "medium";
128         case GL_DEBUG_SEVERITY_LOW:
129                 return "low";
130         default:
131                 break;
132         }
133         return "unknown";
134 }