1 /*
2 * OpenBOR - http://www.LavaLit.com
3 * -----------------------------------------------------------------------
4 * All rights reserved, see LICENSE in OpenBOR root for details.
5 *
6 * Copyright (c) 2004 - 2011 OpenBOR Team
7 */
8
9 /*
10 * Dynamic OpenGL function loader. Allows the program to run using SDL software
11 * blitting when there is no OpenGL implementation available. This is the case
12 * by default in some Linux distributions and on some very old Windows computers.
13 *
14 * Date: August 3, 2010
15 * Update, September 17, 2010
16 */
17
18 #include "loadgl.h"
19
20 #ifndef APIENTRY
21 #define APIENTRY
22 #endif
23
24 // Macros for compatibility between SDL and EGL
25 #ifdef SDL // SDL is currently used on all OpenGL-capable platforms
26 #include "sdlport.h"
27 #define GetProcAddress SDL_GL_GetProcAddress
28 #elif EGL // proof of concept for EGL support, especially useful with OpenGL ES
29 #define GetProcAddress eglGetProcAddress
30 #else
31 #error no API for dynamically loading OpenGL functions is defined
32 #endif
33
34 void (APIENTRY *ptr_glViewport)(GLint x, GLint y, GLsizei width, GLsizei height);
35 void (APIENTRY *ptr_glMatrixMode)(GLenum mode);
36 void (APIENTRY *ptr_glLoadIdentity)(void);
37
38 void (APIENTRY *ptr_glGenTextures)(GLsizei n, GLuint *textures);
39 void (APIENTRY *ptr_glDeleteTextures)(GLsizei n, const GLuint *textures);
40 void (APIENTRY *ptr_glBindTexture)(GLenum target, GLuint texture);
41 void (APIENTRY *ptr_glTexImage2D)(GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
42 void (APIENTRY *ptr_glTexSubImage2D)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels);
43
44 void (APIENTRY *ptr_glClear)(GLbitfield mask);
45 void (APIENTRY *ptr_glClearColor)(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
46 void (APIENTRY *ptr_glColor4f)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
47 void (APIENTRY *ptr_glBlendFunc)(GLenum sfactor, GLenum dfactor);
48 void (APIENTRY *ptr_glTexEnvi)(GLenum, GLenum, GLint);
49 void (APIENTRY *ptr_glTexEnvfv)(GLenum, GLenum, const GLfloat*);
50
51 void (APIENTRY *ptr_glEnable)(GLenum cap);
52 void (APIENTRY *ptr_glDisable)(GLenum cap);
53
54 void (APIENTRY *ptr_glGetIntegerv)(GLenum pname, GLint* params);
55 const GLubyte* (APIENTRY *ptr_glGetString)(GLenum name);
56 GLenum (APIENTRY *ptr_glGetError)(void);
57
58 #ifdef GLES
59 void (APIENTRY *ptr_glOrthox)(GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed near_val, GLfixed far_val);
60 void (APIENTRY *ptr_glTexParameterx)(GLenum target, GLenum pname, GLfixed param);
61
62 void (APIENTRY *ptr_glEnableClientState)(GLenum cap);
63 void (APIENTRY *ptr_glDisableClientState)(GLenum cap);
64 void (APIENTRY *ptr_glTexCoordPointer)(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr);
65 void (APIENTRY *ptr_glVertexPointer)(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr);
66 void (APIENTRY *ptr_glDrawArrays)(GLenum mode, GLint first, GLsizei count);
67 #else
68 void (APIENTRY *ptr_glOrtho)(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near_val, GLdouble far_val);
69 void (APIENTRY *ptr_glTexParameteri)(GLenum target, GLenum pname, GLint param);
70 void (APIENTRY *ptr_glBegin)(GLenum mode);
71 void (APIENTRY *ptr_glEnd)(void);
72 void (APIENTRY *ptr_glVertex2i)(GLint x, GLint y);
73 void (APIENTRY *ptr_glTexCoord2f)(GLfloat s, GLfloat t);
74 #endif
75
76 // optional multitexturing extension (core in OpenGL 1.3 and OpenGL ES 1.0)
77 void (APIENTRY *ptr_glActiveTexture)(GLenum texture);
78 void (APIENTRY *ptr_glMultiTexCoord2f)(GLenum texture, GLfloat s, GLfloat t);
79
80 PFNGLCREATESHADEROBJECTARBPROC glCreateShaderObjectARB;
81 PFNGLSHADERSOURCEARBPROC glShaderSourceARB;
82 PFNGLCOMPILESHADERARBPROC glCompileShaderARB;
83 PFNGLCREATEPROGRAMOBJECTARBPROC glCreateProgramObjectARB;
84 PFNGLATTACHOBJECTARBPROC glAttachObjectARB;
85 PFNGLLINKPROGRAMARBPROC glLinkProgramARB;
86 PFNGLUSEPROGRAMOBJECTARBPROC glUseProgramObjectARB;
87 PFNGLGETUNIFORMLOCATIONARBPROC glGetUniformLocationARB;
88 PFNGLUNIFORM1IARBPROC glUniform1iARB;
89 PFNGLUNIFORM1FARBPROC glUniform1fARB;
90 PFNGLUNIFORM4FARBPROC glUniform4fARB;
91
92 #define LOADFUNC(X,Y) Y = GetProcAddress(X); if(!Y) { printf("Failed to load OpenGL function " X "..."); return 0; }
93 #define LOADFUNC2(X) X = GetProcAddress(#X); if(!X) { printf("Failed to load OpenGL function " #X "..."); return 0; }
94
LoadGLFunctions()95 int LoadGLFunctions()
96 {
97 // Load every OpenGL function we use in video.c
98 LOADFUNC("glViewport", ptr_glViewport);
99 LOADFUNC("glMatrixMode", ptr_glMatrixMode);
100 LOADFUNC("glLoadIdentity", ptr_glLoadIdentity);
101
102 LOADFUNC("glGenTextures", ptr_glGenTextures);
103 LOADFUNC("glDeleteTextures", ptr_glDeleteTextures);
104 LOADFUNC("glBindTexture", ptr_glBindTexture);
105 LOADFUNC("glTexImage2D", ptr_glTexImage2D);
106 LOADFUNC("glTexSubImage2D", ptr_glTexSubImage2D);
107
108 LOADFUNC("glClear", ptr_glClear);
109 LOADFUNC("glClearColor", ptr_glClearColor);
110 LOADFUNC("glColor4f", ptr_glColor4f);
111 LOADFUNC("glBlendFunc", ptr_glBlendFunc);
112 LOADFUNC("glTexEnvi", ptr_glTexEnvi);
113 LOADFUNC("glTexEnvfv", ptr_glTexEnvfv);
114
115 LOADFUNC("glEnable", ptr_glEnable);
116 LOADFUNC("glDisable", ptr_glDisable);
117
118 LOADFUNC("glGetIntegerv", ptr_glGetIntegerv);
119 LOADFUNC("glGetString", ptr_glGetString);
120 LOADFUNC("glGetError", ptr_glGetError);
121
122 #ifdef GLES
123 LOADFUNC("glOrthox", ptr_glOrthox);
124 LOADFUNC("glTexParameterx", ptr_glTexParameterx);
125 LOADFUNC("glEnableClientState", ptr_glEnableClientState);
126 LOADFUNC("glDisableClientState", ptr_glDisableClientState);
127 LOADFUNC("glTexCoordPointer", ptr_glTexCoordPointer);
128 LOADFUNC("glVertexPointer", ptr_glVertexPointer);
129 LOADFUNC("glDrawArrays", ptr_glDrawArrays);
130 #else
131 LOADFUNC("glOrtho", ptr_glOrtho);
132 LOADFUNC("glTexParameteri", ptr_glTexParameteri);
133 LOADFUNC("glBegin", ptr_glBegin);
134 LOADFUNC("glEnd", ptr_glEnd);
135 LOADFUNC("glVertex2i", ptr_glVertex2i);
136 LOADFUNC("glTexCoord2f", ptr_glTexCoord2f);
137 #endif
138
139 // load multisampling functions; try the ARB versions if the core versions are not available
140 ptr_glActiveTexture = GetProcAddress("glActiveTexture");
141 if(!ptr_glActiveTexture)
142 LOADFUNC("glActiveTextureARB", ptr_glActiveTexture);
143 #ifndef GLES
144 ptr_glMultiTexCoord2f = GetProcAddress("glMultiTexCoord2f");
145 if(!ptr_glMultiTexCoord2f)
146 LOADFUNC("glMultiTexCoord2fARB", ptr_glMultiTexCoord2f);
147 #endif
148
149 // load optional GLSL extensions
150 glCreateShaderObjectARB = GetProcAddress("glCreateShaderObjectARB");
151 glShaderSourceARB = GetProcAddress("glShaderSourceARB");
152 glCompileShaderARB = GetProcAddress("glCompileShaderARB");
153 glCreateProgramObjectARB = GetProcAddress("glCreateProgramObjectARB");
154 glAttachObjectARB = GetProcAddress("glAttachObjectARB");
155 glLinkProgramARB = GetProcAddress("glLinkProgramARB");
156 glUseProgramObjectARB = GetProcAddress("glUseProgramObjectARB");
157 glGetUniformLocationARB = GetProcAddress("glGetUniformLocationARB");
158 glUniform1iARB = GetProcAddress("glUniform1iARB");
159 glUniform1fARB = GetProcAddress("glUniform1fARB");
160 glUniform4fARB = GetProcAddress("glUniform4fARB");
161
162 return 1;
163 }
164
165 #ifndef DARWIN
glViewport(GLint x,GLint y,GLsizei width,GLsizei height)166 void APIENTRY glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
167 {
168 ptr_glViewport(x, y, width, height);
169 }
170
glMatrixMode(GLenum mode)171 void APIENTRY glMatrixMode(GLenum mode)
172 {
173 ptr_glMatrixMode(mode);
174 }
175
glLoadIdentity(void)176 void APIENTRY glLoadIdentity(void)
177 {
178 ptr_glLoadIdentity();
179 }
180
glGenTextures(GLsizei n,GLuint * textures)181 void APIENTRY glGenTextures(GLsizei n, GLuint *textures)
182 {
183 ptr_glGenTextures(n, textures);
184 }
185
glDeleteTextures(GLsizei n,const GLuint * textures)186 void APIENTRY glDeleteTextures(GLsizei n, const GLuint *textures)
187 {
188 ptr_glDeleteTextures(n, textures);
189 }
190
glActiveTexture(GLenum texture)191 void APIENTRY glActiveTexture(GLenum texture)
192 {
193 ptr_glActiveTexture(texture);
194 }
195
glBindTexture(GLenum target,GLuint texture)196 void APIENTRY glBindTexture(GLenum target, GLuint texture)
197 {
198 ptr_glBindTexture(target, texture);
199 }
200
glTexImage2D(GLenum target,GLint level,GLint internalFormat,GLsizei width,GLsizei height,GLint border,GLenum format,GLenum type,const GLvoid * pixels)201 void APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
202 {
203 ptr_glTexImage2D(target, level, internalFormat, width, height, border, format, type, pixels);
204 }
205
glTexSubImage2D(GLenum target,GLint level,GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,GLenum format,GLenum type,const GLvoid * pixels)206 void APIENTRY glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels)
207 {
208 ptr_glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
209 }
210
glClear(GLbitfield mask)211 void APIENTRY glClear(GLbitfield mask)
212 {
213 ptr_glClear(mask);
214 }
215
glClearColor(GLclampf red,GLclampf green,GLclampf blue,GLclampf alpha)216 void APIENTRY glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
217 {
218 ptr_glClearColor(red, green, blue, alpha);
219 }
220
glColor4f(GLfloat red,GLfloat green,GLfloat blue,GLfloat alpha)221 void APIENTRY glColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
222 {
223 ptr_glColor4f(red, green, blue, alpha);
224 }
225
glBlendFunc(GLenum sfactor,GLenum dfactor)226 void APIENTRY glBlendFunc(GLenum sfactor, GLenum dfactor)
227 {
228 ptr_glBlendFunc(sfactor, dfactor);
229 }
230
glTexEnvi(GLenum target,GLenum pname,GLint param)231 void APIENTRY glTexEnvi(GLenum target, GLenum pname, GLint param)
232 {
233 ptr_glTexEnvi(target, pname, param);
234 }
235
glTexEnvfv(GLenum target,GLenum pname,const GLfloat * params)236 void APIENTRY glTexEnvfv(GLenum target, GLenum pname, const GLfloat* params)
237 {
238 ptr_glTexEnvfv(target, pname, params);
239 }
240
glEnable(GLenum cap)241 void APIENTRY glEnable(GLenum cap)
242 {
243 ptr_glEnable(cap);
244 }
245
glDisable(GLenum cap)246 void APIENTRY glDisable(GLenum cap)
247 {
248 ptr_glDisable(cap);
249 }
250
glGetIntegerv(GLenum pname,GLint * params)251 void APIENTRY glGetIntegerv(GLenum pname, GLint* params)
252 {
253 ptr_glGetIntegerv(pname, params);
254 }
255
glGetString(GLenum name)256 const GLubyte* APIENTRY glGetString(GLenum name)
257 {
258 return ptr_glGetString(name);
259 }
260
glGetError(void)261 GLenum APIENTRY glGetError(void)
262 {
263 return ptr_glGetError();
264 }
265
266 #ifdef GLES
glOrthox(GLfixed left,GLfixed right,GLfixed bottom,GLfixed top,GLfixed near_val,GLfixed far_val)267 void APIENTRY glOrthox(GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed near_val, GLfixed far_val)
268 {
269 ptr_glOrthox(left, right, bottom, top, near_val, far_val);
270 }
271
glTexParameterx(GLenum target,GLenum pname,GLfixed param)272 void APIENTRY glTexParameterx(GLenum target, GLenum pname, GLfixed param)
273 {
274 ptr_glTexParameterx(target, pname, param);
275 }
276
glEnableClientState(GLenum cap)277 void APIENTRY glEnableClientState(GLenum cap)
278 {
279 ptr_glEnableClientState(cap);
280 }
281
glDisableClientState(GLenum cap)282 void APIENTRY glDisableClientState(GLenum cap)
283 {
284 ptr_glDisableClientState(cap);
285 }
286
glTexCoordPointer(GLint size,GLenum type,GLsizei stride,const GLvoid * ptr)287 void APIENTRY glTexCoordPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr)
288 {
289 ptr_glTexCoordPointer(size, type, stride, ptr);
290 }
291
glVertexPointer(GLint size,GLenum type,GLsizei stride,const GLvoid * ptr)292 void APIENTRY glVertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr)
293 {
294 ptr_glVertexPointer(size, type, stride, ptr);
295 }
296
glDrawArrays(GLenum mode,GLint first,GLsizei count)297 void APIENTRY glDrawArrays(GLenum mode, GLint first, GLsizei count)
298 {
299 ptr_glDrawArrays(mode, first, count);
300 }
301 #else
glOrtho(GLdouble left,GLdouble right,GLdouble bottom,GLdouble top,GLdouble near_val,GLdouble far_val)302 void APIENTRY glOrtho(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near_val, GLdouble far_val)
303 {
304 ptr_glOrtho(left, right, bottom, top, near_val, far_val);
305 }
306
glTexParameteri(GLenum target,GLenum pname,GLint param)307 void APIENTRY glTexParameteri(GLenum target, GLenum pname, GLint param)
308 {
309 ptr_glTexParameteri(target, pname, param);
310 }
311
glBegin(GLenum mode)312 void APIENTRY glBegin(GLenum mode)
313 {
314 ptr_glBegin(mode);
315 }
316
glEnd(void)317 void APIENTRY glEnd(void)
318 {
319 ptr_glEnd();
320 }
321
glVertex2i(GLint x,GLint y)322 void APIENTRY glVertex2i(GLint x, GLint y)
323 {
324 ptr_glVertex2i(x, y);
325 }
326
glTexCoord2f(GLfloat s,GLfloat t)327 void APIENTRY glTexCoord2f(GLfloat s, GLfloat t)
328 {
329 ptr_glTexCoord2f(s, t);
330 }
331
glMultiTexCoord2f(GLenum texture,GLfloat s,GLfloat t)332 void APIENTRY glMultiTexCoord2f(GLenum texture, GLfloat s, GLfloat t)
333 {
334 ptr_glMultiTexCoord2f(texture, s, t);
335 }
336 #endif
337 #endif
338
339