1 #include "baselayer.h"
2 #include "compat.h"
3 #include "glad/glad.h"
4 #include "glbuild.h"
5
6 #if defined USE_OPENGL
7
8 #ifdef RENDERTYPESDL
9 # include "sdlayer.h"
10 #endif
11
12 GLenum BuildGLError;
BuildGLErrorCheck(void)13 void BuildGLErrorCheck(void)
14 {
15 volatile GLenum err;
16 while (err = glGetError(), err != GL_NO_ERROR)
17 {
18 BuildGLError = err; // set a watchpoint/breakpoint here
19 }
20 }
21
22 #if defined DYNAMIC_GL
23
24 #if !defined RENDERTYPESDL && defined _WIN32
25 bwglCreateContextProcPtr bwglCreateContext;
26 bwglDeleteContextProcPtr bwglDeleteContext;
27 bwglGetProcAddressProcPtr bwglGetProcAddress;
28 bwglMakeCurrentProcPtr bwglMakeCurrent;
29
30 bwglChoosePixelFormatProcPtr bwglChoosePixelFormat;
31 bwglDescribePixelFormatProcPtr bwglDescribePixelFormat;
32 bwglGetPixelFormatProcPtr bwglGetPixelFormat;
33 bwglSetPixelFormatProcPtr bwglSetPixelFormat;
34 #endif
35
36 #endif
37
38 #if defined DYNAMIC_GLU
39
40 // GLU
41 bgluTessBeginContourProcPtr bgluTessBeginContour;
42 bgluTessBeginPolygonProcPtr bgluTessBeginPolygon;
43 bgluTessCallbackProcPtr bgluTessCallback;
44 bgluTessEndContourProcPtr bgluTessEndContour;
45 bgluTessEndPolygonProcPtr bgluTessEndPolygon;
46 bgluTessNormalProcPtr bgluTessNormal;
47 bgluTessPropertyProcPtr bgluTessProperty;
48 bgluTessVertexProcPtr bgluTessVertex;
49 bgluNewTessProcPtr bgluNewTess;
50 bgluDeleteTessProcPtr bgluDeleteTess;
51
52 bgluPerspectiveProcPtr bgluPerspective;
53
54 bgluErrorStringProcPtr bgluErrorString;
55
56 bgluProjectProcPtr bgluProject;
57 bgluUnProjectProcPtr bgluUnProject;
58
59 bgluLookAtProcPtr bgluLookAt;
60
61 #endif
62
63 #if defined DYNAMIC_GL || defined DYNAMIC_GLEXT || defined DYNAMIC_GLU
64 # if !defined _WIN32
65 # include <dlfcn.h>
66 # endif
67 #endif
68
69 #if defined DYNAMIC_GL || defined DYNAMIC_GLEXT
70
71 #if !defined RENDERTYPESDL && defined _WIN32
72 static HMODULE hGLDLL;
73
74 char *gldriver = NULL;
75
getproc_(const char * s,int32_t * err,int32_t fatal,int32_t extension)76 static void *getproc_(const char *s, int32_t *err, int32_t fatal, int32_t extension)
77 {
78 void *t;
79 #if defined RENDERTYPESDL
80 UNREFERENCED_PARAMETER(extension);
81 t = (void *)SDL_GL_GetProcAddress(s);
82 #elif defined _WIN32
83 if (extension) t = (void *)bwglGetProcAddress(s);
84 else t = (void *)GetProcAddress(hGLDLL,s);
85 #else
86 #error Need a dynamic loader for this platform...
87 #endif
88 if (!t && fatal)
89 {
90 initprintf("Failed to find %s in %s\n", s, gldriver);
91 *err = 1;
92 }
93 return t;
94 }
95 #define GETPROC(s) getproc_(s,&err,1,0)
96
loadwgl(const char * driver)97 int32_t loadwgl(const char *driver)
98 {
99 int32_t err=0;
100
101 if (hGLDLL) return 0;
102
103 if (!driver)
104 {
105 driver = "opengl32.dll";
106 }
107
108 hGLDLL = LoadLibrary(driver);
109 if (!hGLDLL)
110 {
111 initprintf("Failed loading \"%s\"\n", driver);
112 return -1;
113 }
114
115 gldriver = Xstrdup(driver);
116
117 bwglCreateContext = (bwglCreateContextProcPtr) GETPROC("wglCreateContext");
118 bwglDeleteContext = (bwglDeleteContextProcPtr) GETPROC("wglDeleteContext");
119 bwglGetProcAddress = (bwglGetProcAddressProcPtr) GETPROC("wglGetProcAddress");
120 bwglMakeCurrent = (bwglMakeCurrentProcPtr) GETPROC("wglMakeCurrent");
121
122 bwglChoosePixelFormat = (bwglChoosePixelFormatProcPtr) GETPROC("wglChoosePixelFormat");
123 bwglDescribePixelFormat = (bwglDescribePixelFormatProcPtr) GETPROC("wglDescribePixelFormat");
124 bwglGetPixelFormat = (bwglGetPixelFormatProcPtr) GETPROC("wglGetPixelFormat");
125 bwglSetPixelFormat = (bwglSetPixelFormatProcPtr) GETPROC("wglSetPixelFormat");
126
127 if (err) unloadwgl();
128 return err;
129 }
unloadwgl(void)130 int32_t unloadwgl(void)
131 {
132 if (!hGLDLL) return 0;
133
134 DO_FREE_AND_NULL(gldriver);
135
136 FreeLibrary(hGLDLL);
137 hGLDLL = NULL;
138
139 bwglCreateContext = (bwglCreateContextProcPtr) NULL;
140 bwglDeleteContext = (bwglDeleteContextProcPtr) NULL;
141 bwglGetProcAddress = (bwglGetProcAddressProcPtr) NULL;
142 bwglMakeCurrent = (bwglMakeCurrentProcPtr) NULL;
143
144 bwglChoosePixelFormat = (bwglChoosePixelFormatProcPtr) NULL;
145 bwglDescribePixelFormat = (bwglDescribePixelFormatProcPtr) NULL;
146 bwglGetPixelFormat = (bwglGetPixelFormatProcPtr) NULL;
147 bwglSetPixelFormat = (bwglSetPixelFormatProcPtr) NULL;
148 return 0;
149 }
150 #endif
151
152 #endif
153
154 #if defined DYNAMIC_GLU
155 #if defined _WIN32
156 static HMODULE hGLUDLL;
157 #else
158 static void *gluhandle = NULL;
159 #endif
160
161 char *glulibrary = NULL;
162
glugetproc_(const char * s,int32_t * err,int32_t fatal)163 static void *glugetproc_(const char *s, int32_t *err, int32_t fatal)
164 {
165 void *t;
166 #if defined _WIN32
167 t = (void *)GetProcAddress(hGLUDLL,s);
168 #else
169 t = (void *)dlsym(gluhandle,s);
170 #endif
171 if (!t && fatal)
172 {
173 initprintf("Failed to find %s in %s\n", s, glulibrary);
174 *err = 1;
175 }
176 return t;
177 }
178 #define GLUGETPROC(s) glugetproc_(s,&err,1)
179 #define GLUGETPROCSOFT(s) glugetproc_(s,&err,0)
180 #endif
181
loadglulibrary(const char * driver)182 int32_t loadglulibrary(const char *driver)
183 {
184 #if defined DYNAMIC_GLU
185 int32_t err=0;
186
187 #if defined _WIN32
188 if (hGLUDLL) return 0;
189 #endif
190
191 if (!driver)
192 {
193 #ifdef _WIN32
194 driver = "glu32.dll";
195 #elif defined __APPLE__
196 driver = "/System/Library/Frameworks/OpenGL.framework/OpenGL"; // FIXME: like I know anything about Apple. Hah.
197 #elif defined __OpenBSD__
198 driver = "libGLU.so";
199 #else
200 driver = "libGLU.so.1";
201 #endif
202 }
203
204 #if defined _WIN32
205 hGLUDLL = LoadLibrary(driver);
206 if (!hGLUDLL)
207 #else
208 gluhandle = dlopen(driver, RTLD_NOW|RTLD_GLOBAL);
209 if (!gluhandle)
210 #endif
211 {
212 initprintf("Failed loading \"%s\"\n",driver);
213 return -1;
214 }
215
216 glulibrary = Xstrdup(driver);
217
218 bgluTessBeginContour = (bgluTessBeginContourProcPtr) GLUGETPROC("gluTessBeginContour");
219 bgluTessBeginPolygon = (bgluTessBeginPolygonProcPtr) GLUGETPROC("gluTessBeginPolygon");
220 bgluTessCallback = (bgluTessCallbackProcPtr) GLUGETPROC("gluTessCallback");
221 bgluTessEndContour = (bgluTessEndContourProcPtr) GLUGETPROC("gluTessEndContour");
222 bgluTessEndPolygon = (bgluTessEndPolygonProcPtr) GLUGETPROC("gluTessEndPolygon");
223 bgluTessNormal = (bgluTessNormalProcPtr) GLUGETPROC("gluTessNormal");
224 bgluTessProperty = (bgluTessPropertyProcPtr) GLUGETPROC("gluTessProperty");
225 bgluTessVertex = (bgluTessVertexProcPtr) GLUGETPROC("gluTessVertex");
226 bgluNewTess = (bgluNewTessProcPtr) GLUGETPROC("gluNewTess");
227 bgluDeleteTess = (bgluDeleteTessProcPtr) GLUGETPROC("gluDeleteTess");
228
229 bgluPerspective = (bgluPerspectiveProcPtr) GLUGETPROC("gluPerspective");
230
231 bgluErrorString = (bgluErrorStringProcPtr) GLUGETPROC("gluErrorString");
232
233 bgluProject = (bgluProjectProcPtr) GLUGETPROC("gluProject");
234 bgluUnProject = (bgluUnProjectProcPtr) GLUGETPROC("gluUnProject");
235
236 bgluLookAt = (bgluLookAtProcPtr) GLUGETPROC("gluLookAt");
237
238 if (err) unloadglulibrary();
239 return err;
240 #else
241 UNREFERENCED_PARAMETER(driver);
242 return 0;
243 #endif
244 }
245
unloadglulibrary(void)246 int32_t unloadglulibrary(void)
247 {
248 #if defined DYNAMIC_GLU
249 #if defined _WIN32
250 if (!hGLUDLL) return 0;
251 #endif
252
253 DO_FREE_AND_NULL(glulibrary);
254
255 #if defined _WIN32
256 FreeLibrary(hGLUDLL);
257 hGLUDLL = NULL;
258 #else
259 if (gluhandle) dlclose(gluhandle);
260 gluhandle = NULL;
261 #endif
262
263 bgluTessBeginContour = (bgluTessBeginContourProcPtr) NULL;
264 bgluTessBeginPolygon = (bgluTessBeginPolygonProcPtr) NULL;
265 bgluTessCallback = (bgluTessCallbackProcPtr) NULL;
266 bgluTessEndContour = (bgluTessEndContourProcPtr) NULL;
267 bgluTessEndPolygon = (bgluTessEndPolygonProcPtr) NULL;
268 bgluTessNormal = (bgluTessNormalProcPtr) NULL;
269 bgluTessProperty = (bgluTessPropertyProcPtr) NULL;
270 bgluTessVertex = (bgluTessVertexProcPtr) NULL;
271 bgluNewTess = (bgluNewTessProcPtr) NULL;
272 bgluDeleteTess = (bgluDeleteTessProcPtr) NULL;
273
274 bgluPerspective = (bgluPerspectiveProcPtr) NULL;
275
276 bgluErrorString = (bgluErrorStringProcPtr) NULL;
277
278 bgluProject = (bgluProjectProcPtr) NULL;
279 bgluUnProject = (bgluUnProjectProcPtr) NULL;
280
281 bgluLookAt = (bgluLookAtProcPtr)NULL;
282 #endif
283
284 return 0;
285 }
286
287
288 //////// glGenTextures/glDeleteTextures debugging ////////
289 # if defined DEBUGGINGAIDS && defined DEBUG_TEXTURE_NAMES
290 static uint8_t *texnameused; // bitmap
291 static uint32_t *texnamefromwhere; // hash of __FILE__
292 static uint32_t texnameallocsize;
293
294 // djb3 algorithm
texdbg_getcode(const char * s)295 static inline uint32_t texdbg_getcode(const char *s)
296 {
297 uint32_t h = 5381;
298 int32_t ch;
299
300 while ((ch = *s++) != '\0')
301 h = ((h << 5) + h) ^ ch;
302
303 return h;
304 }
305
texdbg_realloc(uint32_t maxtexname)306 static void texdbg_realloc(uint32_t maxtexname)
307 {
308 uint32_t newsize = texnameallocsize ? texnameallocsize : 64;
309
310 if (maxtexname < texnameallocsize)
311 return;
312
313 while (maxtexname >= newsize)
314 newsize <<= 1;
315 // initprintf("texdebug: new size %u\n", newsize);
316
317 texnameused = Xrealloc(texnameused, newsize>>3);
318 texnamefromwhere = Xrealloc(texnamefromwhere, newsize*sizeof(uint32_t));
319
320 Bmemset(texnameused + (texnameallocsize>>3), 0, (newsize-texnameallocsize)>>3);
321 Bmemset(texnamefromwhere + texnameallocsize, 0, (newsize-texnameallocsize)*sizeof(uint32_t));
322
323 texnameallocsize = newsize;
324 }
325
326 #undef bglGenTextures
texdbg_bglGenTextures(GLsizei n,GLuint * textures,const char * srcfn)327 void texdbg_bglGenTextures(GLsizei n, GLuint *textures, const char *srcfn)
328 {
329 int32_t i;
330 uint32_t hash = srcfn ? texdbg_getcode(srcfn) : 0;
331
332 for (i=0; i<n; i++)
333 if (textures[i] < texnameallocsize && (texnameused[textures[i]>>3]&pow2char[textures[i]&7]))
334 initprintf("texdebug %x Gen: overwriting used tex name %u from %x\n", hash, textures[i], texnamefromwhere[textures[i]]);
335
336 bglGenTextures(n, textures);
337
338 {
339 GLuint maxtexname = 0;
340
341 for (i=0; i<n; i++)
342 maxtexname = max(maxtexname, textures[i]);
343
344 texdbg_realloc(maxtexname);
345
346 for (i=0; i<n; i++)
347 {
348 texnameused[textures[i]>>3] |= pow2char[textures[i]&7];
349 texnamefromwhere[textures[i]] = hash;
350 }
351 }
352 }
353
354 #undef bglDeleteTextures
texdbg_bglDeleteTextures(GLsizei n,const GLuint * textures,const char * srcfn)355 void texdbg_bglDeleteTextures(GLsizei n, const GLuint *textures, const char *srcfn)
356 {
357 int32_t i;
358 uint32_t hash = srcfn ? texdbg_getcode(srcfn) : 0;
359
360 for (i=0; i<n; i++)
361 if (textures[i] < texnameallocsize)
362 {
363 if ((texnameused[textures[i]>>3]&pow2char[textures[i]&7])==0)
364 initprintf("texdebug %x Del: deleting unused tex name %u\n", hash, textures[i]);
365 else if ((texnameused[textures[i]>>3]&pow2char[textures[i]&7]) &&
366 texnamefromwhere[textures[i]] != hash)
367 initprintf("texdebug %x Del: deleting foreign tex name %u from %x\n", hash,
368 textures[i], texnamefromwhere[textures[i]]);
369 }
370
371 bglDeleteTextures(n, textures);
372
373 if (texnameallocsize)
374 for (i=0; i<n; i++)
375 {
376 texnameused[textures[i]>>3] &= ~pow2char[textures[i]&7];
377 texnamefromwhere[textures[i]] = 0;
378 }
379 }
380 # endif // defined DEBUGGINGAIDS
381
382 #endif
383