Skip to content

Latest commit

 

History

History
1397 lines (1158 loc) · 45.3 KB

mojoshader_opengl.c

File metadata and controls

1397 lines (1158 loc) · 45.3 KB
 
Apr 29, 2008
Apr 29, 2008
1
2
3
4
5
6
7
8
9
/**
* MojoShader; generate shader programs from bytecode of compiled
* Direct3D shaders.
*
* Please see the file LICENSE.txt in the source's root directory.
*
* This file written by Ryan C. Gordon.
*/
Apr 26, 2008
Apr 26, 2008
10
11
12
13
14
15
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include <assert.h>
Apr 30, 2008
Apr 30, 2008
16
17
18
19
20
#ifdef _MSC_VER
#define WIN32_LEAN_AND_MEAN 1
#include <windows.h> // GL headers need this for WINGDIAPI definition.
#endif
Apr 26, 2008
Apr 26, 2008
21
#include "mojoshader.h"
Apr 27, 2008
Apr 27, 2008
22
#define GL_GLEXT_LEGACY 1
Apr 29, 2008
Apr 29, 2008
23
24
#include "GL/gl.h"
#include "GL/glext.h"
Apr 26, 2008
Apr 26, 2008
25
26
27
28
// Get basic wankery out of the way here...
typedef unsigned int uint; // this is a printf() helper. don't use for code.
Apr 30, 2008
Apr 30, 2008
29
30
31
32
33
34
#ifdef _MSC_VER
#define snprintf _snprintf
typedef unsigned __int8 uint8;
typedef unsigned __int32 uint32;
typedef unsigned __int32 int32;
May 8, 2008
May 8, 2008
35
36
37
// Warning Level 4 considered harmful. :)
#pragma warning(disable: 4100) // "unreferenced formal parameter"
#pragma warning(disable: 4389) // "signed/unsigned mismatch"
Apr 30, 2008
Apr 30, 2008
38
39
#else
#include <stdint.h>
Apr 26, 2008
Apr 26, 2008
40
41
42
typedef uint8_t uint8;
typedef uint32_t uint32;
typedef int32_t int32;
Apr 30, 2008
Apr 30, 2008
43
44
45
#endif
#define STATICARRAYLEN(x) ( (sizeof ((x))) / (sizeof ((x)[0])) )
Apr 26, 2008
Apr 26, 2008
46
Apr 30, 2008
Apr 30, 2008
47
48
49
50
#ifndef SUPPORT_PROFILE_GLSL
#define SUPPORT_PROFILE_GLSL 1
#endif
May 25, 2008
May 25, 2008
51
52
53
54
#ifndef SUPPORT_PROFILE_ARB1
#define SUPPORT_PROFILE_ARB1 1
#endif
Apr 26, 2008
Apr 26, 2008
55
56
57
struct MOJOSHADER_glShader
{
const MOJOSHADER_parseData *parseData;
May 25, 2008
May 25, 2008
58
GLuint handle;
Apr 26, 2008
Apr 26, 2008
59
60
61
uint32 refcount;
};
Apr 27, 2008
Apr 27, 2008
62
63
typedef struct
{
Apr 27, 2008
Apr 27, 2008
64
MOJOSHADER_shaderType shader_type;
Apr 27, 2008
Apr 27, 2008
65
const MOJOSHADER_uniform *uniform;
Apr 27, 2008
Apr 27, 2008
66
GLuint location;
Apr 27, 2008
Apr 27, 2008
67
68
} UniformMap;
May 6, 2008
May 6, 2008
69
70
71
72
73
74
75
typedef struct
{
MOJOSHADER_shaderType shader_type;
const MOJOSHADER_sampler *sampler;
GLuint location;
} SamplerMap;
Apr 27, 2008
Apr 27, 2008
76
77
typedef struct
{
Apr 27, 2008
Apr 27, 2008
78
const MOJOSHADER_attribute *attribute;
Apr 27, 2008
Apr 27, 2008
79
GLuint location;
Apr 27, 2008
Apr 27, 2008
80
81
} AttributeMap;
Apr 26, 2008
Apr 26, 2008
82
83
struct MOJOSHADER_glProgram
{
Apr 27, 2008
Apr 27, 2008
84
85
MOJOSHADER_glShader *vertex;
MOJOSHADER_glShader *fragment;
May 25, 2008
May 25, 2008
86
GLuint handle;
May 6, 2008
May 6, 2008
87
88
uint32 constant_count; // !!! FIXME: misnamed.
GLfloat *constants; // !!! FIXME: misnamed.
Apr 27, 2008
Apr 27, 2008
89
uint32 uniform_count;
Apr 27, 2008
Apr 27, 2008
90
UniformMap *uniforms;
May 6, 2008
May 6, 2008
91
92
uint32 sampler_count;
SamplerMap *samplers;
Apr 27, 2008
Apr 27, 2008
93
uint32 attribute_count;
Apr 27, 2008
Apr 27, 2008
94
AttributeMap *attributes;
Apr 26, 2008
Apr 26, 2008
95
96
97
uint32 refcount;
};
May 3, 2008
May 3, 2008
98
99
100
101
#ifndef WINGDIAPI
#define WINGDIAPI
#endif
Apr 28, 2008
Apr 28, 2008
102
// Entry points in base OpenGL that lack function pointer prototypes...
May 3, 2008
May 3, 2008
103
104
typedef WINGDIAPI void (APIENTRYP PFNGLGETINTEGERVPROC) (GLenum pname, GLint *params);
typedef WINGDIAPI const GLubyte * (APIENTRYP PFNGLGETSTRINGPROC) (GLenum name);
May 28, 2008
May 28, 2008
105
typedef WINGDIAPI GLenum (APIENTRYP PFNGLGETERRORPROC) (void);
Apr 28, 2008
Apr 28, 2008
106
Apr 28, 2008
Apr 28, 2008
107
108
109
110
111
112
113
114
115
struct MOJOSHADER_glContext
{
// Allocators...
MOJOSHADER_malloc malloc_fn;
MOJOSHADER_free free_fn;
void *malloc_data;
// The constant register files...
// Man, it kills me how much memory this takes...
Apr 29, 2008
Apr 29, 2008
116
117
118
119
120
121
GLfloat vs_reg_file_f[8192 * 4];
GLint vs_reg_file_i[2047 * 4];
GLint vs_reg_file_b[2047];
GLfloat ps_reg_file_f[8192 * 4];
GLint ps_reg_file_i[2047 * 4];
GLint ps_reg_file_b[2047];
May 6, 2008
May 6, 2008
122
GLuint sampler_reg_file[16];
Apr 28, 2008
Apr 28, 2008
123
124
125
126
127
// GL stuff...
int opengl_major;
int opengl_minor;
MOJOSHADER_glProgram *bound_program;
Apr 30, 2008
Apr 30, 2008
128
char profile[16];
Apr 28, 2008
Apr 28, 2008
129
130
131
// Extensions...
int have_base_opengl;
May 25, 2008
May 25, 2008
132
133
int have_GL_ARB_vertex_program;
int have_GL_ARB_fragment_program;
Apr 28, 2008
Apr 28, 2008
134
135
136
137
138
139
140
141
int have_GL_ARB_shader_objects;
int have_GL_ARB_vertex_shader;
int have_GL_ARB_fragment_shader;
int have_GL_ARB_shading_language_100;
int have_GL_NV_half_float;
// Entry points...
PFNGLGETSTRINGPROC glGetString;
May 28, 2008
May 28, 2008
142
PFNGLGETERRORPROC glGetError;
May 3, 2008
May 3, 2008
143
PFNGLGETINTEGERVPROC glGetIntegerv;
Apr 28, 2008
Apr 28, 2008
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
PFNGLDELETEOBJECTARBPROC glDeleteObject;
PFNGLATTACHOBJECTARBPROC glAttachObject;
PFNGLCOMPILESHADERARBPROC glCompileShader;
PFNGLCREATEPROGRAMOBJECTARBPROC glCreateProgramObject;
PFNGLCREATESHADEROBJECTARBPROC glCreateShaderObject;
PFNGLDISABLEVERTEXATTRIBARRAYARBPROC glDisableVertexAttribArray;
PFNGLENABLEVERTEXATTRIBARRAYARBPROC glEnableVertexAttribArray;
PFNGLGETATTRIBLOCATIONARBPROC glGetAttribLocation;
PFNGLGETINFOLOGARBPROC glGetInfoLog;
PFNGLGETOBJECTPARAMETERIVARBPROC glGetObjectParameteriv;
PFNGLGETUNIFORMLOCATIONARBPROC glGetUniformLocation;
PFNGLLINKPROGRAMARBPROC glLinkProgram;
PFNGLSHADERSOURCEARBPROC glShaderSource;
PFNGLUNIFORM1IARBPROC glUniform1i;
PFNGLUNIFORM4FVARBPROC glUniform4fv;
PFNGLUNIFORM4IVARBPROC glUniform4iv;
PFNGLUSEPROGRAMOBJECTARBPROC glUseProgramObject;
PFNGLVERTEXATTRIBPOINTERARBPROC glVertexAttribPointer;
May 28, 2008
May 28, 2008
162
163
164
165
166
167
168
PFNGLGETPROGRAMIVARBPROC glGetProgramivARB;
PFNGLGETPROGRAMSTRINGARBPROC glGetProgramStringARB;
PFNGLPROGRAMENVPARAMETER4FVARBPROC glProgramEnvParameter4fvARB;
PFNGLDELETEPROGRAMSARBPROC glDeleteProgramsARB;
PFNGLGENPROGRAMSARBPROC glGenProgramsARB;
PFNGLBINDPROGRAMARBPROC glBindProgramARB;
PFNGLPROGRAMSTRINGARBPROC glProgramStringARB;
May 25, 2008
May 25, 2008
169
170
171
// interface for profile-specific things.
int (*profileMaxUniforms)(MOJOSHADER_shaderType shader_type);
May 28, 2008
May 28, 2008
172
int (*profileCompileShader)(const MOJOSHADER_parseData *pd, GLuint *s);
May 25, 2008
May 25, 2008
173
174
void (*profileDeleteShader)(const GLuint shader);
void (*profileDeleteProgram)(const GLuint program);
May 28, 2008
May 28, 2008
175
176
177
GLint (*profileGetUniformLocation)(GLuint, const MOJOSHADER_parseData *, int);
GLuint (*profileLinkProgram)(MOJOSHADER_glShader *, MOJOSHADER_glShader *);
void (*profileUseProgramObject)(MOJOSHADER_glProgram *program);
May 29, 2008
May 29, 2008
178
179
180
void (*profileUniform4fv)(const MOJOSHADER_parseData *pd, GLint loc, GLsizei siz, GLfloat *v);
void (*profileUniform4iv)(const MOJOSHADER_parseData *pd, GLint loc, GLsizei siz, GLint *v);
void (*profileUniform1i)(const MOJOSHADER_parseData *pd, GLint loc, GLint v);
May 28, 2008
May 28, 2008
181
void (*profileSetSampler)(GLint loc, GLuint sampler);
Apr 28, 2008
Apr 28, 2008
182
183
};
May 25, 2008
May 25, 2008
184
185
// predeclare some profile implementation stuff...
static int impl_GLSL_MaxUniforms(MOJOSHADER_shaderType shader_type);
May 28, 2008
May 28, 2008
186
187
188
189
190
191
static int impl_GLSL_CompileShader(const MOJOSHADER_parseData *pd, GLuint *s);
static void impl_GLSL_DeleteShader(const GLuint shader);
static void impl_GLSL_DeleteProgram(const GLuint program);
static GLint impl_GLSL_GetUniformLocation(GLuint, const MOJOSHADER_parseData *, int);
static GLuint impl_GLSL_LinkProgram(MOJOSHADER_glShader *, MOJOSHADER_glShader *);
static void impl_GLSL_UseProgramObject(MOJOSHADER_glProgram *program);
May 29, 2008
May 29, 2008
192
193
194
static void impl_GLSL_Uniform4fv(const MOJOSHADER_parseData *pd, GLint loc, GLsizei siz, GLfloat *v);
static void impl_GLSL_Uniform4iv(const MOJOSHADER_parseData *pd, GLint loc, GLsizei siz, GLint *v);
static void impl_GLSL_Uniform1i(const MOJOSHADER_parseData *pd, GLint loc, GLint v);
May 28, 2008
May 28, 2008
195
196
static void impl_GLSL_SetSampler(GLint loc, GLuint sampler);
May 25, 2008
May 25, 2008
197
static int impl_ARB1_MaxUniforms(MOJOSHADER_shaderType shader_type);
May 28, 2008
May 28, 2008
198
199
200
201
202
203
static int impl_ARB1_CompileShader(const MOJOSHADER_parseData *pd, GLuint *s);
static void impl_ARB1_DeleteShader(const GLuint shader);
static void impl_ARB1_DeleteProgram(const GLuint program);
static GLint impl_ARB1_GetUniformLocation(GLuint, const MOJOSHADER_parseData *, int);
static GLuint impl_ARB1_LinkProgram(MOJOSHADER_glShader *, MOJOSHADER_glShader *);
static void impl_ARB1_UseProgramObject(MOJOSHADER_glProgram *program);
May 29, 2008
May 29, 2008
204
205
206
static void impl_ARB1_Uniform4fv(const MOJOSHADER_parseData *pd, GLint loc, GLsizei siz, GLfloat *v);
static void impl_ARB1_Uniform4iv(const MOJOSHADER_parseData *pd, GLint loc, GLsizei siz, GLint *v);
static void impl_ARB1_Uniform1i(const MOJOSHADER_parseData *pd, GLint loc, GLint v);
May 28, 2008
May 28, 2008
207
static void impl_ARB1_SetSampler(GLint loc, GLuint sampler);
May 25, 2008
May 25, 2008
208
209
210
Apr 28, 2008
Apr 28, 2008
211
static MOJOSHADER_glContext *ctx = NULL;
Apr 28, 2008
Apr 28, 2008
212
Apr 26, 2008
Apr 26, 2008
213
Apr 27, 2008
Apr 27, 2008
214
215
216
217
218
219
220
221
// Error state...
static char error_buffer[1024] = { '\0' };
static void set_error(const char *str)
{
snprintf(error_buffer, sizeof (error_buffer), "%s", str);
} // set_error
Apr 26, 2008
Apr 26, 2008
222
223
224
225
226
227
228
229
230
231
232
233
234
// #define this to force app to supply an allocator, so there's no reference
// to the C runtime's malloc() and free()...
#if MOJOSHADER_FORCE_ALLOCATOR
#define internal_malloc NULL
#define internal_free NULL
#else
static void *internal_malloc(int bytes, void *d) { return malloc(bytes); }
static void internal_free(void *ptr, void *d) { free(ptr); }
#endif
static inline void *Malloc(const size_t len)
{
May 10, 2008
May 10, 2008
235
void *retval = ctx->malloc_fn((int) len, ctx->malloc_data);
Apr 27, 2008
Apr 27, 2008
236
237
238
if (retval == NULL)
set_error("out of memory");
return retval;
Apr 26, 2008
Apr 26, 2008
239
240
241
242
} // Malloc
static inline void Free(void *ptr)
{
Apr 27, 2008
Apr 27, 2008
243
if (ptr != NULL)
Apr 28, 2008
Apr 28, 2008
244
ctx->free_fn(ptr, ctx->malloc_data);
Apr 26, 2008
Apr 26, 2008
245
246
247
} // Free
Apr 27, 2008
Apr 27, 2008
248
249
250
251
252
253
const char *MOJOSHADER_glGetError(void)
{
return error_buffer;
} // MOJOSHADER_glGetError
Apr 28, 2008
Apr 28, 2008
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
static void *loadsym(void *(*lookup)(const char *fn), const char *fn, int *ext)
{
void *retval = NULL;
if (lookup != NULL)
{
retval = lookup(fn);
if (retval == NULL)
{
char arbfn[64];
snprintf(arbfn, sizeof (arbfn), "%sARB", fn);
retval = lookup(arbfn);
} // if
} // if
if (retval == NULL)
*ext = 0;
return retval;
} // loadsym
static void lookup_entry_points(void *(*lookup)(const char *fnname))
{
Apr 28, 2008
Apr 28, 2008
276
#define DO_LOOKUP(ext, typ, fn) ctx->fn = (typ) loadsym(lookup, #fn, &ctx->have_##ext)
Apr 28, 2008
Apr 28, 2008
277
DO_LOOKUP(base_opengl, PFNGLGETSTRINGPROC, glGetString);
May 28, 2008
May 28, 2008
278
DO_LOOKUP(base_opengl, PFNGLGETERRORPROC, glGetError);
May 3, 2008
May 3, 2008
279
DO_LOOKUP(base_opengl, PFNGLGETINTEGERVPROC, glGetIntegerv);
Apr 28, 2008
Apr 28, 2008
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
DO_LOOKUP(GL_ARB_shader_objects, PFNGLDELETEOBJECTARBPROC, glDeleteObject);
DO_LOOKUP(GL_ARB_shader_objects, PFNGLATTACHOBJECTARBPROC, glAttachObject);
DO_LOOKUP(GL_ARB_shader_objects, PFNGLCOMPILESHADERARBPROC, glCompileShader);
DO_LOOKUP(GL_ARB_shader_objects, PFNGLCREATEPROGRAMOBJECTARBPROC, glCreateProgramObject);
DO_LOOKUP(GL_ARB_shader_objects, PFNGLCREATESHADEROBJECTARBPROC, glCreateShaderObject);
DO_LOOKUP(GL_ARB_shader_objects, PFNGLGETINFOLOGARBPROC, glGetInfoLog);
DO_LOOKUP(GL_ARB_shader_objects, PFNGLGETOBJECTPARAMETERIVARBPROC, glGetObjectParameteriv);
DO_LOOKUP(GL_ARB_shader_objects, PFNGLGETUNIFORMLOCATIONARBPROC, glGetUniformLocation);
DO_LOOKUP(GL_ARB_shader_objects, PFNGLLINKPROGRAMARBPROC, glLinkProgram);
DO_LOOKUP(GL_ARB_shader_objects, PFNGLSHADERSOURCEARBPROC, glShaderSource);
DO_LOOKUP(GL_ARB_shader_objects, PFNGLUNIFORM1IARBPROC, glUniform1i);
DO_LOOKUP(GL_ARB_shader_objects, PFNGLUNIFORM4FVARBPROC, glUniform4fv);
DO_LOOKUP(GL_ARB_shader_objects, PFNGLUNIFORM4IVARBPROC, glUniform4iv);
DO_LOOKUP(GL_ARB_shader_objects, PFNGLUSEPROGRAMOBJECTARBPROC, glUseProgramObject);
DO_LOOKUP(GL_ARB_vertex_shader, PFNGLDISABLEVERTEXATTRIBARRAYARBPROC, glDisableVertexAttribArray);
DO_LOOKUP(GL_ARB_vertex_shader, PFNGLENABLEVERTEXATTRIBARRAYARBPROC, glEnableVertexAttribArray);
DO_LOOKUP(GL_ARB_vertex_shader, PFNGLGETATTRIBLOCATIONARBPROC, glGetAttribLocation);
DO_LOOKUP(GL_ARB_vertex_shader, PFNGLVERTEXATTRIBPOINTERARBPROC, glVertexAttribPointer);
May 28, 2008
May 28, 2008
298
299
300
301
302
303
304
305
306
307
DO_LOOKUP(GL_ARB_vertex_program, PFNGLUSEPROGRAMOBJECTARBPROC, glUseProgramObject);
DO_LOOKUP(GL_ARB_vertex_program, PFNGLVERTEXATTRIBPOINTERARBPROC, glVertexAttribPointer);
DO_LOOKUP(GL_ARB_vertex_program, PFNGLGETPROGRAMIVARBPROC, glGetProgramivARB);
DO_LOOKUP(GL_ARB_vertex_program, PFNGLGETPROGRAMSTRINGARBPROC, glGetProgramStringARB);
DO_LOOKUP(GL_ARB_vertex_program, PFNGLPROGRAMENVPARAMETER4FVARBPROC, glProgramEnvParameter4fvARB);
DO_LOOKUP(GL_ARB_vertex_program, PFNGLDELETEPROGRAMSARBPROC, glDeleteProgramsARB);
DO_LOOKUP(GL_ARB_vertex_program, PFNGLGENPROGRAMSARBPROC, glGenProgramsARB);
DO_LOOKUP(GL_ARB_vertex_program, PFNGLBINDPROGRAMARBPROC, glBindProgramARB);
DO_LOOKUP(GL_ARB_vertex_program, PFNGLPROGRAMSTRINGARBPROC, glProgramStringARB);
Apr 28, 2008
Apr 28, 2008
308
309
310
311
312
313
314
315
316
317
#undef DO_LOOKUP
} // lookup_entry_points
static int verify_extension(const char *ext, int have, const char *extlist,
int major, int minor)
{
if (have == 0)
return 0; // don't bother checking, we're missing an entry point.
Apr 30, 2008
Apr 30, 2008
318
319
320
else if (!ctx->have_base_opengl)
return 0; // don't bother checking, we're missing basic functionality.
Apr 28, 2008
Apr 28, 2008
321
// See if it's in the spec for this GL implementation's version.
Apr 28, 2008
Apr 28, 2008
322
323
if (major >= 0)
{
Apr 28, 2008
Apr 28, 2008
324
if ( ((ctx->opengl_major << 16) | (ctx->opengl_minor & 0xFFFF)) >=
Apr 28, 2008
Apr 28, 2008
325
326
327
((major << 16) | (minor & 0xFFFF)) )
return 1;
} // if
Apr 28, 2008
Apr 28, 2008
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
// Not available in the GL version, check the extension list.
const char *ptr = strstr(extlist, ext);
if (ptr == NULL)
return 0;
const char endchar = ptr[strlen(ext)];
if ((endchar == '\0') || (endchar == ' '))
return 1; // extension is in the list.
return 0; // just not supported, fail.
} // verify_extension
static void parse_opengl_version(const char *verstr)
{
if (verstr == NULL)
Apr 28, 2008
Apr 28, 2008
345
ctx->opengl_major = ctx->opengl_minor = 0;
Apr 28, 2008
Apr 28, 2008
346
else
Apr 28, 2008
Apr 28, 2008
347
sscanf(verstr, "%d.%d", &ctx->opengl_major, &ctx->opengl_minor);
Apr 28, 2008
Apr 28, 2008
348
349
350
} // parse_opengl_version
Apr 30, 2008
Apr 30, 2008
351
static void load_extensions(void *(*lookup)(const char *fnname))
Apr 28, 2008
Apr 28, 2008
352
{
Apr 30, 2008
Apr 30, 2008
353
354
const char *extlist = NULL;
Apr 28, 2008
Apr 28, 2008
355
ctx->have_base_opengl = 1;
May 25, 2008
May 25, 2008
356
357
ctx->have_GL_ARB_vertex_program = 1;
ctx->have_GL_ARB_fragment_program = 1;
Apr 28, 2008
Apr 28, 2008
358
359
360
361
362
ctx->have_GL_ARB_shader_objects = 1;
ctx->have_GL_ARB_vertex_shader = 1;
ctx->have_GL_ARB_fragment_shader = 1;
ctx->have_GL_ARB_shading_language_100 = 1;
ctx->have_GL_NV_half_float = 1;
Apr 28, 2008
Apr 28, 2008
363
364
365
lookup_entry_points(lookup);
Apr 30, 2008
Apr 30, 2008
366
if (!ctx->have_base_opengl)
Apr 28, 2008
Apr 28, 2008
367
set_error("missing basic OpenGL entry points");
Apr 30, 2008
Apr 30, 2008
368
369
370
371
372
else
{
parse_opengl_version((const char *) ctx->glGetString(GL_VERSION));
extlist = (const char *) ctx->glGetString(GL_EXTENSIONS);
} // else
Apr 28, 2008
Apr 28, 2008
373
374
375
376
377
if (extlist == NULL)
extlist = ""; // just in case.
#define VERIFY_EXT(ext, major, minor) \
Apr 28, 2008
Apr 28, 2008
378
ctx->have_##ext = verify_extension(#ext, ctx->have_##ext, extlist, major, minor)
Apr 28, 2008
Apr 28, 2008
379
May 25, 2008
May 25, 2008
380
381
VERIFY_EXT(GL_ARB_vertex_program, -1, -1);
VERIFY_EXT(GL_ARB_fragment_program, -1, -1);
Apr 28, 2008
Apr 28, 2008
382
383
384
385
VERIFY_EXT(GL_ARB_shader_objects, 2, 0);
VERIFY_EXT(GL_ARB_vertex_shader, 2, 0);
VERIFY_EXT(GL_ARB_fragment_shader, 2, 0);
VERIFY_EXT(GL_ARB_shading_language_100, 2, 0);
Apr 28, 2008
Apr 28, 2008
386
VERIFY_EXT(GL_NV_half_float, -1, -1);
Apr 28, 2008
Apr 28, 2008
387
388
#undef VERIFY_EXT
Apr 30, 2008
Apr 30, 2008
389
390
391
392
393
394
395
} // load_extensions
static int valid_profile(const char *profile)
{
if (!ctx->have_base_opengl)
return 0;
Apr 28, 2008
Apr 28, 2008
396
Apr 30, 2008
Apr 30, 2008
397
398
#define MUST_HAVE(p, x) \
if (!ctx->have_##x) { set_error(#p " profile needs " #x); return 0; }
Apr 28, 2008
Apr 28, 2008
399
May 8, 2008
May 8, 2008
400
401
402
403
404
if (profile == NULL)
{
set_error("NULL profile");
return 0;
} // if
Apr 30, 2008
Apr 30, 2008
405
May 25, 2008
May 25, 2008
406
407
408
409
410
411
412
413
#if SUPPORT_PROFILE_ARB1
else if (strcmp(profile, MOJOSHADER_PROFILE_ARB1) == 0)
{
MUST_HAVE(MOJOSHADER_PROFILE_ARB1, GL_ARB_vertex_program);
MUST_HAVE(MOJOSHADER_PROFILE_ARB1, GL_ARB_fragment_program);
} // else if
#endif
Apr 30, 2008
Apr 30, 2008
414
415
#if SUPPORT_PROFILE_GLSL
else if (strcmp(profile, MOJOSHADER_PROFILE_GLSL) == 0)
Apr 28, 2008
Apr 28, 2008
416
{
Apr 30, 2008
Apr 30, 2008
417
418
419
420
421
422
MUST_HAVE(MOJOSHADER_PROFILE_GLSL, GL_ARB_shader_objects);
MUST_HAVE(MOJOSHADER_PROFILE_GLSL, GL_ARB_vertex_shader);
MUST_HAVE(MOJOSHADER_PROFILE_GLSL, GL_ARB_fragment_shader);
MUST_HAVE(MOJOSHADER_PROFILE_GLSL, GL_ARB_shading_language_100);
} // else if
#endif
Apr 28, 2008
Apr 28, 2008
423
424
425
else
{
Apr 30, 2008
Apr 30, 2008
426
set_error("unknown or unsupported profile");
Apr 28, 2008
Apr 28, 2008
427
428
429
return 0;
} // else
Apr 30, 2008
Apr 30, 2008
430
#undef MUST_HAVE
Apr 28, 2008
Apr 28, 2008
431
432
return 1;
Apr 30, 2008
Apr 30, 2008
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
} // valid_profile
const char *MOJOSHADER_glBestProfile(void *(*lookup)(const char *fnname))
{
const char *retval = NULL;
MOJOSHADER_glContext _ctx;
MOJOSHADER_glContext *current_ctx = ctx;
ctx = &_ctx;
memset(ctx, '\0', sizeof (MOJOSHADER_glContext));
load_extensions(lookup);
if (ctx->have_base_opengl)
{
static const char *priority[] = {
MOJOSHADER_PROFILE_GLSL,
May 25, 2008
May 25, 2008
450
MOJOSHADER_PROFILE_ARB1,
Apr 30, 2008
Apr 30, 2008
451
452
453
454
455
};
int i;
for (i = 0; i < STATICARRAYLEN(priority); i++)
{
May 28, 2008
May 28, 2008
456
457
// !!! FIXME: if Mac OS X <= 10.4, don't ever pick GLSL, even if
// !!! FIXME: the system claims it is available.
Apr 30, 2008
Apr 30, 2008
458
459
460
461
462
463
if (valid_profile(priority[i]))
{
retval = priority[i];
break;
} // if
} // for
Apr 28, 2008
Apr 28, 2008
464
Apr 30, 2008
Apr 30, 2008
465
466
467
if (retval == NULL)
set_error("no profiles available");
} // if
Apr 28, 2008
Apr 28, 2008
468
Apr 30, 2008
Apr 30, 2008
469
470
471
472
473
474
ctx = current_ctx;
return retval;
} // MOJOSHADER_glBestProfile
MOJOSHADER_glContext *MOJOSHADER_glCreateContext(const char *profile,
Apr 28, 2008
Apr 28, 2008
475
476
477
void *(*lookup)(const char *fnname),
MOJOSHADER_malloc m, MOJOSHADER_free f,
void *d)
Apr 26, 2008
Apr 26, 2008
478
{
Apr 29, 2008
Apr 29, 2008
479
MOJOSHADER_glContext *retval = NULL;
Apr 28, 2008
Apr 28, 2008
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
MOJOSHADER_glContext *current_ctx = ctx;
ctx = NULL;
if (m == NULL) m = internal_malloc;
if (f == NULL) f = internal_free;
ctx = (MOJOSHADER_glContext *) m(sizeof (MOJOSHADER_glContext), d);
if (ctx == NULL)
{
set_error("out of memory");
goto init_fail;
} // if
memset(ctx, '\0', sizeof (MOJOSHADER_glContext));
ctx->malloc_fn = m;
ctx->free_fn = f;
ctx->malloc_data = d;
Apr 30, 2008
Apr 30, 2008
497
snprintf(ctx->profile, sizeof (ctx->profile), "%s", profile);
Apr 27, 2008
Apr 27, 2008
498
Apr 30, 2008
Apr 30, 2008
499
500
load_extensions(lookup);
if (!valid_profile(profile))
Apr 28, 2008
Apr 28, 2008
501
goto init_fail;
Apr 26, 2008
Apr 26, 2008
502
503
504
MOJOSHADER_glBindProgram(NULL);
May 25, 2008
May 25, 2008
505
506
507
508
509
510
511
512
513
514
// !!! FIXME: generalize this part.
if (profile == NULL) {}
#if SUPPORT_PROFILE_GLSL
else if (strcmp(profile, MOJOSHADER_PROFILE_GLSL) == 0)
{
ctx->profileMaxUniforms = impl_GLSL_MaxUniforms;
ctx->profileCompileShader = impl_GLSL_CompileShader;
ctx->profileDeleteShader = impl_GLSL_DeleteShader;
ctx->profileDeleteProgram = impl_GLSL_DeleteProgram;
May 28, 2008
May 28, 2008
515
516
517
518
519
520
521
ctx->profileGetUniformLocation = impl_GLSL_GetUniformLocation;
ctx->profileLinkProgram = impl_GLSL_LinkProgram;
ctx->profileUseProgramObject = impl_GLSL_UseProgramObject;
ctx->profileUniform4fv = impl_GLSL_Uniform4fv;
ctx->profileUniform4iv = impl_GLSL_Uniform4iv;
ctx->profileUniform1i = impl_GLSL_Uniform1i;
ctx->profileSetSampler = impl_GLSL_SetSampler;
May 25, 2008
May 25, 2008
522
523
524
525
526
527
528
529
530
531
} // if
#endif
#if SUPPORT_PROFILE_ARB1
else if (strcmp(profile, MOJOSHADER_PROFILE_ARB1) == 0)
{
ctx->profileMaxUniforms = impl_ARB1_MaxUniforms;
ctx->profileCompileShader = impl_ARB1_CompileShader;
ctx->profileDeleteShader = impl_ARB1_DeleteShader;
ctx->profileDeleteProgram = impl_ARB1_DeleteProgram;
May 28, 2008
May 28, 2008
532
533
534
535
536
537
538
ctx->profileGetUniformLocation = impl_ARB1_GetUniformLocation;
ctx->profileLinkProgram = impl_ARB1_LinkProgram;
ctx->profileUseProgramObject = impl_ARB1_UseProgramObject;
ctx->profileUniform4fv = impl_ARB1_Uniform4fv;
ctx->profileUniform4iv = impl_ARB1_Uniform4iv;
ctx->profileUniform1i = impl_ARB1_Uniform1i;
ctx->profileSetSampler = impl_ARB1_SetSampler;
May 25, 2008
May 25, 2008
539
540
541
542
543
544
545
} // if
#endif
assert(ctx->profileMaxUniforms != NULL);
assert(ctx->profileCompileShader != NULL);
assert(ctx->profileDeleteShader != NULL);
assert(ctx->profileDeleteProgram != NULL);
May 28, 2008
May 28, 2008
546
547
548
549
550
551
552
553
554
555
556
assert(ctx->profileMaxUniforms != NULL);
assert(ctx->profileCompileShader != NULL);
assert(ctx->profileDeleteShader != NULL);
assert(ctx->profileDeleteProgram != NULL);
assert(ctx->profileGetUniformLocation != NULL);
assert(ctx->profileLinkProgram != NULL);
assert(ctx->profileUseProgramObject != NULL);
assert(ctx->profileUniform4fv != NULL);
assert(ctx->profileUniform4iv != NULL);
assert(ctx->profileUniform1i != NULL);
assert(ctx->profileSetSampler != NULL);
May 25, 2008
May 25, 2008
557
Apr 29, 2008
Apr 29, 2008
558
retval = ctx;
Apr 28, 2008
Apr 28, 2008
559
560
ctx = current_ctx;
return retval;
Apr 28, 2008
Apr 28, 2008
561
562
init_fail:
Apr 28, 2008
Apr 28, 2008
563
564
565
566
if (ctx != NULL)
f(ctx, d);
ctx = current_ctx;
return NULL;
Apr 28, 2008
Apr 28, 2008
567
} // MOJOSHADER_glCreateContext
Apr 26, 2008
Apr 26, 2008
568
569
Apr 28, 2008
Apr 28, 2008
570
571
572
573
574
575
void MOJOSHADER_glMakeContextCurrent(MOJOSHADER_glContext *_ctx)
{
ctx = _ctx;
} // MOJOSHADER_glMakeContextCurrent
May 25, 2008
May 25, 2008
576
static int impl_GLSL_MaxUniforms(MOJOSHADER_shaderType shader_type)
May 3, 2008
May 3, 2008
577
578
579
580
581
582
583
584
585
586
587
588
{
GLenum pname = GL_NONE;
GLint val = 0;
if (shader_type == MOJOSHADER_TYPE_VERTEX)
pname = GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB;
else if (shader_type == MOJOSHADER_TYPE_PIXEL)
pname = GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB;
else
return -1;
ctx->glGetIntegerv(pname, &val);
return (int) val;
May 25, 2008
May 25, 2008
589
590
591
} // impl_GLSL_MaxUniforms
May 28, 2008
May 28, 2008
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
static int impl_ARB1_MaxUniforms(MOJOSHADER_shaderType shader_type)
{
GLint retval = 0;
GLenum program_type = GL_NONE;
if (shader_type == MOJOSHADER_TYPE_VERTEX)
program_type = GL_VERTEX_PROGRAM_ARB;
else if (shader_type == MOJOSHADER_TYPE_PIXEL)
program_type = GL_FRAGMENT_PROGRAM_ARB;
else
return -1;
ctx->glGetProgramivARB(program_type, GL_MAX_PROGRAM_PARAMETERS_ARB, &retval);
return (int) retval;
} // impl_ARB1_MaxUniforms
May 25, 2008
May 25, 2008
608
609
610
int MOJOSHADER_glMaxUniforms(MOJOSHADER_shaderType shader_type)
{
return ctx->profileMaxUniforms(shader_type);
May 3, 2008
May 3, 2008
611
612
613
} // MOJOSHADER_glMaxUniforms
May 25, 2008
May 25, 2008
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
static int impl_GLSL_CompileShader(const MOJOSHADER_parseData *pd, GLuint *s)
{
GLint ok = 0;
GLint shaderlen = (GLint) pd->output_len;
const GLenum shader_type = (pd->shader_type == MOJOSHADER_TYPE_PIXEL) ? GL_FRAGMENT_SHADER : GL_VERTEX_SHADER;
GLuint shader = ctx->glCreateShaderObject(shader_type);
ctx->glShaderSource(shader, 1, (const GLchar **) &pd->output, &shaderlen);
ctx->glCompileShader(shader);
ctx->glGetObjectParameteriv(shader, GL_OBJECT_COMPILE_STATUS_ARB, &ok);
if (!ok)
{
GLsizei len = 0;
ctx->glGetInfoLog(shader, sizeof (error_buffer), &len,
(GLchar *) error_buffer);
*s = 0;
return 0;
} // if
*s = shader;
return 1;
} // impl_GLSL_CompileShader
May 28, 2008
May 28, 2008
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
static int impl_ARB1_CompileShader(const MOJOSHADER_parseData *pd, GLuint *s)
{
GLint shaderlen = (GLint) pd->output_len;
const GLenum shader_type = (pd->shader_type == MOJOSHADER_TYPE_PIXEL) ? GL_FRAGMENT_PROGRAM_ARB : GL_VERTEX_PROGRAM_ARB;
GLuint shader = 0;
ctx->glGenProgramsARB(1, &shader);
ctx->glGetError(); // flush any existing error state.
ctx->glBindProgramARB(shader_type, shader);
ctx->glProgramStringARB(shader_type, GL_PROGRAM_FORMAT_ASCII_ARB,
shaderlen, pd->output);
if (ctx->glGetError() == GL_INVALID_OPERATION)
{
GLint pos = 0;
ctx->glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &pos);
const GLubyte *errstr = ctx->glGetString(GL_PROGRAM_ERROR_STRING_ARB);
snprintf(error_buffer, sizeof (error_buffer),
"ARB1 compile error at position %d: %s",
(int) pos, (const char *) errstr);
ctx->glBindProgramARB(shader_type, 0);
ctx->glDeleteProgramsARB(1, &shader);
*s = 0;
return 0;
} // if
*s = shader;
return 1;
} // impl_ARB1_CompileShader
May 25, 2008
May 25, 2008
670
671
672
673
674
675
static void impl_GLSL_DeleteShader(const GLuint shader)
{
ctx->glDeleteObject(shader);
} // impl_GLSL_DeleteShader
May 28, 2008
May 28, 2008
676
677
678
679
680
681
682
static void impl_ARB1_DeleteShader(const GLuint _shader)
{
GLuint shader = _shader; // const removal.
ctx->glDeleteProgramsARB(1, &shader);
} // impl_ARB1_DeleteShader
May 25, 2008
May 25, 2008
683
684
685
686
687
688
static void impl_GLSL_DeleteProgram(const GLuint program)
{
ctx->glDeleteObject(program);
} // impl_GLSL_DeleteProgram
May 28, 2008
May 28, 2008
689
690
691
692
693
694
static void impl_ARB1_DeleteProgram(const GLuint program)
{
// no-op. ARB1 doesn't have real linked programs.
} // impl_GLSL_DeleteProgram
Apr 26, 2008
Apr 26, 2008
695
696
697
698
MOJOSHADER_glShader *MOJOSHADER_glCompileShader(const unsigned char *tokenbuf,
const unsigned int bufsize)
{
MOJOSHADER_glShader *retval = NULL;
May 25, 2008
May 25, 2008
699
GLuint shader = 0;
Apr 28, 2008
Apr 28, 2008
700
701
702
703
const MOJOSHADER_parseData *pd = MOJOSHADER_parse(ctx->profile, tokenbuf,
bufsize, ctx->malloc_fn,
ctx->free_fn,
ctx->malloc_data);
Apr 26, 2008
Apr 26, 2008
704
if (pd->error != NULL)
Apr 27, 2008
Apr 27, 2008
705
706
{
set_error(pd->error);
Apr 27, 2008
Apr 27, 2008
707
goto compile_shader_fail;
Apr 27, 2008
Apr 27, 2008
708
} // if
Apr 26, 2008
Apr 26, 2008
709
710
711
retval = (MOJOSHADER_glShader *) Malloc(sizeof (MOJOSHADER_glShader));
if (retval == NULL)
Apr 27, 2008
Apr 27, 2008
712
713
goto compile_shader_fail;
May 25, 2008
May 25, 2008
714
if (!ctx->profileCompileShader(pd, &shader))
Apr 27, 2008
Apr 27, 2008
715
goto compile_shader_fail;
Apr 26, 2008
Apr 26, 2008
716
717
718
719
720
retval->parseData = pd;
retval->handle = shader;
retval->refcount = 1;
return retval;
Apr 27, 2008
Apr 27, 2008
721
722
723
724
725
compile_shader_fail:
MOJOSHADER_freeParseData(pd);
Free(retval);
if (shader != 0)
May 25, 2008
May 25, 2008
726
ctx->profileDeleteShader(shader);
Apr 27, 2008
Apr 27, 2008
727
return NULL;
Apr 26, 2008
Apr 26, 2008
728
729
730
} // MOJOSHADER_glCompileShader
Apr 29, 2008
Apr 29, 2008
731
732
733
734
735
736
737
const MOJOSHADER_parseData *MOJOSHADER_glGetShaderParseData(
MOJOSHADER_glShader *shader)
{
return (shader != NULL) ? shader->parseData : NULL;
} // MOJOSHADER_glGetShaderParseData
Apr 26, 2008
Apr 26, 2008
738
739
740
741
static void shader_unref(MOJOSHADER_glShader *shader)
{
if (shader != NULL)
{
Apr 27, 2008
Apr 27, 2008
742
const uint32 refcount = shader->refcount;
Apr 26, 2008
Apr 26, 2008
743
if (refcount > 1)
Apr 27, 2008
Apr 27, 2008
744
shader->refcount--;
Apr 26, 2008
Apr 26, 2008
745
746
else
{
May 25, 2008
May 25, 2008
747
ctx->profileDeleteShader(shader->handle);
Apr 26, 2008
Apr 26, 2008
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
MOJOSHADER_freeParseData(shader->parseData);
Free(shader);
} // else
} // if
} // shader_unref
static void program_unref(MOJOSHADER_glProgram *program)
{
if (program != NULL)
{
const uint32 refcount = program->refcount;
if (refcount > 1)
program->refcount--;
else
{
May 25, 2008
May 25, 2008
764
ctx->profileDeleteProgram(program->handle);
Apr 26, 2008
Apr 26, 2008
765
766
shader_unref(program->vertex);
shader_unref(program->fragment);
May 6, 2008
May 6, 2008
767
Free(program->constants);
May 6, 2008
May 6, 2008
768
769
770
Free(program->samplers);
Free(program->uniforms);
Free(program->attributes);
Apr 26, 2008
Apr 26, 2008
771
772
773
774
775
776
Free(program);
} // else
} // if
} // program_unref
May 28, 2008
May 28, 2008
777
778
779
780
781
782
783
784
785
786
787
788
789
790
static GLint impl_GLSL_GetUniformLocation(GLuint handle,
const MOJOSHADER_parseData *pd, int idx)
{
return ctx->glGetUniformLocation(handle, pd->uniforms[idx].name);
} // impl_GLSL_GetUniformLocation
static GLint impl_ARB1_GetUniformLocation(GLuint handle,
const MOJOSHADER_parseData *pd, int idx)
{
// !!! FIXME: this only works if you have no bool or int uniforms.
return idx;
} // impl_ARB1_GetUniformLocation
Apr 27, 2008
Apr 27, 2008
791
792
793
794
static void lookup_uniforms(MOJOSHADER_glProgram *program,
MOJOSHADER_glShader *shader)
{
const MOJOSHADER_parseData *pd = shader->parseData;
Apr 27, 2008
Apr 27, 2008
795
const MOJOSHADER_uniform *u = pd->uniforms;
Apr 27, 2008
Apr 27, 2008
796
const MOJOSHADER_shaderType shader_type = pd->shader_type;
May 28, 2008
May 28, 2008
797
798
const GLuint handle = program->handle;
int i;
Apr 27, 2008
Apr 27, 2008
799
800
801
for (i = 0; i < pd->uniform_count; i++)
{
May 28, 2008
May 28, 2008
802
const GLint loc = ctx->profileGetUniformLocation(handle, pd, i);
Apr 27, 2008
Apr 27, 2008
803
804
805
if (loc != -1) // maybe the Uniform was optimized out?
{
UniformMap *map = &program->uniforms[program->uniform_count];
Apr 27, 2008
Apr 27, 2008
806
map->shader_type = shader_type;
Apr 27, 2008
Apr 27, 2008
807
map->uniform = &u[i];
Apr 27, 2008
Apr 27, 2008
808
map->location = (GLuint) loc;
Apr 27, 2008
Apr 27, 2008
809
810
811
812
813
814
program->uniform_count++;
} // if
} // for
} // lookup_uniforms
May 6, 2008
May 6, 2008
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
static void lookup_samplers(MOJOSHADER_glProgram *program,
MOJOSHADER_glShader *shader)
{
int i;
const MOJOSHADER_parseData *pd = shader->parseData;
const MOJOSHADER_sampler *s = pd->samplers;
const MOJOSHADER_shaderType shader_type = pd->shader_type;
for (i = 0; i < pd->sampler_count; i++)
{
const GLint loc = ctx->glGetUniformLocation(program->handle, s[i].name);
if (loc != -1) // maybe the Sampler was optimized out?
{
SamplerMap *map = &program->samplers[program->sampler_count];
map->shader_type = shader_type;
map->sampler = &s[i];
map->location = (GLuint) loc;
program->sampler_count++;
} // if
} // for
} // lookup_samplers
Apr 27, 2008
Apr 27, 2008
838
839
840
841
static void lookup_attributes(MOJOSHADER_glProgram *program)
{
int i;
const MOJOSHADER_parseData *pd = program->vertex->parseData;
Apr 27, 2008
Apr 27, 2008
842
const MOJOSHADER_attribute *a = pd->attributes;
Apr 27, 2008
Apr 27, 2008
843
844
845
for (i = 0; i < pd->attribute_count; i++)
{
May 13, 2008
May 13, 2008
846
const GLint loc = ctx->glGetAttribLocation(program->handle, a[i].name);
Apr 27, 2008
Apr 27, 2008
847
848
849
850
if (loc != -1) // maybe the Attribute was optimized out?
{
AttributeMap *map = &program->attributes[program->attribute_count];
map->attribute = &a[i];
Apr 27, 2008
Apr 27, 2008
851
map->location = (GLuint) loc;
Apr 27, 2008
Apr 27, 2008
852
853
854
855
856
857
program->attribute_count++;
} // if
} // for
} // lookup_attributes
May 28, 2008
May 28, 2008
858
859
static GLuint impl_GLSL_LinkProgram(MOJOSHADER_glShader *vshader,
MOJOSHADER_glShader *pshader)
Apr 26, 2008
Apr 26, 2008
860
{
May 25, 2008
May 25, 2008
861
const GLuint program = ctx->glCreateProgramObject();
Apr 26, 2008
Apr 26, 2008
862
Apr 28, 2008
Apr 28, 2008
863
864
if (vshader != NULL) ctx->glAttachObject(program, vshader->handle);
if (pshader != NULL) ctx->glAttachObject(program, pshader->handle);
Apr 27, 2008
Apr 27, 2008
865
Apr 28, 2008
Apr 28, 2008
866
ctx->glLinkProgram(program);
Apr 27, 2008
Apr 27, 2008
867
868
GLint ok = 0;
Apr 28, 2008
Apr 28, 2008
869
ctx->glGetObjectParameteriv(program, GL_OBJECT_LINK_STATUS_ARB, &ok);
Apr 27, 2008
Apr 27, 2008
870
871
872
if (!ok)
{
GLsizei len = 0;
Apr 28, 2008
Apr 28, 2008
873
ctx->glGetInfoLog(program, sizeof (error_buffer), &len, (GLchar *) error_buffer);
May 28, 2008
May 28, 2008
874
875
ctx->glDeleteObject(program);
return 0;
Apr 27, 2008
Apr 27, 2008
876
} // if
Apr 26, 2008
Apr 26, 2008
877
May 28, 2008
May 28, 2008
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
return program;
} // impl_GLSL_LinkProgram
static GLuint impl_ARB1_LinkProgram(MOJOSHADER_glShader *vshader,
MOJOSHADER_glShader *pshader)
{
// there is no formal linking in ARB1...just return a unique value.
static GLuint retval = 1;
return retval++;
} // impl_ARB1_LinkProgram
MOJOSHADER_glProgram *MOJOSHADER_glLinkProgram(MOJOSHADER_glShader *vshader,
MOJOSHADER_glShader *pshader)
{
if ((vshader == NULL) && (pshader == NULL))
return NULL;
int numregs = 0;
int consts = 0;
MOJOSHADER_glProgram *retval = NULL;
const GLuint program = ctx->profileLinkProgram(vshader, pshader);
if (program == 0)
goto link_program_fail;
Apr 27, 2008
Apr 27, 2008
904
905
retval = (MOJOSHADER_glProgram *) Malloc(sizeof (MOJOSHADER_glProgram));
if (retval == NULL)
Apr 27, 2008
Apr 27, 2008
906
907
goto link_program_fail;
memset(retval, '\0', sizeof (MOJOSHADER_glProgram));
Apr 27, 2008
Apr 27, 2008
908
May 6, 2008
May 6, 2008
909
numregs = 0;
Apr 27, 2008
Apr 27, 2008
910
911
if (vshader != NULL) numregs += vshader->parseData->uniform_count;
if (pshader != NULL) numregs += pshader->parseData->uniform_count;
Apr 27, 2008
Apr 27, 2008
912
913
914
retval->uniforms = (UniformMap *) Malloc(sizeof (UniformMap) * numregs);
if (retval->uniforms == NULL)
goto link_program_fail;
Apr 27, 2008
Apr 27, 2008
915
memset(retval->uniforms, '\0', sizeof (UniformMap) * numregs);
Apr 27, 2008
Apr 27, 2008
916
May 6, 2008
May 6, 2008
917
918
919
920
921
922
923
924
numregs = 0;
if (vshader != NULL) numregs += vshader->parseData->sampler_count;
if (pshader != NULL) numregs += pshader->parseData->sampler_count;
retval->samplers = (SamplerMap *) Malloc(sizeof (SamplerMap) * numregs);
if (retval->samplers == NULL)
goto link_program_fail;
memset(retval->samplers, '\0', sizeof (SamplerMap) * numregs);
Apr 27, 2008
Apr 27, 2008
925
926
927
928
retval->handle = program;
retval->vertex = vshader;
retval->fragment = pshader;
retval->refcount = 1;
Apr 26, 2008
Apr 26, 2008
929
930
if (vshader != NULL)
Apr 27, 2008
Apr 27, 2008
931
{
May 11, 2008
May 11, 2008
932
933
if (consts < vshader->parseData->constant_count)
consts = vshader->parseData->constant_count;
Apr 27, 2008
Apr 27, 2008
934
935
936
937
938
939
retval->attributes = (AttributeMap *) Malloc(sizeof (AttributeMap) *
vshader->parseData->attribute_count);
if (retval->attributes == NULL)
goto link_program_fail;
lookup_attributes(retval);
Apr 27, 2008
Apr 27, 2008
940
lookup_uniforms(retval, vshader);
May 6, 2008
May 6, 2008
941
lookup_samplers(retval, vshader);
Apr 26, 2008
Apr 26, 2008
942
vshader->refcount++;
Apr 27, 2008
Apr 27, 2008
943
944
} // if
Apr 26, 2008
Apr 26, 2008
945
if (pshader != NULL)
Apr 27, 2008
Apr 27, 2008
946
{
May 11, 2008
May 11, 2008
947
948
if (consts < pshader->parseData->constant_count)
consts = pshader->parseData->constant_count;
May 6, 2008
May 6, 2008
949
Apr 27, 2008
Apr 27, 2008
950
lookup_uniforms(retval, pshader);
May 6, 2008
May 6, 2008
951
lookup_samplers(retval, vshader);
Apr 26, 2008
Apr 26, 2008
952
pshader->refcount++;
Apr 27, 2008
Apr 27, 2008
953
} // if
Apr 27, 2008
Apr 27, 2008
954
May 11, 2008
May 11, 2008
955
if (consts > 0)
May 6, 2008
May 6, 2008
956
{
May 11, 2008
May 11, 2008
957
retval->constants = (GLfloat *) Malloc(sizeof (GLfloat) * consts * 4);
May 6, 2008
May 6, 2008
958
959
if (retval->constants == NULL)
goto link_program_fail;
May 11, 2008
May 11, 2008
960
retval->constant_count = (uint32) consts;
May 6, 2008
May 6, 2008
961
962
} // if
Apr 27, 2008
Apr 27, 2008
963
return retval;
Apr 27, 2008
Apr 27, 2008
964
965
966
967
link_program_fail:
if (retval != NULL)
{
May 6, 2008
May 6, 2008
968
969
Free(retval->constants);
Free(retval->samplers);
Apr 27, 2008
Apr 27, 2008
970
971
Free(retval->uniforms);
Free(retval->attributes);
Apr 27, 2008
Apr 27, 2008
972
973
974
Free(retval);
} // if
May 28, 2008
May 28, 2008
975
976
977
if (program != 0)
ctx->profileDeleteProgram(program);
Apr 27, 2008
Apr 27, 2008
978
return NULL;
Apr 26, 2008
Apr 26, 2008
979
980
981
} // MOJOSHADER_glLinkProgram
May 28, 2008
May 28, 2008
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
static void impl_GLSL_UseProgramObject(MOJOSHADER_glProgram *program)
{
ctx->glUseProgramObject((program != NULL) ? program->handle : 0);
} // impl_GLSL_UseProgramObject
static void impl_ARB1_UseProgramObject(MOJOSHADER_glProgram *program)
{
GLuint vhandle = 0;
GLuint phandle = 0;
if (program != NULL)
{
if (program->vertex != NULL)
vhandle = program->vertex->handle;
if (program->fragment != NULL)
phandle = program->fragment->handle;
} // if
ctx->glBindProgramARB(GL_VERTEX_PROGRAM_ARB, vhandle);