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