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