Merge branch 'gles'
[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 struct gl_info gli;
21
22 /*---------------------------------------------------------------------------*/
23
24 #if !ENABLE_OPENGLES
25
26 PFNGLCLIENTACTIVETEXTURE_PROC glClientActiveTexture_;
27 PFNGLACTIVETEXTURE_PROC       glActiveTexture_;
28
29 PFNGLGENBUFFERS_PROC          glGenBuffers_;
30 PFNGLBINDBUFFER_PROC          glBindBuffer_;
31 PFNGLBUFFERDATA_PROC          glBufferData_;
32 PFNGLBUFFERSUBDATA_PROC       glBufferSubData_;
33 PFNGLDELETEBUFFERS_PROC       glDeleteBuffers_;
34 PFNGLISBUFFER_PROC            glIsBuffer_;
35
36 PFNGLPOINTPARAMETERFV_PROC    glPointParameterfv_;
37
38 #endif
39
40 /*---------------------------------------------------------------------------*/
41
42 int glext_check(const char *needle)
43 {
44     const GLubyte *haystack, *c;
45
46     /* Search for the given string in the OpenGL extension strings. */
47
48     for (haystack = glGetString(GL_EXTENSIONS); *haystack; haystack++)
49     {
50         for (c = (const GLubyte *) needle; *c && *haystack; c++, haystack++)
51             if (*c != *haystack)
52                 break;
53
54         if ((*c == 0) && (*haystack == ' ' || *haystack == '\0'))
55             return 1;
56     }
57
58     return 0;
59 }
60
61 int glext_assert(const char *ext)
62 {
63     if (!glext_check(ext))
64     {
65         fprintf(stderr, "Missing required OpenGL extension (%s)\n", ext);
66         return 0;
67     }
68     return 1;
69 }
70
71 /*---------------------------------------------------------------------------*/
72
73 #define SDL_GL_GFPA(fun, str) do {       \
74     ptr = SDL_GL_GetProcAddress(str);    \
75     memcpy(&fun, &ptr, sizeof (void *)); \
76 } while(0)
77
78 /*---------------------------------------------------------------------------*/
79
80 int glext_init(void)
81 {
82     void *ptr = 0;
83
84     memset(&gli, 0, sizeof (struct gl_info));
85
86     /* Common init. */
87
88     gli.max_texture_units = 1;
89     glGetIntegerv(GL_MAX_TEXTURE_SIZE, &gli.max_texture_size);
90
91 #if !ENABLE_OPENGLES
92     /* Desktop init. */
93
94     if (glext_assert("ARB_multitexture"))
95     {
96         glGetIntegerv(GL_MAX_TEXTURE_UNITS, &gli.max_texture_units);
97
98         SDL_GL_GFPA(glClientActiveTexture_, "glClientActiveTextureARB");
99         SDL_GL_GFPA(glActiveTexture_,       "glActiveTextureARB");
100
101         gli.multitexture = 1;
102     }
103
104     if (glext_assert("ARB_vertex_buffer_object"))
105     {
106         SDL_GL_GFPA(glGenBuffers_,          "glGenBuffersARB");
107         SDL_GL_GFPA(glBindBuffer_,          "glBindBufferARB");
108         SDL_GL_GFPA(glBufferData_,          "glBufferDataARB");
109         SDL_GL_GFPA(glBufferSubData_,       "glBufferSubDataARB");
110         SDL_GL_GFPA(glDeleteBuffers_,       "glDeleteBuffersARB");
111         SDL_GL_GFPA(glIsBuffer_,            "glIsBufferARB");
112
113         gli.vertex_buffer_object = 1;
114     }
115
116     if (glext_assert("ARB_point_parameters"))
117     {
118         SDL_GL_GFPA(glPointParameterfv_,   "glPointParameterfvARB");
119
120         gli.point_parameters = 1;
121     }
122
123     return (gli.multitexture &&
124             gli.vertex_buffer_object &&
125             gli.point_parameters);
126 #else
127     /* GLES init. */
128
129     glGetIntegerv(GL_MAX_TEXTURE_UNITS, &gli.max_texture_units);
130
131     gli.multitexture = 1;
132     gli.vertex_buffer_object = 1;
133     gli.point_parameters = 1;
134
135     return 1;
136 #endif
137 }
138
139 /*---------------------------------------------------------------------------*/
140
141 void glClipPlane4f_(GLenum p, GLfloat a, GLfloat b, GLfloat c, GLfloat d)
142 {
143 #if ENABLE_OPENGLES
144
145     GLfloat v[4];
146
147     v[0] = a;
148     v[1] = b;
149     v[2] = c;
150     v[3] = d;
151
152     glClipPlanef(p, v);
153
154 #else
155
156     GLdouble v[4];
157
158     v[0] = a;
159     v[1] = b;
160     v[2] = c;
161     v[3] = d;
162
163     glClipPlane(p, v);
164
165 #endif
166 }
167
168 /*---------------------------------------------------------------------------*/