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