Skip to content

Latest commit

 

History

History
900 lines (736 loc) · 27.2 KB

mojoshader_opengl.c

File metadata and controls

900 lines (736 loc) · 27.2 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
35
36
#ifdef _MSC_VER
#define snprintf _snprintf
typedef unsigned __int8 uint8;
typedef unsigned __int32 uint32;
typedef unsigned __int32 int32;
#else
#include <stdint.h>
Apr 26, 2008
Apr 26, 2008
37
38
39
typedef uint8_t uint8;
typedef uint32_t uint32;
typedef int32_t int32;
Apr 30, 2008
Apr 30, 2008
40
41
42
#endif
#define STATICARRAYLEN(x) ( (sizeof ((x))) / (sizeof ((x)[0])) )
Apr 26, 2008
Apr 26, 2008
43
Apr 30, 2008
Apr 30, 2008
44
45
46
47
#ifndef SUPPORT_PROFILE_GLSL
#define SUPPORT_PROFILE_GLSL 1
#endif
Apr 26, 2008
Apr 26, 2008
48
49
50
struct MOJOSHADER_glShader
{
const MOJOSHADER_parseData *parseData;
Apr 27, 2008
Apr 27, 2008
51
GLhandleARB handle;
Apr 26, 2008
Apr 26, 2008
52
53
54
uint32 refcount;
};
Apr 27, 2008
Apr 27, 2008
55
56
typedef struct
{
Apr 27, 2008
Apr 27, 2008
57
MOJOSHADER_shaderType shader_type;
Apr 27, 2008
Apr 27, 2008
58
const MOJOSHADER_uniform *uniform;
Apr 27, 2008
Apr 27, 2008
59
GLuint location;
Apr 27, 2008
Apr 27, 2008
60
61
} UniformMap;
Apr 27, 2008
Apr 27, 2008
62
63
typedef struct
{
Apr 27, 2008
Apr 27, 2008
64
const MOJOSHADER_attribute *attribute;
Apr 27, 2008
Apr 27, 2008
65
GLuint location;
Apr 27, 2008
Apr 27, 2008
66
67
} AttributeMap;
Apr 26, 2008
Apr 26, 2008
68
69
struct MOJOSHADER_glProgram
{
Apr 27, 2008
Apr 27, 2008
70
71
MOJOSHADER_glShader *vertex;
MOJOSHADER_glShader *fragment;
Apr 27, 2008
Apr 27, 2008
72
GLhandleARB handle;
Apr 27, 2008
Apr 27, 2008
73
uint32 uniform_count;
Apr 27, 2008
Apr 27, 2008
74
UniformMap *uniforms;
Apr 27, 2008
Apr 27, 2008
75
uint32 attribute_count;
Apr 27, 2008
Apr 27, 2008
76
AttributeMap *attributes;
Apr 26, 2008
Apr 26, 2008
77
78
79
uint32 refcount;
};
Apr 28, 2008
Apr 28, 2008
80
// Entry points in base OpenGL that lack function pointer prototypes...
May 3, 2008
May 3, 2008
81
82
typedef WINGDIAPI void (APIENTRYP PFNGLGETINTEGERVPROC) (GLenum pname, GLint *params);
typedef WINGDIAPI const GLubyte * (APIENTRYP PFNGLGETSTRINGPROC) (GLenum name);
Apr 28, 2008
Apr 28, 2008
83
Apr 28, 2008
Apr 28, 2008
84
85
86
87
88
89
90
91
92
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
93
94
95
96
97
98
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];
Apr 28, 2008
Apr 28, 2008
99
100
101
102
103
// GL stuff...
int opengl_major;
int opengl_minor;
MOJOSHADER_glProgram *bound_program;
Apr 30, 2008
Apr 30, 2008
104
char profile[16];
Apr 28, 2008
Apr 28, 2008
105
106
107
108
109
110
111
112
113
114
115
// Extensions...
int have_base_opengl;
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 3, 2008
May 3, 2008
116
PFNGLGETINTEGERVPROC glGetIntegerv;
Apr 28, 2008
Apr 28, 2008
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
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;
};
static MOJOSHADER_glContext *ctx = NULL;
Apr 28, 2008
Apr 28, 2008
138
Apr 26, 2008
Apr 26, 2008
139
Apr 27, 2008
Apr 27, 2008
140
141
142
143
144
145
146
147
// 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
148
149
150
151
152
153
154
155
156
157
158
159
160
// #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)
{
Apr 28, 2008
Apr 28, 2008
161
void *retval = ctx->malloc_fn(len, ctx->malloc_data);
Apr 27, 2008
Apr 27, 2008
162
163
164
if (retval == NULL)
set_error("out of memory");
return retval;
Apr 26, 2008
Apr 26, 2008
165
166
167
168
} // Malloc
static inline void Free(void *ptr)
{
Apr 27, 2008
Apr 27, 2008
169
if (ptr != NULL)
Apr 28, 2008
Apr 28, 2008
170
ctx->free_fn(ptr, ctx->malloc_data);
Apr 26, 2008
Apr 26, 2008
171
172
173
} // Free
Apr 27, 2008
Apr 27, 2008
174
175
176
177
178
179
const char *MOJOSHADER_glGetError(void)
{
return error_buffer;
} // MOJOSHADER_glGetError
Apr 28, 2008
Apr 28, 2008
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
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
202
#define DO_LOOKUP(ext, typ, fn) ctx->fn = (typ) loadsym(lookup, #fn, &ctx->have_##ext)
Apr 28, 2008
Apr 28, 2008
203
DO_LOOKUP(base_opengl, PFNGLGETSTRINGPROC, glGetString);
May 3, 2008
May 3, 2008
204
DO_LOOKUP(base_opengl, PFNGLGETINTEGERVPROC, glGetIntegerv);
Apr 28, 2008
Apr 28, 2008
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
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);
#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
233
234
235
else if (!ctx->have_base_opengl)
return 0; // don't bother checking, we're missing basic functionality.
Apr 28, 2008
Apr 28, 2008
236
// See if it's in the spec for this GL implementation's version.
Apr 28, 2008
Apr 28, 2008
237
238
if (major >= 0)
{
Apr 28, 2008
Apr 28, 2008
239
if ( ((ctx->opengl_major << 16) | (ctx->opengl_minor & 0xFFFF)) >=
Apr 28, 2008
Apr 28, 2008
240
241
242
((major << 16) | (minor & 0xFFFF)) )
return 1;
} // if
Apr 28, 2008
Apr 28, 2008
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
// 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
260
ctx->opengl_major = ctx->opengl_minor = 0;
Apr 28, 2008
Apr 28, 2008
261
else
Apr 28, 2008
Apr 28, 2008
262
sscanf(verstr, "%d.%d", &ctx->opengl_major, &ctx->opengl_minor);
Apr 28, 2008
Apr 28, 2008
263
264
265
} // parse_opengl_version
Apr 30, 2008
Apr 30, 2008
266
static void load_extensions(void *(*lookup)(const char *fnname))
Apr 28, 2008
Apr 28, 2008
267
{
Apr 30, 2008
Apr 30, 2008
268
269
const char *extlist = NULL;
Apr 28, 2008
Apr 28, 2008
270
271
272
273
274
275
ctx->have_base_opengl = 1;
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
276
277
278
lookup_entry_points(lookup);
Apr 30, 2008
Apr 30, 2008
279
if (!ctx->have_base_opengl)
Apr 28, 2008
Apr 28, 2008
280
set_error("missing basic OpenGL entry points");
Apr 30, 2008
Apr 30, 2008
281
282
283
284
285
else
{
parse_opengl_version((const char *) ctx->glGetString(GL_VERSION));
extlist = (const char *) ctx->glGetString(GL_EXTENSIONS);
} // else
Apr 28, 2008
Apr 28, 2008
286
287
288
289
290
if (extlist == NULL)
extlist = ""; // just in case.
#define VERIFY_EXT(ext, major, minor) \
Apr 28, 2008
Apr 28, 2008
291
ctx->have_##ext = verify_extension(#ext, ctx->have_##ext, extlist, major, minor)
Apr 28, 2008
Apr 28, 2008
292
293
294
295
296
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
297
VERIFY_EXT(GL_NV_half_float, -1, -1);
Apr 28, 2008
Apr 28, 2008
298
299
#undef VERIFY_EXT
Apr 30, 2008
Apr 30, 2008
300
301
302
303
304
305
306
} // load_extensions
static int valid_profile(const char *profile)
{
if (!ctx->have_base_opengl)
return 0;
Apr 28, 2008
Apr 28, 2008
307
Apr 30, 2008
Apr 30, 2008
308
309
#define MUST_HAVE(p, x) \
if (!ctx->have_##x) { set_error(#p " profile needs " #x); return 0; }
Apr 28, 2008
Apr 28, 2008
310
Apr 30, 2008
Apr 30, 2008
311
312
313
314
if (0) {}
#if SUPPORT_PROFILE_GLSL
else if (strcmp(profile, MOJOSHADER_PROFILE_GLSL) == 0)
Apr 28, 2008
Apr 28, 2008
315
{
Apr 30, 2008
Apr 30, 2008
316
317
318
319
320
321
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
322
323
324
else
{
Apr 30, 2008
Apr 30, 2008
325
set_error("unknown or unsupported profile");
Apr 28, 2008
Apr 28, 2008
326
327
328
return 0;
} // else
Apr 30, 2008
Apr 30, 2008
329
#undef MUST_HAVE
Apr 28, 2008
Apr 28, 2008
330
331
return 1;
Apr 30, 2008
Apr 30, 2008
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
} // 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,
};
int i;
for (i = 0; i < STATICARRAYLEN(priority); i++)
{
if (valid_profile(priority[i]))
{
retval = priority[i];
break;
} // if
} // for
Apr 28, 2008
Apr 28, 2008
360
Apr 30, 2008
Apr 30, 2008
361
362
363
if (retval == NULL)
set_error("no profiles available");
} // if
Apr 28, 2008
Apr 28, 2008
364
Apr 30, 2008
Apr 30, 2008
365
366
367
368
369
370
ctx = current_ctx;
return retval;
} // MOJOSHADER_glBestProfile
MOJOSHADER_glContext *MOJOSHADER_glCreateContext(const char *profile,
Apr 28, 2008
Apr 28, 2008
371
372
373
void *(*lookup)(const char *fnname),
MOJOSHADER_malloc m, MOJOSHADER_free f,
void *d)
Apr 26, 2008
Apr 26, 2008
374
{
Apr 29, 2008
Apr 29, 2008
375
MOJOSHADER_glContext *retval = NULL;
Apr 28, 2008
Apr 28, 2008
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
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
393
snprintf(ctx->profile, sizeof (ctx->profile), "%s", profile);
Apr 27, 2008
Apr 27, 2008
394
Apr 30, 2008
Apr 30, 2008
395
396
load_extensions(lookup);
if (!valid_profile(profile))
Apr 28, 2008
Apr 28, 2008
397
goto init_fail;
Apr 26, 2008
Apr 26, 2008
398
399
400
MOJOSHADER_glBindProgram(NULL);
Apr 29, 2008
Apr 29, 2008
401
retval = ctx;
Apr 28, 2008
Apr 28, 2008
402
403
ctx = current_ctx;
return retval;
Apr 28, 2008
Apr 28, 2008
404
405
init_fail:
Apr 28, 2008
Apr 28, 2008
406
407
408
409
if (ctx != NULL)
f(ctx, d);
ctx = current_ctx;
return NULL;
Apr 28, 2008
Apr 28, 2008
410
} // MOJOSHADER_glCreateContext
Apr 26, 2008
Apr 26, 2008
411
412
Apr 28, 2008
Apr 28, 2008
413
414
415
416
417
418
void MOJOSHADER_glMakeContextCurrent(MOJOSHADER_glContext *_ctx)
{
ctx = _ctx;
} // MOJOSHADER_glMakeContextCurrent
May 3, 2008
May 3, 2008
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
int MOJOSHADER_glMaxUniforms(MOJOSHADER_shaderType shader_type)
{
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;
} // MOJOSHADER_glMaxUniforms
Apr 26, 2008
Apr 26, 2008
435
436
437
438
MOJOSHADER_glShader *MOJOSHADER_glCompileShader(const unsigned char *tokenbuf,
const unsigned int bufsize)
{
MOJOSHADER_glShader *retval = NULL;
Apr 27, 2008
Apr 27, 2008
439
GLhandleARB shader = 0;
Apr 28, 2008
Apr 28, 2008
440
441
442
443
const MOJOSHADER_parseData *pd = MOJOSHADER_parse(ctx->profile, tokenbuf,
bufsize, ctx->malloc_fn,
ctx->free_fn,
ctx->malloc_data);
Apr 29, 2008
Apr 29, 2008
444
445
446
447
GLint ok = 0;
const GLenum shader_type = (pd->shader_type == MOJOSHADER_TYPE_PIXEL) ? GL_FRAGMENT_SHADER : GL_VERTEX_SHADER;
GLint shaderlen = (GLint) pd->output_len;
Apr 26, 2008
Apr 26, 2008
448
if (pd->error != NULL)
Apr 27, 2008
Apr 27, 2008
449
450
{
set_error(pd->error);
Apr 27, 2008
Apr 27, 2008
451
goto compile_shader_fail;
Apr 27, 2008
Apr 27, 2008
452
} // if
Apr 26, 2008
Apr 26, 2008
453
454
455
retval = (MOJOSHADER_glShader *) Malloc(sizeof (MOJOSHADER_glShader));
if (retval == NULL)
Apr 27, 2008
Apr 27, 2008
456
457
goto compile_shader_fail;
Apr 28, 2008
Apr 28, 2008
458
shader = ctx->glCreateShaderObject(shader_type);
Apr 26, 2008
Apr 26, 2008
459
Apr 28, 2008
Apr 28, 2008
460
461
462
ctx->glShaderSource(shader, 1, (const GLchar **) &pd->output, &shaderlen);
ctx->glCompileShader(shader);
ctx->glGetObjectParameteriv(shader, GL_OBJECT_COMPILE_STATUS_ARB, &ok);
Apr 26, 2008
Apr 26, 2008
463
464
465
466
if (!ok)
{
GLsizei len = 0;
Apr 28, 2008
Apr 28, 2008
467
ctx->glGetInfoLog(shader, sizeof (error_buffer), &len, (GLchar *) error_buffer);
Apr 27, 2008
Apr 27, 2008
468
goto compile_shader_fail;
Apr 26, 2008
Apr 26, 2008
469
470
471
472
473
474
} // if
retval->parseData = pd;
retval->handle = shader;
retval->refcount = 1;
return retval;
Apr 27, 2008
Apr 27, 2008
475
476
477
478
479
compile_shader_fail:
MOJOSHADER_freeParseData(pd);
Free(retval);
if (shader != 0)
Apr 28, 2008
Apr 28, 2008
480
ctx->glDeleteObject(shader);
Apr 27, 2008
Apr 27, 2008
481
return NULL;
Apr 26, 2008
Apr 26, 2008
482
483
484
} // MOJOSHADER_glCompileShader
Apr 29, 2008
Apr 29, 2008
485
486
487
488
489
490
491
const MOJOSHADER_parseData *MOJOSHADER_glGetShaderParseData(
MOJOSHADER_glShader *shader)
{
return (shader != NULL) ? shader->parseData : NULL;
} // MOJOSHADER_glGetShaderParseData
Apr 26, 2008
Apr 26, 2008
492
493
494
495
static void shader_unref(MOJOSHADER_glShader *shader)
{
if (shader != NULL)
{
Apr 27, 2008
Apr 27, 2008
496
const uint32 refcount = shader->refcount;
Apr 26, 2008
Apr 26, 2008
497
if (refcount > 1)
Apr 27, 2008
Apr 27, 2008
498
shader->refcount--;
Apr 26, 2008
Apr 26, 2008
499
500
else
{
Apr 28, 2008
Apr 28, 2008
501
ctx->glDeleteObject(shader->handle);
Apr 26, 2008
Apr 26, 2008
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
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
{
Apr 28, 2008
Apr 28, 2008
518
ctx->glDeleteObject(program->handle);
Apr 26, 2008
Apr 26, 2008
519
520
shader_unref(program->vertex);
shader_unref(program->fragment);
Apr 27, 2008
Apr 27, 2008
521
Free(program->attributes);
Apr 27, 2008
Apr 27, 2008
522
Free(program->uniforms);
Apr 26, 2008
Apr 26, 2008
523
524
525
526
527
528
Free(program);
} // else
} // if
} // program_unref
Apr 27, 2008
Apr 27, 2008
529
530
531
532
533
static void lookup_uniforms(MOJOSHADER_glProgram *program,
MOJOSHADER_glShader *shader)
{
int i;
const MOJOSHADER_parseData *pd = shader->parseData;
Apr 27, 2008
Apr 27, 2008
534
const MOJOSHADER_uniform *u = pd->uniforms;
Apr 27, 2008
Apr 27, 2008
535
const MOJOSHADER_shaderType shader_type = pd->shader_type;
Apr 27, 2008
Apr 27, 2008
536
537
538
for (i = 0; i < pd->uniform_count; i++)
{
Apr 28, 2008
Apr 28, 2008
539
const GLint loc = ctx->glGetUniformLocation(program->handle, u[i].name);
Apr 27, 2008
Apr 27, 2008
540
541
542
if (loc != -1) // maybe the Uniform was optimized out?
{
UniformMap *map = &program->uniforms[program->uniform_count];
Apr 27, 2008
Apr 27, 2008
543
map->shader_type = shader_type;
Apr 27, 2008
Apr 27, 2008
544
map->uniform = &u[i];
Apr 27, 2008
Apr 27, 2008
545
map->location = (GLuint) loc;
Apr 27, 2008
Apr 27, 2008
546
547
548
549
550
551
program->uniform_count++;
} // if
} // for
} // lookup_uniforms
Apr 27, 2008
Apr 27, 2008
552
553
554
555
static void lookup_attributes(MOJOSHADER_glProgram *program)
{
int i;
const MOJOSHADER_parseData *pd = program->vertex->parseData;
Apr 27, 2008
Apr 27, 2008
556
const MOJOSHADER_attribute *a = pd->attributes;
Apr 27, 2008
Apr 27, 2008
557
558
559
for (i = 0; i < pd->attribute_count; i++)
{
Apr 28, 2008
Apr 28, 2008
560
const GLint loc = ctx->glGetAttribLocation(program->handle, a->name);
Apr 27, 2008
Apr 27, 2008
561
562
563
564
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
565
map->location = (GLuint) loc;
Apr 27, 2008
Apr 27, 2008
566
567
568
569
570
571
program->attribute_count++;
} // if
} // for
} // lookup_attributes
Apr 26, 2008
Apr 26, 2008
572
573
574
MOJOSHADER_glProgram *MOJOSHADER_glLinkProgram(MOJOSHADER_glShader *vshader,
MOJOSHADER_glShader *pshader)
{
Apr 27, 2008
Apr 27, 2008
575
576
577
if ((vshader == NULL) && (pshader == NULL))
return NULL;
Apr 27, 2008
Apr 27, 2008
578
MOJOSHADER_glProgram *retval = NULL;
Apr 28, 2008
Apr 28, 2008
579
const GLhandleARB program = ctx->glCreateProgramObject();
Apr 29, 2008
Apr 29, 2008
580
int numregs = 0;
Apr 26, 2008
Apr 26, 2008
581
Apr 28, 2008
Apr 28, 2008
582
583
if (vshader != NULL) ctx->glAttachObject(program, vshader->handle);
if (pshader != NULL) ctx->glAttachObject(program, pshader->handle);
Apr 27, 2008
Apr 27, 2008
584
Apr 28, 2008
Apr 28, 2008
585
ctx->glLinkProgram(program);
Apr 27, 2008
Apr 27, 2008
586
587
GLint ok = 0;
Apr 28, 2008
Apr 28, 2008
588
ctx->glGetObjectParameteriv(program, GL_OBJECT_LINK_STATUS_ARB, &ok);
Apr 27, 2008
Apr 27, 2008
589
590
591
if (!ok)
{
GLsizei len = 0;
Apr 28, 2008
Apr 28, 2008
592
ctx->glGetInfoLog(program, sizeof (error_buffer), &len, (GLchar *) error_buffer);
Apr 27, 2008
Apr 27, 2008
593
594
goto link_program_fail;
} // if
Apr 26, 2008
Apr 26, 2008
595
Apr 27, 2008
Apr 27, 2008
596
597
retval = (MOJOSHADER_glProgram *) Malloc(sizeof (MOJOSHADER_glProgram));
if (retval == NULL)
Apr 27, 2008
Apr 27, 2008
598
599
goto link_program_fail;
memset(retval, '\0', sizeof (MOJOSHADER_glProgram));
Apr 27, 2008
Apr 27, 2008
600
601
602
if (vshader != NULL) numregs += vshader->parseData->uniform_count;
if (pshader != NULL) numregs += pshader->parseData->uniform_count;
Apr 27, 2008
Apr 27, 2008
603
604
605
retval->uniforms = (UniformMap *) Malloc(sizeof (UniformMap) * numregs);
if (retval->uniforms == NULL)
goto link_program_fail;
Apr 27, 2008
Apr 27, 2008
606
memset(retval->uniforms, '\0', sizeof (UniformMap) * numregs);
Apr 27, 2008
Apr 27, 2008
607
608
609
610
611
retval->handle = program;
retval->vertex = vshader;
retval->fragment = pshader;
retval->refcount = 1;
Apr 26, 2008
Apr 26, 2008
612
613
if (vshader != NULL)
Apr 27, 2008
Apr 27, 2008
614
{
Apr 27, 2008
Apr 27, 2008
615
616
617
618
619
620
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
621
lookup_uniforms(retval, vshader);
Apr 26, 2008
Apr 26, 2008
622
vshader->refcount++;
Apr 27, 2008
Apr 27, 2008
623
624
} // if
Apr 26, 2008
Apr 26, 2008
625
if (pshader != NULL)
Apr 27, 2008
Apr 27, 2008
626
627
{
lookup_uniforms(retval, pshader);
Apr 26, 2008
Apr 26, 2008
628
pshader->refcount++;
Apr 27, 2008
Apr 27, 2008
629
} // if
Apr 27, 2008
Apr 27, 2008
630
631
return retval;
Apr 27, 2008
Apr 27, 2008
632
633
634
635
link_program_fail:
if (retval != NULL)
{
Apr 27, 2008
Apr 27, 2008
636
637
Free(retval->uniforms);
Free(retval->attributes);
Apr 27, 2008
Apr 27, 2008
638
639
640
Free(retval);
} // if
Apr 28, 2008
Apr 28, 2008
641
ctx->glDeleteObject(program);
Apr 27, 2008
Apr 27, 2008
642
return NULL;
Apr 26, 2008
Apr 26, 2008
643
644
645
646
647
} // MOJOSHADER_glLinkProgram
void MOJOSHADER_glBindProgram(MOJOSHADER_glProgram *program)
{
Apr 27, 2008
Apr 27, 2008
648
GLhandleARB handle = 0;
Apr 27, 2008
Apr 27, 2008
649
int i;
Apr 27, 2008
Apr 27, 2008
650
Apr 28, 2008
Apr 28, 2008
651
if (program == ctx->bound_program)
Apr 27, 2008
Apr 27, 2008
652
653
654
return; // nothing to do.
// Disable any client-side arrays the current program could have used.
Apr 28, 2008
Apr 28, 2008
655
656
// !!! FIXME: don't disable yet...see which ones get reused, and disable
// !!! FIXME: only what we don't need in MOJOSHADER_glProgramReady().
Apr 28, 2008
Apr 28, 2008
657
if (ctx->bound_program != NULL)
Apr 27, 2008
Apr 27, 2008
658
{
Apr 28, 2008
Apr 28, 2008
659
660
const int count = ctx->bound_program->attribute_count;
for (i = 0; i < count; i++)
Apr 27, 2008
Apr 27, 2008
661
{
Apr 28, 2008
Apr 28, 2008
662
663
const AttributeMap *map = &ctx->bound_program->attributes[i];
ctx->glDisableVertexAttribArray(map->location);
Apr 27, 2008
Apr 27, 2008
664
665
666
} // if
} // for
Apr 26, 2008
Apr 26, 2008
667
668
669
670
671
672
if (program != NULL)
{
handle = program->handle;
program->refcount++;
} // if
Apr 28, 2008
Apr 28, 2008
673
674
675
ctx->glUseProgramObject(handle);
program_unref(ctx->bound_program);
ctx->bound_program = program;
Apr 26, 2008
Apr 26, 2008
676
677
678
} // MOJOSHADER_glBindProgram
Apr 30, 2008
Apr 30, 2008
679
static inline uint minuint(const uint a, const uint b)
Apr 27, 2008
Apr 27, 2008
680
{
Apr 30, 2008
Apr 30, 2008
681
682
return ((a < b) ? a : b);
} // minuint
Apr 27, 2008
Apr 27, 2008
683
684
Apr 26, 2008
Apr 26, 2008
685
void MOJOSHADER_glSetVertexShaderUniformF(unsigned int idx, const float *data,
Apr 27, 2008
Apr 27, 2008
686
unsigned int vec4n)
Apr 26, 2008
Apr 26, 2008
687
{
Apr 28, 2008
Apr 28, 2008
688
const uint maxregs = STATICARRAYLEN(ctx->vs_reg_file_f) / 4;
Apr 27, 2008
Apr 27, 2008
689
690
if (idx < maxregs)
{
Apr 29, 2008
Apr 29, 2008
691
assert(sizeof (GLfloat) == sizeof (float));
Apr 30, 2008
Apr 30, 2008
692
const uint cpy = (minuint(maxregs - idx, vec4n) * sizeof (*data)) * 4;
Apr 28, 2008
Apr 28, 2008
693
memcpy(ctx->vs_reg_file_f + (idx * 4), data, cpy);
Apr 27, 2008
Apr 27, 2008
694
} // if
Apr 26, 2008
Apr 26, 2008
695
696
697
698
} // MOJOSHADER_glSetVertexShaderUniformF
void MOJOSHADER_glSetVertexShaderUniformI(unsigned int idx, const int *data,
Apr 27, 2008
Apr 27, 2008
699
unsigned int ivec4n)
Apr 26, 2008
Apr 26, 2008
700
{
Apr 28, 2008
Apr 28, 2008
701
const uint maxregs = STATICARRAYLEN(ctx->vs_reg_file_i) / 4;
Apr 27, 2008
Apr 27, 2008
702
703
if (idx < maxregs)
{
Apr 29, 2008
Apr 29, 2008
704
assert(sizeof (GLint) == sizeof (int));
Apr 30, 2008
Apr 30, 2008
705
const uint cpy = (minuint(maxregs - idx, ivec4n) * sizeof (*data)) * 4;
Apr 28, 2008
Apr 28, 2008
706
memcpy(ctx->vs_reg_file_i + (idx * 4), data, cpy);
Apr 27, 2008
Apr 27, 2008
707
} // if
Apr 26, 2008
Apr 26, 2008
708
709
710
711
712
713
} // MOJOSHADER_glSetVertexShaderUniformI
void MOJOSHADER_glSetVertexShaderUniformB(unsigned int idx, const int *data,
unsigned int bcount)
{
Apr 28, 2008
Apr 28, 2008
714
const uint maxregs = STATICARRAYLEN(ctx->vs_reg_file_f) / 4;
Apr 27, 2008
Apr 27, 2008
715
716
if (idx < maxregs)
{
Apr 29, 2008
Apr 29, 2008
717
GLint *wptr = ctx->vs_reg_file_b + idx;
Apr 30, 2008
Apr 30, 2008
718
GLint *endptr = wptr + minuint(maxregs - idx, bcount);
Apr 27, 2008
Apr 27, 2008
719
720
721
while (wptr != endptr)
*(wptr++) = *(data++) ? 1 : 0;
} // if
Apr 26, 2008
Apr 26, 2008
722
723
724
725
} // MOJOSHADER_glSetVertexShaderUniformB
void MOJOSHADER_glSetPixelShaderUniformF(unsigned int idx, const float *data,
Apr 27, 2008
Apr 27, 2008
726
unsigned int vec4n)
Apr 26, 2008
Apr 26, 2008
727
{
Apr 28, 2008
Apr 28, 2008
728
const uint maxregs = STATICARRAYLEN(ctx->ps_reg_file_f) / 4;
Apr 27, 2008
Apr 27, 2008
729
730
if (idx < maxregs)
{
Apr 29, 2008
Apr 29, 2008
731
assert(sizeof (GLfloat) == sizeof (float));
Apr 30, 2008
Apr 30, 2008
732
const uint cpy = (minuint(maxregs - idx, vec4n) * sizeof (*data)) * 4;
Apr 28, 2008
Apr 28, 2008
733
memcpy(ctx->ps_reg_file_f + (idx * 4), data, cpy);
Apr 27, 2008
Apr 27, 2008
734
} // if
Apr 26, 2008
Apr 26, 2008
735
736
737
738
} // MOJOSHADER_glSetPixelShaderUniformF
void MOJOSHADER_glSetPixelShaderUniformI(unsigned int idx, const int *data,
Apr 27, 2008
Apr 27, 2008
739
unsigned int ivec4n)
Apr 26, 2008
Apr 26, 2008
740
{
Apr 28, 2008
Apr 28, 2008
741
const uint maxregs = STATICARRAYLEN(ctx->ps_reg_file_i) / 4;
Apr 27, 2008
Apr 27, 2008
742
743
if (idx < maxregs)
{
Apr 29, 2008
Apr 29, 2008
744
assert(sizeof (GLint) == sizeof (int));
Apr 30, 2008
Apr 30, 2008
745
const uint cpy = (minuint(maxregs - idx, ivec4n) * sizeof (*data)) * 4;
Apr 28, 2008
Apr 28, 2008
746
memcpy(ctx->ps_reg_file_i + (idx * 4), data, cpy);
Apr 27, 2008
Apr 27, 2008
747
} // if
Apr 26, 2008
Apr 26, 2008
748
749
750
751
} // MOJOSHADER_glSetPixelShaderUniformI
void MOJOSHADER_glSetPixelShaderUniformB(unsigned int idx, const int *data,
Apr 27, 2008
Apr 27, 2008
752
unsigned int bcount)
Apr 26, 2008
Apr 26, 2008
753
{
Apr 28, 2008
Apr 28, 2008
754
const uint maxregs = STATICARRAYLEN(ctx->ps_reg_file_f) / 4;
Apr 27, 2008
Apr 27, 2008
755
756
if (idx < maxregs)
{
Apr 29, 2008
Apr 29, 2008
757
GLint *wptr = ctx->ps_reg_file_b + idx;
Apr 30, 2008
Apr 30, 2008
758
GLint *endptr = wptr + minuint(maxregs - idx, bcount);
Apr 27, 2008
Apr 27, 2008
759
760
761
while (wptr != endptr)
*(wptr++) = *(data++) ? 1 : 0;
} // if
Apr 26, 2008
Apr 26, 2008
762
763
764
} // MOJOSHADER_glSetPixelShaderUniformB
Apr 27, 2008
Apr 27, 2008
765
766
767
768
static inline GLenum opengl_attr_type(const MOJOSHADER_attributeType type)
{
switch (type)
{
Apr 28, 2008
Apr 28, 2008
769
case MOJOSHADER_ATTRIBUTE_UNKNOWN: return GL_NONE; // oh well.
Apr 27, 2008
Apr 27, 2008
770
771
772
case MOJOSHADER_ATTRIBUTE_BYTE: return GL_BYTE;
case MOJOSHADER_ATTRIBUTE_UBYTE: return GL_UNSIGNED_BYTE;
case MOJOSHADER_ATTRIBUTE_SHORT: return GL_SHORT;
Apr 27, 2008
Apr 27, 2008
773
case MOJOSHADER_ATTRIBUTE_USHORT: return GL_UNSIGNED_SHORT;
Apr 27, 2008
Apr 27, 2008
774
775
776
777
case MOJOSHADER_ATTRIBUTE_INT: return GL_INT;
case MOJOSHADER_ATTRIBUTE_UINT: return GL_UNSIGNED_INT;
case MOJOSHADER_ATTRIBUTE_FLOAT: return GL_FLOAT;
case MOJOSHADER_ATTRIBUTE_DOUBLE: return GL_DOUBLE;
Apr 28, 2008
Apr 28, 2008
778
779
case MOJOSHADER_ATTRIBUTE_HALF_FLOAT:
Apr 28, 2008
Apr 28, 2008
780
if (ctx->have_GL_NV_half_float)
Apr 28, 2008
Apr 28, 2008
781
782
return GL_HALF_FLOAT_NV;
break;
Apr 27, 2008
Apr 27, 2008
783
784
785
786
787
788
} // switch
return GL_NONE; // oh well. Raises a GL error later.
} // opengl_attr_type
Apr 26, 2008
Apr 26, 2008
789
790
791
792
793
794
void MOJOSHADER_glSetVertexAttribute(MOJOSHADER_usage usage,
int index, unsigned int size,
MOJOSHADER_attributeType type,
int normalized, unsigned int stride,
const void *ptr)
{
Apr 28, 2008
Apr 28, 2008
795
if ((ctx->bound_program == NULL) || (ctx->bound_program->vertex == NULL))
Apr 27, 2008
Apr 27, 2008
796
797
return;
Apr 28, 2008
Apr 28, 2008
798
799
800
const GLenum gl_type = opengl_attr_type(type);
const GLboolean norm = (normalized) ? GL_TRUE : GL_FALSE;
GLuint gl_index = 0;
Apr 27, 2008
Apr 27, 2008
801
Apr 28, 2008
Apr 28, 2008
802
803
804
// We have to map POSITION0 to generic vertex attribute 0; the
// GL_ARB_vertex_shader spec says this is equivalent to using
// glVertexPointer(), but without the limitations of that entry point.
Apr 27, 2008
Apr 27, 2008
805
Apr 28, 2008
Apr 28, 2008
806
if ((usage != MOJOSHADER_USAGE_POSITION) || (index != 0))
Apr 27, 2008
Apr 27, 2008
807
{
Apr 28, 2008
Apr 28, 2008
808
809
810
811
812
813
int i;
const int count = ctx->bound_program->attribute_count;
for (i = 0; i < count; i++)
{
const AttributeMap *map = &ctx->bound_program->attributes[i];
const MOJOSHADER_attribute *a = map->attribute;
Apr 27, 2008
Apr 27, 2008
814
Apr 28, 2008
Apr 28, 2008
815
816
// !!! FIXME: is this array guaranteed to be sorted by usage?
// !!! FIXME: if so, we can break if a->usage > usage.
Apr 27, 2008
Apr 27, 2008
817
Apr 28, 2008
Apr 28, 2008
818
819
820
821
822
823
if ((a->usage == usage) && (a->index == index))
{
gl_index = map->location;
break;
} // if
} // for
Apr 27, 2008
Apr 27, 2008
824
Apr 28, 2008
Apr 28, 2008
825
826
if (gl_index == 0)
return; // nothing to do, this shader doesn't use this stream.
Apr 27, 2008
Apr 27, 2008
827
} // if
Apr 28, 2008
Apr 28, 2008
828
829
830
ctx->glVertexAttribPointer(gl_index, size, gl_type, norm, stride, ptr);
ctx->glEnableVertexAttribArray(gl_index);
Apr 26, 2008
Apr 26, 2008
831
832
833
834
835
} // MOJOSHADER_glSetVertexAttribute
void MOJOSHADER_glProgramReady(void)
{
Apr 27, 2008
Apr 27, 2008
836
837
int i;
Apr 28, 2008
Apr 28, 2008
838
if (ctx->bound_program == NULL)
Apr 27, 2008
Apr 27, 2008
839
840
841
842
843
return; // nothing to do.
// !!! FIXME: don't push Uniforms if we know they haven't changed.
// push Uniforms to the program from our register files...
Apr 28, 2008
Apr 28, 2008
844
845
const int count = ctx->bound_program->uniform_count;
for (i = 0; i < count; i++)
Apr 27, 2008
Apr 27, 2008
846
{
Apr 28, 2008
Apr 28, 2008
847
const UniformMap *map = &ctx->bound_program->uniforms[i];
Apr 27, 2008
Apr 27, 2008
848
849
850
851
852
853
854
855
856
const MOJOSHADER_uniform *u = map->uniform;
const MOJOSHADER_uniformType type = u->type;
const MOJOSHADER_shaderType shader_type = map->shader_type;
const int index = u->index;
const GLint location = map->location;
if (shader_type == MOJOSHADER_TYPE_VERTEX)
{
if (type == MOJOSHADER_UNIFORM_FLOAT)
Apr 28, 2008
Apr 28, 2008
857
ctx->glUniform4fv(location, 1, &ctx->vs_reg_file_f[index * 4]);
Apr 27, 2008
Apr 27, 2008
858
else if (type == MOJOSHADER_UNIFORM_INT)
Apr 28, 2008
Apr 28, 2008
859
ctx->glUniform4iv(location, 1, &ctx->vs_reg_file_i[index * 4]);
Apr 27, 2008
Apr 27, 2008
860
else if (type == MOJOSHADER_UNIFORM_BOOL)
Apr 28, 2008
Apr 28, 2008
861
ctx->glUniform1i(location, ctx->vs_reg_file_b[index]);
Apr 27, 2008
Apr 27, 2008
862
863
864
865
866
} // if
else if (shader_type == MOJOSHADER_TYPE_PIXEL)
{
if (type == MOJOSHADER_UNIFORM_FLOAT)
Apr 28, 2008
Apr 28, 2008
867
ctx->glUniform4fv(location, 1, &ctx->ps_reg_file_f[index * 4]);
Apr 27, 2008
Apr 27, 2008
868
else if (type == MOJOSHADER_UNIFORM_INT)
Apr 28, 2008
Apr 28, 2008
869
ctx->glUniform4iv(location, 1, &ctx->ps_reg_file_i[index * 4]);
Apr 27, 2008
Apr 27, 2008
870
else if (type == MOJOSHADER_UNIFORM_BOOL)
Apr 28, 2008
Apr 28, 2008
871
ctx->glUniform1i(location, ctx->ps_reg_file_b[index]);
Apr 27, 2008
Apr 27, 2008
872
873
} // else if
} // for
Apr 26, 2008
Apr 26, 2008
874
875
876
} // MOJOSHADER_glProgramReady
Apr 27, 2008
Apr 27, 2008
877
void MOJOSHADER_glDeleteProgram(MOJOSHADER_glProgram *program)
Apr 26, 2008
Apr 26, 2008
878
{
Apr 27, 2008
Apr 27, 2008
879
program_unref(program);
Apr 26, 2008
Apr 26, 2008
880
881
882
} // MOJOSHADER_glDeleteProgram
Apr 27, 2008
Apr 27, 2008
883
void MOJOSHADER_glDeleteShader(MOJOSHADER_glShader *shader)
Apr 26, 2008
Apr 26, 2008
884
885
886
887
888
{
shader_unref(shader);
} // MOJOSHADER_glDeleteShader
Apr 28, 2008
Apr 28, 2008
889
void MOJOSHADER_glDestroyContext(MOJOSHADER_glContext *_ctx)
Apr 26, 2008
Apr 26, 2008
890
{
Apr 28, 2008
Apr 28, 2008
891
892
MOJOSHADER_glContext *current_ctx = ctx;
ctx = _ctx;
Apr 26, 2008
Apr 26, 2008
893
MOJOSHADER_glBindProgram(NULL);
Apr 28, 2008
Apr 28, 2008
894
lookup_entry_points(NULL);
Apr 28, 2008
Apr 28, 2008
895
896
Free(ctx);
ctx = ((current_ctx == _ctx) ? NULL : current_ctx);
Apr 28, 2008
Apr 28, 2008
897
} // MOJOSHADER_glDestroyContext
Apr 26, 2008
Apr 26, 2008
898
899
// end of mojoshader_opengl.c ...