1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 
5 #include "SDL.h"
6 
7 #include "oglfunc.h"
8 
9 // Base OpenGL / OpenGL ES
10 avpPFNGLACTIVETEXTUREPROC pglActiveTexture;
11 avpPFNGLBINDTEXTUREPROC		pglBindTexture;
12 avpPFNGLBLENDFUNCPROC		pglBlendFunc;
13 avpPFNGLCLEARPROC			pglClear;
14 avpPFNGLCLEARCOLORPROC		pglClearColor;
15 avpPFNGLCULLFACEPROC		pglCullFace;
16 avpPFNGLDELETETEXTURESPROC		pglDeleteTextures;
17 avpPFNGLDEPTHFUNCPROC		pglDepthFunc;
18 avpPFNGLDEPTHMASKPROC		pglDepthMask;
19 avpPFNGLDEPTHRANGEPROC		pglDepthRange;
20 avpPFNGLDISABLEPROC		pglDisable;
21 avpPFNGLDRAWELEMENTSPROC		pglDrawElements;
22 avpPFNGLENABLEPROC			pglEnable;
23 avpPFNGLFRONTFACEPROC		pglFrontFace;
24 avpPFNGLGENTEXTURESPROC		pglGenTextures;
25 avpPFNGLGETERRORPROC		pglGetError;
26 avpPFNGLGETFLOATVPROC		pglGetFloatv;
27 avpPFNGLGETINTEGERVPROC		pglGetIntegerv;
28 avpPFNGLGETSTRINGPROC		pglGetString;
29 avpPFNGLGETTEXPARAMETERFVPROC	pglGetTexParameterfv;
30 avpPFNGLHINTPROC			pglHint;
31 avpPFNGLPIXELSTOREIPROC		pglPixelStorei;
32 avpPFNGLPOLYGONOFFSETPROC		pglPolygonOffset;
33 avpPFNGLREADPIXELSPROC		pglReadPixels;
34 avpPFNGLTEXIMAGE2DPROC		pglTexImage2D;
35 avpPFNGLTEXPARAMETERFPROC		pglTexParameterf;
36 avpPFNGLTEXPARAMETERIPROC		pglTexParameteri;
37 avpPFNGLTEXSUBIMAGE2DPROC		pglTexSubImage2D;
38 avpPFNGLVIEWPORTPROC		pglViewport;
39 
40 // OpenGL 2.1 / OpenGL ES 2.0
41 avpPFNGLATTACHSHADERPROC pglAttachShader;
42 avpPFNGLBINDATTRIBLOCATIONPROC pglBindAttribLocation;
43 avpPFNGLBINDBUFFERPROC pglBindBuffer;
44 avpPFNGLBUFFERDATAPROC pglBufferData;
45 avpPFNGLBUFFERSUBDATAPROC pglBufferSubData;
46 avpPFNGLCREATEPROGRAMPROC pglCreateProgram;
47 avpPFNGLCREATESHADERPROC pglCreateShader;
48 avpPFNGLCOMPILESHADERPROC pglCompileShader;
49 avpPFNGLDELETEBUFFERSPROC pglDeleteBuffers;
50 avpPFNGLDELETEPROGRAMPROC pglDeleteProgram;
51 avpPFNGLDELETESHADERPROC pglDeleteShader;
52 avpPFNGLDISABLEVERTEXATTRIBARRAYPROC pglDisableVertexAttribArray;
53 avpPFNGLENABLEVERTEXATTRIBARRAYPROC pglEnableVertexAttribArray;
54 avpPFNGLGENBUFFERSPROC pglGenBuffers;
55 avpPFNGLGETATTRIBLOCATIONPROC pglGetAttribLocation;
56 avpPFNGLGETPROGRAMINFOLOGPROC pglGetProgramInfoLog;
57 avpPFNGLGETPROGRAMIVPROC pglGetProgramiv;
58 avpPFNGLGETSHADERINFOLOGPROC pglGetShaderInfoLog;
59 avpPFNGLGETSHADERIVPROC pglGetShaderiv;
60 avpPFNGLGETUNIFORMLOCATIONPROC pglGetUniformLocation;
61 avpPFNGLLINKPROGRAMPROC pglLinkProgram;
62 avpPFNGLSHADERSOURCEPROC pglShaderSource;
63 avpPFNGLVALIDATEPROGRAMPROC pglValidateProgram;
64 avpPFNGLVERTEXATTRIBPOINTERPROC pglVertexAttribPointer;
65 avpPFNGLUNIFORM1IPROC pglUniform1i;
66 avpPFNGLUNIFORMMATRIX4FVPROC pglUniformMatrix4fv;
67 avpPFNGLUSEPROGRAMPROC pglUseProgram;
68 
69 // GL_EXT_framebuffer_object / GL_ARB_framebuffer_object / OpenGL ES 2.0
70 avpPFNGLBINDFRAMEBUFFERPROC pglBindFramebuffer;
71 avpPFNGLBINDRENDERBUFFERPROC pglBindRenderbuffer;
72 avpPFNGLCHECKFRAMEBUFFERSTATUSPROC pglCheckFramebufferStatus;
73 avpPFNGLDELETEFRAMEBUFFERSPROC pglDeleteFramebuffers;
74 avpPFNGLDELETERENDERBUFFERSPROC pglDeleteRenderbuffers;
75 avpPFNGLFRAMEBUFFERRENDERBUFFERPROC pglFramebufferRenderbuffer;
76 avpPFNGLFRAMEBUFFERTEXTURE2DPROC pglFramebufferTexture2D;
77 avpPFNGLGENERATEMIPMAPPROC pglGenerateMipmap;
78 avpPFNGLGENFRAMEBUFFERSPROC pglGenFramebuffers;
79 avpPFNGLGENRENDERBUFFERSPROC pglGenRenderbuffers;
80 avpPFNGLRENDERBUFFERSTORAGEPROC pglRenderbufferStorage;
81 
82 int ogl_have_multisample_filter_hint;
83 int ogl_have_texture_filter_anisotropic;
84 int ogl_have_framebuffer_object;
85 
86 int ogl_use_multisample_filter_hint;
87 int ogl_use_texture_filter_anisotropic;
88 int ogl_use_framebuffer_object;
89 
dummyfunc()90 static void dummyfunc()
91 {
92 }
93 
94 #define LoadOGLProc_(type, func, name) {                    \
95 	if (!mode) p##func = (type) dummyfunc; else			\
96 	p##func = (type) SDL_GL_GetProcAddress(#name);			\
97 	if (p##func == NULL) {						\
98 		if (!ogl_missing_func) ogl_missing_func = #func;	\
99 	}								\
100 }
101 
102 #define LoadOGLProc(type, func)						\
103 	LoadOGLProc_(type, func, func)
104 
105 #define LoadOGLProc2(type, func1, func2)					\
106 	LoadOGLProc_(type, func1, func1); \
107 	if (p##func1 == NULL) { \
108 		ogl_missing_func = NULL; \
109 		LoadOGLProc_(type, func1, func2); \
110 	}
111 
112 #define LoadOGLExtProc(e, type, func)						\
113 	if ((e)) { \
114 		LoadOGLProc(type, func); \
115 	} else { \
116 		p##func = NULL; \
117 	}
118 
119 #define LoadOGLExtProc2(e, type, func1, func2)					\
120 	if ((e)) { \
121 		LoadOGLProc2(type, func1, func2); \
122 	} else { \
123 		p##func = NULL; \
124 	}
125 
check_token(const char * string,const char * token)126 static int check_token(const char *string, const char *token)
127 {
128 	const char *s = string;
129 	int len = strlen(token);
130 
131 	while ((s = strstr(s, token)) != NULL) {
132 		const char *next = s + len;
133 
134 		if ((s == string || *(s-1) == ' ') &&
135 			(*next == 0 || *next == ' ')) {
136 
137 			return 1;
138 		}
139 
140 		s = next;
141 	}
142 
143 	return 0;
144 }
145 
load_ogl_functions(int mode)146 void load_ogl_functions(int mode)
147 {
148 	const char* ogl_missing_func;
149 	const char* ext;
150 
151 	int base_framebuffer_object;
152 	int ext_framebuffer_object;
153 	int arb_framebuffer_object;
154 
155 	ogl_missing_func = NULL;
156 
157 	// Base OpenGL / OpenGL ES
158 	LoadOGLProc(avpPFNGLACTIVETEXTUREPROC, glActiveTexture);
159 	LoadOGLProc(avpPFNGLBINDTEXTUREPROC, glBindTexture);
160 	LoadOGLProc(avpPFNGLBLENDFUNCPROC, glBlendFunc);
161 	LoadOGLProc(avpPFNGLCLEARPROC, glClear);
162 	LoadOGLProc(avpPFNGLCLEARCOLORPROC, glClearColor);
163 	LoadOGLProc(avpPFNGLCULLFACEPROC, glCullFace);
164 	LoadOGLProc(avpPFNGLDELETETEXTURESPROC, glDeleteTextures);
165 	LoadOGLProc(avpPFNGLDEPTHFUNCPROC, glDepthFunc);
166 	LoadOGLProc(avpPFNGLDEPTHMASKPROC, glDepthMask);
167 	LoadOGLProc2(avpPFNGLDEPTHRANGEPROC, glDepthRange, glDepthRangef);
168 	LoadOGLProc(avpPFNGLDISABLEPROC, glDisable);
169 	LoadOGLProc(avpPFNGLDRAWELEMENTSPROC, glDrawElements);
170 	LoadOGLProc(avpPFNGLENABLEPROC, glEnable);
171 	LoadOGLProc(avpPFNGLFRONTFACEPROC, glFrontFace);
172 	LoadOGLProc(avpPFNGLGENTEXTURESPROC, glGenTextures);
173 	LoadOGLProc(avpPFNGLGETERRORPROC, glGetError);
174 	LoadOGLProc(avpPFNGLGETFLOATVPROC, glGetFloatv);
175 	LoadOGLProc(avpPFNGLGETINTEGERVPROC, glGetIntegerv);
176 	LoadOGLProc(avpPFNGLGETSTRINGPROC, glGetString);
177 	LoadOGLProc(avpPFNGLGETTEXPARAMETERFVPROC, glGetTexParameterfv);
178 	LoadOGLProc(avpPFNGLHINTPROC, glHint);
179 	LoadOGLProc(avpPFNGLPIXELSTOREIPROC, glPixelStorei);
180 	LoadOGLProc(avpPFNGLPOLYGONOFFSETPROC, glPolygonOffset);
181 	LoadOGLProc(avpPFNGLREADPIXELSPROC, glReadPixels);
182 	LoadOGLProc(avpPFNGLTEXIMAGE2DPROC, glTexImage2D);
183 	LoadOGLProc(avpPFNGLTEXPARAMETERFPROC, glTexParameterf);
184 	LoadOGLProc(avpPFNGLTEXPARAMETERIPROC, glTexParameteri);
185 	LoadOGLProc(avpPFNGLTEXSUBIMAGE2DPROC, glTexSubImage2D);
186 	LoadOGLProc(avpPFNGLVIEWPORTPROC, glViewport);
187 
188 	// OpenGL 2.1 / OpenGL ES 2.0
189 	LoadOGLProc(avpPFNGLATTACHSHADERPROC, glAttachShader);
190 	LoadOGLProc(avpPFNGLBINDATTRIBLOCATIONPROC, glBindAttribLocation);
191 	LoadOGLProc(avpPFNGLBINDBUFFERPROC, glBindBuffer);
192 	LoadOGLProc(avpPFNGLBUFFERDATAPROC, glBufferData);
193 	LoadOGLProc(avpPFNGLBUFFERSUBDATAPROC, glBufferSubData);
194 	LoadOGLProc(avpPFNGLCREATEPROGRAMPROC, glCreateProgram);
195 	LoadOGLProc(avpPFNGLCREATESHADERPROC, glCreateShader);
196 	LoadOGLProc(avpPFNGLCOMPILESHADERPROC, glCompileShader);
197 	LoadOGLProc(avpPFNGLDELETEBUFFERSPROC, glDeleteBuffers);
198 	LoadOGLProc(avpPFNGLDELETEPROGRAMPROC, glDeleteProgram);
199 	LoadOGLProc(avpPFNGLDELETESHADERPROC, glDeleteShader);
200 	LoadOGLProc(avpPFNGLDISABLEVERTEXATTRIBARRAYPROC, glDisableVertexAttribArray);
201 	LoadOGLProc(avpPFNGLENABLEVERTEXATTRIBARRAYPROC, glEnableVertexAttribArray);
202 	LoadOGLProc(avpPFNGLGENBUFFERSPROC, glGenBuffers);
203 	LoadOGLProc(avpPFNGLGETATTRIBLOCATIONPROC, glGetAttribLocation);
204 	LoadOGLProc(avpPFNGLGETPROGRAMINFOLOGPROC, glGetProgramInfoLog);
205 	LoadOGLProc(avpPFNGLGETPROGRAMIVPROC, glGetProgramiv);
206 	LoadOGLProc(avpPFNGLGETSHADERINFOLOGPROC, glGetShaderInfoLog);
207 	LoadOGLProc(avpPFNGLGETSHADERIVPROC, glGetShaderiv);
208 	LoadOGLProc(avpPFNGLGETUNIFORMLOCATIONPROC, glGetUniformLocation);
209 	LoadOGLProc(avpPFNGLLINKPROGRAMPROC, glLinkProgram);
210 	LoadOGLProc(avpPFNGLSHADERSOURCEPROC, glShaderSource);
211 	LoadOGLProc(avpPFNGLVALIDATEPROGRAMPROC, glValidateProgram);
212 	LoadOGLProc(avpPFNGLVERTEXATTRIBPOINTERPROC, glVertexAttribPointer);
213 	LoadOGLProc(avpPFNGLUNIFORM1IPROC, glUniform1i);
214 	LoadOGLProc(avpPFNGLUNIFORMMATRIX4FVPROC, glUniformMatrix4fv);
215 	LoadOGLProc(avpPFNGLUSEPROGRAMPROC, glUseProgram);
216 
217 	if (!mode) {
218 		return;
219 	}
220 
221 	if (ogl_missing_func) {
222 		fprintf(stderr, "Unable to load OpenGL Library: missing function %s\n", ogl_missing_func);
223 		exit(EXIT_FAILURE);
224 	}
225 
226 #if !defined(NDEBUG)
227 	printf("GL_VENDOR: %s\n", pglGetString(GL_VENDOR));
228 	printf("GL_RENDERER: %s\n", pglGetString(GL_RENDERER));
229 	printf("GL_VERSION: %s\n", pglGetString(GL_VERSION));
230 	printf("GL_SHADING_LANGUAGE_VERSION: %s\n", pglGetString(GL_SHADING_LANGUAGE_VERSION));
231 	printf("GL_EXTENSIONS: %s\n", pglGetString(GL_EXTENSIONS));
232 #endif
233 
234 	ext = (const char *) pglGetString(GL_EXTENSIONS);
235 
236 	// GL_EXT_framebuffer_object / GL_ARB_framebuffer_object / OpenGL ES 2.0
237 	// figure out which version of framebuffer objects to use, if any
238 	ext_framebuffer_object = check_token(ext, "GL_EXT_framebuffer_object");
239 	arb_framebuffer_object = check_token(ext, "GL_ARB_framebuffer_object");
240 
241 #if defined(USE_OPENGL_ES)
242 	// not quite right as ARB fbo includes functionality not present in ES2.
243 	base_framebuffer_object = 1;
244 #else
245 	base_framebuffer_object = arb_framebuffer_object;
246 #endif
247 
248 	ogl_missing_func = NULL;
249 	LoadOGLExtProc(base_framebuffer_object, avpPFNGLBINDFRAMEBUFFERPROC, glBindFramebuffer);
250 	LoadOGLExtProc(base_framebuffer_object, avpPFNGLBINDRENDERBUFFERPROC, glBindRenderbuffer);
251 	LoadOGLExtProc(base_framebuffer_object, avpPFNGLCHECKFRAMEBUFFERSTATUSPROC, glCheckFramebufferStatus);
252 	LoadOGLExtProc(base_framebuffer_object, avpPFNGLDELETEFRAMEBUFFERSPROC, glDeleteFramebuffers);
253 	LoadOGLExtProc(base_framebuffer_object, avpPFNGLDELETERENDERBUFFERSPROC, glDeleteRenderbuffers);
254 	LoadOGLExtProc(base_framebuffer_object, avpPFNGLFRAMEBUFFERRENDERBUFFERPROC, glFramebufferRenderbuffer);
255 	LoadOGLExtProc(base_framebuffer_object, avpPFNGLFRAMEBUFFERTEXTURE2DPROC, glFramebufferTexture2D);
256 	LoadOGLExtProc(base_framebuffer_object, avpPFNGLGENERATEMIPMAPPROC, glGenerateMipmap);
257 	LoadOGLExtProc(base_framebuffer_object, avpPFNGLGENFRAMEBUFFERSPROC, glGenFramebuffers);
258 	LoadOGLExtProc(base_framebuffer_object, avpPFNGLGENRENDERBUFFERSPROC, glGenRenderbuffers);
259 	LoadOGLExtProc(base_framebuffer_object, avpPFNGLRENDERBUFFERSTORAGEPROC, glRenderbufferStorage);
260 	if (base_framebuffer_object != 0 && ogl_missing_func == NULL) {
261 		ogl_have_framebuffer_object = 1;
262 
263 #if !defined(NDEBUG)
264 		printf("ARB/ES2 framebuffer objects enabled.\n");
265 #endif
266 	}
267 
268 	if (ext_framebuffer_object != 0 && ogl_have_framebuffer_object == 0) {
269 		// try the EXT suffixed functions
270 		ogl_missing_func = NULL;
271 		LoadOGLProc_(avpPFNGLBINDFRAMEBUFFERPROC, glBindFramebuffer, glBindFramebufferEXT);
272 		LoadOGLProc_(avpPFNGLBINDRENDERBUFFERPROC, glBindRenderbuffer, glBindRenderbufferEXT);
273 		LoadOGLProc_(avpPFNGLCHECKFRAMEBUFFERSTATUSPROC, glCheckFramebufferStatus, glCheckFramebufferStatusEXT);
274 		LoadOGLProc_(avpPFNGLDELETEFRAMEBUFFERSPROC, glDeleteFramebuffers, glDeleteFramebuffersEXT);
275 		LoadOGLProc_(avpPFNGLDELETERENDERBUFFERSPROC, glDeleteRenderbuffers, glDeleteRenderbuffersEXT);
276 		LoadOGLProc_(avpPFNGLFRAMEBUFFERRENDERBUFFERPROC, glFramebufferRenderbuffer, glFramebufferRenderbufferEXT);
277 		LoadOGLProc_(avpPFNGLFRAMEBUFFERTEXTURE2DPROC, glFramebufferTexture2D, glFramebufferTexture2DEXT);
278 		LoadOGLProc_(avpPFNGLGENERATEMIPMAPPROC, glGenerateMipmap, glGenerateMipmapEXT);
279 		LoadOGLProc_(avpPFNGLGENFRAMEBUFFERSPROC, glGenFramebuffers, glGenFramebuffersEXT);
280 		LoadOGLProc_(avpPFNGLGENRENDERBUFFERSPROC, glGenRenderbuffers, glGenRenderbuffersEXT);
281 		LoadOGLProc_(avpPFNGLRENDERBUFFERSTORAGEPROC, glRenderbufferStorage, glRenderbufferStorageEXT);
282 		if (ogl_missing_func == NULL) {
283 			ogl_have_framebuffer_object = 1;
284 
285 #if !defined(NDEBUG)
286 			printf("EXT framebuffer objects enabled.\n");
287 #endif
288 		}
289 	}
290 
291 	// other extensions
292 	ogl_have_multisample_filter_hint = check_token(ext, "GL_NV_multisample_filter_hint");
293 	ogl_have_texture_filter_anisotropic = check_token(ext, "GL_EXT_texture_filter_anisotropic");
294 
295 	ogl_use_multisample_filter_hint = ogl_have_multisample_filter_hint;
296 	ogl_use_texture_filter_anisotropic = ogl_have_texture_filter_anisotropic;
297 	ogl_use_framebuffer_object = ogl_have_framebuffer_object;
298 }
299 
check_for_errors_(const char * file,int line)300 int check_for_errors_(const char *file, int line)
301 {
302 	GLenum error;
303 	int diderror = 0;
304 
305 	while ((error = pglGetError()) != GL_NO_ERROR) {
306 		fprintf(stderr, "OPENGL ERROR: %04X (%s:%d)\n", error, file, line);
307 
308 		diderror = 1;
309 	}
310 
311 	return diderror;
312 }
313