Implement crude handling of missing OpenGL extensions
[neverball] / share / glext.c
1 /*
2  * Copyright (C) 2003-2011 Neverball authors
3  *
4  * NEVERBALL is  free software; you can redistribute  it and/or modify
5  * it under the  terms of the GNU General  Public License as published
6  * by the Free  Software Foundation; either version 2  of the License,
7  * or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT  ANY  WARRANTY;  without   even  the  implied  warranty  of
11  * MERCHANTABILITY or  FITNESS FOR A PARTICULAR PURPOSE.   See the GNU
12  * General Public License for more details.
13  */
14
15 #include <SDL.h>
16 #include <stdio.h>
17
18 #include "glext.h"
19
20 /*---------------------------------------------------------------------------*/
21
22 #if !ENABLE_OPENGLES
23
24 PFNGLCLIENTACTIVETEXTURE_PROC glClientActiveTexture_;
25 PFNGLACTIVETEXTURE_PROC       glActiveTexture_;
26
27 PFNGLGENBUFFERS_PROC          glGenBuffers_;
28 PFNGLBINDBUFFER_PROC          glBindBuffer_;
29 PFNGLBUFFERDATA_PROC          glBufferData_;
30 PFNGLBUFFERSUBDATA_PROC       glBufferSubData_;
31 PFNGLDELETEBUFFERS_PROC       glDeleteBuffers_;
32 PFNGLISBUFFER_PROC            glIsBuffer_;
33
34 PFNGLPOINTPARAMETERFV_PROC    glPointParameterfv_;
35
36 #endif
37
38 /*---------------------------------------------------------------------------*/
39
40 int glext_check(const char *needle)
41 {
42     const GLubyte *haystack, *c;
43
44     /* Search for the given string in the OpenGL extension strings. */
45
46     for (haystack = glGetString(GL_EXTENSIONS); *haystack; haystack++)
47     {
48         for (c = (const GLubyte *) needle; *c && *haystack; c++, haystack++)
49             if (*c != *haystack)
50                 break;
51
52         if ((*c == 0) && (*haystack == ' ' || *haystack == '\0'))
53             return 1;
54     }
55
56     return 0;
57 }
58
59 int glext_assert(const char *ext)
60 {
61     if (!glext_check(ext))
62     {
63         fprintf(stderr, "Missing required OpenGL extension (%s)\n", ext);
64         return 0;
65     }
66     return 1;
67 }
68
69 /*---------------------------------------------------------------------------*/
70
71 #define SDL_GL_GFPA(fun, str) do {       \
72     ptr = SDL_GL_GetProcAddress(str);    \
73     memcpy(&fun, &ptr, sizeof (void *)); \
74 } while(0)
75
76 /*---------------------------------------------------------------------------*/
77
78 int glext_init(void)
79 {
80 #if !ENABLE_OPENGLES
81
82     void *ptr;
83
84     if (glext_assert("ARB_multitexture"))
85     {
86         SDL_GL_GFPA(glClientActiveTexture_, "glClientActiveTextureARB");
87         SDL_GL_GFPA(glActiveTexture_,       "glActiveTextureARB");
88     }
89     else
90         return 0;
91
92     if (glext_assert("ARB_vertex_buffer_object"))
93     {
94         SDL_GL_GFPA(glGenBuffers_,          "glGenBuffersARB");
95         SDL_GL_GFPA(glBindBuffer_,          "glBindBufferARB");
96         SDL_GL_GFPA(glBufferData_,          "glBufferDataARB");
97         SDL_GL_GFPA(glBufferSubData_,       "glBufferSubDataARB");
98         SDL_GL_GFPA(glDeleteBuffers_,       "glDeleteBuffersARB");
99         SDL_GL_GFPA(glIsBuffer_,            "glIsBufferARB");
100     }
101     else
102         return 0;
103
104     if (glext_assert("ARB_point_parameters"))
105         SDL_GL_GFPA(glPointParameterfv_,   "glPointParameterfvARB");
106     else
107         return 0;
108
109     return 1;
110
111 #else
112
113     return 1;
114
115 #endif
116 }
117
118 /*---------------------------------------------------------------------------*/
119
120 void glClipPlane4f_(GLenum p, GLfloat a, GLfloat b, GLfloat c, GLfloat d)
121 {
122 #if ENABLE_OPENGLES
123
124     GLfloat v[4];
125
126     v[0] = a;
127     v[1] = b;
128     v[2] = c;
129     v[3] = d;
130
131     glClipPlanef(p, v);
132
133 #else
134
135     GLdouble v[4];
136
137     v[0] = a;
138     v[1] = b;
139     v[2] = c;
140     v[3] = d;
141
142     glClipPlane(p, v);
143
144 #endif
145 }
146
147 /*---------------------------------------------------------------------------*/