Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
Initial add of mojoshader_opengl.c
Not nearly ready for primetime, just want to make sure I don't delete this again by accident. :) --HG-- branch : trunk
- Loading branch information
Showing
1 changed file
with
368 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,368 @@ | ||
|
||
/* !!! FIXME: merge this in? | ||
static GLenum opengl_attr_type(const MOJOSHADER_attributeType type) | ||
{ | ||
switch (type) | ||
{ | ||
case MOJOSHADER_ATTRIBUTE_BYTE: return GL_BYTE; | ||
case MOJOSHADER_ATTRIBUTE_UBYTE: return GL_UNSIGNED_BYTE; | ||
case MOJOSHADER_ATTRIBUTE_SHORT: return GL_SHORT; | ||
case MOJOSHADER_ATTRIBUTE_USHORT: return GL_USHORT; | ||
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; | ||
} // switch | ||
return GL_NONE; // oh well. Raises a GL error later. | ||
} // opengl_attr_type | ||
static GLenum opengl_attr_index(const MOJOSHADER_usage usage, const int index) | ||
{ | ||
switch (usage) | ||
{ | ||
case MOJOSHADER_USAGE_POSITION, | ||
case MOJOSHADER_USAGE_BLENDWEIGHT, | ||
case MOJOSHADER_USAGE_BLENDINDICES, | ||
case MOJOSHADER_USAGE_NORMAL, | ||
case MOJOSHADER_USAGE_POINTSIZE, | ||
case MOJOSHADER_USAGE_TEXCOORD, | ||
case MOJOSHADER_USAGE_TANGENT, | ||
case MOJOSHADER_USAGE_BINORMAL, | ||
case MOJOSHADER_USAGE_TESSFACTOR, | ||
case MOJOSHADER_USAGE_POSITIONT, | ||
case MOJOSHADER_USAGE_COLOR, | ||
case MOJOSHADER_USAGE_FOG, | ||
case MOJOSHADER_USAGE_DEPTH, | ||
case MOJOSHADER_USAGE_SAMPLE, | ||
case MOJOSHADER_USAGE_TOTAL: return GL_NONE; // stop compiler whining. | ||
} // switch | ||
return GL_NONE; // will fail later. | ||
} // opengl_attr_index | ||
void MOJOSHADER_glSetVertexDeclaration(MOJOSHADER_usage usage, int index, | ||
unsigned int size, | ||
MOJOSHADER_attributeType type, | ||
int normalized, unsigned int stride, | ||
const void *ptr) | ||
{ | ||
const GLuint gl_index = opengl_attr_index(usage, index); | ||
const GLenum gl_type = opengl_attr_type(type); | ||
const GLboolean gl_normalized = (normalized) ? GL_TRUE : GL_FALSE; | ||
pglVertexAttribPointer(gl_index, size, gl_type, gl_normalized, | ||
stride, ptr); | ||
} // MOJOSHADER_glSetVertexDeclaration | ||
*/ | ||
|
||
|
||
|
||
|
||
|
||
#include <stdio.h> | ||
#include <string.h> | ||
#include <stdlib.h> | ||
#include <stdint.h> | ||
#include <stdarg.h> | ||
#include <assert.h> | ||
|
||
#include "mojoshader.h" | ||
|
||
// Get basic wankery out of the way here... | ||
|
||
typedef unsigned int uint; // this is a printf() helper. don't use for code. | ||
typedef uint8_t uint8; | ||
typedef uint32_t uint32; | ||
typedef int32_t int32; | ||
|
||
struct MOJOSHADER_glShader | ||
{ | ||
const MOJOSHADER_parseData *parseData; | ||
GLuint handle; | ||
uint32 refcount; | ||
}; | ||
|
||
struct MOJOSHADER_glProgram | ||
{ | ||
const MOJOSHADER_glShader *vertex; | ||
const MOJOSHADER_glShader *fragment; | ||
GLuint handle; | ||
uint32 refcount; | ||
}; | ||
|
||
// Allocators... | ||
static MOJOSHADER_malloc malloc_fn = NULL; | ||
static MOJOSHADER_free free_fn = NULL; | ||
static void *malloc_data = NULL; | ||
|
||
// The constant register files... | ||
// Man, it kills me how much memory this takes... | ||
static float vs_register_file_f[8192 * 4]; | ||
static int vs_register_file_i[2047 * 4]; | ||
static uint8 vs_register_file_b[2047]; | ||
static float ps_register_file_f[8192 * 4]; | ||
static int ps_register_file_i[2047 * 4]; | ||
static uint8 ps_register_file_b[2047]; | ||
|
||
// GL stuff... | ||
static MOJOSHADER_glProgram *bound_program = NULL; | ||
|
||
|
||
// #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) | ||
{ | ||
return malloc_fn(len, malloc_data); | ||
} // Malloc | ||
|
||
static inline void Free(void *ptr) | ||
{ | ||
return free_fn(ptr, malloc_data); | ||
} // Free | ||
|
||
|
||
int MOJOSHADER_glInit(const char *_profile, | ||
void *(*lookup)(const char *fnname), | ||
MOJOSHADER_malloc m, MOJOSHADER_free f, void *d) | ||
{ | ||
if (strcmp(_profile, MOJOSHADER_PROFILE_GLSL) != 0) | ||
profile = MOJOSHADER_PROFILE_GLSL; | ||
else | ||
return 0; | ||
|
||
// !!! FIXME: lookup glGetString(), check extensions. | ||
|
||
malloc_fn = (m == NULL) ? internal_malloc : m; | ||
free_fn = (f == NULL) ? internal_free : f; | ||
malloc_data = d; | ||
|
||
// !!! FIXME: lookup other entry points. | ||
|
||
memset(vs_register_file_f, '\0', sizeof (vs_register_file_f)); | ||
memset(vs_register_file_i, '\0', sizeof (vs_register_file_i)); | ||
memset(vs_register_file_b, '\0', sizeof (vs_register_file_b)); | ||
memset(ps_register_file_f, '\0', sizeof (ps_register_file_f)); | ||
memset(ps_register_file_i, '\0', sizeof (ps_register_file_i)); | ||
memset(ps_register_file_b, '\0', sizeof (ps_register_file_b)); | ||
|
||
MOJOSHADER_glBindProgram(NULL); | ||
|
||
return 1; | ||
} // MOJOSHADER_glInit | ||
|
||
|
||
MOJOSHADER_glShader *MOJOSHADER_glCompileShader(const unsigned char *tokenbuf, | ||
const unsigned int bufsize) | ||
{ | ||
MOJOSHADER_glShader *retval = NULL; | ||
const MOJOSHADER_parseData *pd = MOJOSHADER_parse(profile, tokenbuf, | ||
bufsize, malloc_fn, | ||
free_fn, malloc_data); | ||
if (pd->error != NULL) | ||
{ | ||
MOJOSHADER_freeParseData(pd); | ||
return NULL; | ||
} // if | ||
|
||
retval = (MOJOSHADER_glShader *) Malloc(sizeof (MOJOSHADER_glShader)); | ||
if (retval == NULL) | ||
{ | ||
MOJOSHADER_freeParseData(pd); | ||
return NULL; | ||
} // if | ||
|
||
GLint ok = 0; | ||
const GLenum shader_type = (pd->shader_type == MOJOSHADER_TYPE_PIXEL) ? GL_FRAGMENT_SHADER_ARB : GL_VERTEX_SHADER_ARB; | ||
GLint shaderlen = (GLint) pd->output_len; | ||
const GLhandleARB shader = pglCreateShaderObjectARB(shader_type); | ||
|
||
pglShaderSourceARB(shader, 1, (const GLcharARB **) &pd->output, &shaderlen); | ||
pglCompileShaderARB(shader); | ||
pglGetObjectParameterivARB(shader, GL_OBJECT_COMPILE_STATUS_ARB, &ok); | ||
|
||
if (!ok) | ||
{ | ||
GLcharARB err[1024]; | ||
GLsizei len = 0; | ||
//glGetInfoLogARB(shader, sizeof (err), &len, err); | ||
//printf("FAIL: %s glsl compile: %s\n", fname, err); | ||
pglDeleteObjectARB(shader); | ||
MOJOSHADER_freeParseData(pd); | ||
Free(retval); | ||
return NULL; | ||
} // if | ||
|
||
retval->parseData = pd; | ||
retval->handle = shader; | ||
retval->refcount = 1; | ||
return retval; | ||
} // MOJOSHADER_glCompileShader | ||
|
||
|
||
static void shader_unref(MOJOSHADER_glShader *shader) | ||
{ | ||
if (shader != NULL) | ||
{ | ||
const uint32 refcount = program->refcount; | ||
if (refcount > 1) | ||
program->refcount--; | ||
else | ||
{ | ||
pglDeleteObjectARB(shader->handle); | ||
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 | ||
{ | ||
pglDeleteObjectARB(program->handle); | ||
shader_unref(program->vertex); | ||
shader_unref(program->fragment); | ||
Free(program); | ||
} // else | ||
} // if | ||
} // program_unref | ||
|
||
|
||
MOJOSHADER_glProgram *MOJOSHADER_glLinkProgram(MOJOSHADER_glShader *vshader, | ||
MOJOSHADER_glShader *pshader) | ||
{ | ||
// !!! FIXME: actually link. | ||
|
||
// !!! FIXME: alloc retval. | ||
|
||
retval->vertex = vshader; | ||
retval->fragment = pshader; | ||
retval->handle = program; | ||
retval->refcount = 1; | ||
|
||
if (vshader != NULL) | ||
vshader->refcount++; | ||
if (pshader != NULL) | ||
pshader->refcount++; | ||
} // MOJOSHADER_glLinkProgram | ||
|
||
|
||
void MOJOSHADER_glBindProgram(MOJOSHADER_glProgram *program) | ||
{ | ||
GLuint handle = 0; | ||
if (program != NULL) | ||
{ | ||
handle = program->handle; | ||
program->refcount++; | ||
} // if | ||
|
||
// !!! FIXME: unbind client-side arrays. | ||
|
||
pglUseProgramObjectARB(handle); | ||
program_unref(bound_program); | ||
bound_program = program; | ||
} // MOJOSHADER_glBindProgram | ||
|
||
|
||
void MOJOSHADER_glSetVertexShaderUniformF(unsigned int idx, const float *data, | ||
unsigned int vec4count) | ||
{ | ||
} // MOJOSHADER_glSetVertexShaderUniformF | ||
|
||
|
||
void MOJOSHADER_glSetVertexShaderUniformI(unsigned int idx, const int *data, | ||
unsigned int ivec4count) | ||
{ | ||
} // MOJOSHADER_glSetVertexShaderUniformI | ||
|
||
|
||
void MOJOSHADER_glSetVertexShaderUniformB(unsigned int idx, const int *data, | ||
unsigned int bcount) | ||
{ | ||
// !!! FIXME: check for overflow! | ||
uint8 *wptr = vs_register_file_b + idx; | ||
uint8 *endptr = wptr + bcount; | ||
while (wptr != endptr) | ||
*(wptr++) = *(data++) ? 1 : 0; | ||
} // MOJOSHADER_glSetVertexShaderUniformB | ||
|
||
|
||
void MOJOSHADER_glSetPixelShaderUniformF(unsigned int idx, const float *data, | ||
unsigned int vec4count) | ||
{ | ||
} // MOJOSHADER_glSetPixelShaderUniformF | ||
|
||
|
||
void MOJOSHADER_glSetPixelShaderUniformI(unsigned int idx, const int *data, | ||
unsigned int ivec4count) | ||
{ | ||
} // MOJOSHADER_glSetPixelShaderUniformI | ||
|
||
|
||
void MOJOSHADER_glSetPixelShaderUniformB(unsigned int idx, const int *data, | ||
unsigned int bcount) | ||
{ | ||
// !!! FIXME: check for overflow! | ||
uint8 *wptr = ps_register_file_b + idx; | ||
uint8 *endptr = wptr + bcount; | ||
while (wptr != endptr) | ||
*(wptr++) = *(data++) ? 1 : 0; | ||
} // MOJOSHADER_glSetPixelShaderUniformB | ||
|
||
|
||
void MOJOSHADER_glSetVertexAttribute(MOJOSHADER_usage usage, | ||
int index, unsigned int size, | ||
MOJOSHADER_attributeType type, | ||
int normalized, unsigned int stride, | ||
const void *ptr) | ||
{ | ||
} // MOJOSHADER_glSetVertexAttribute | ||
|
||
|
||
void MOJOSHADER_glProgramReady(void) | ||
{ | ||
} // MOJOSHADER_glProgramReady | ||
|
||
|
||
void MOJOSHADER_glDeleteProgram(const MOJOSHADER_glProgram *program) | ||
{ | ||
program_unref(shader); | ||
} // MOJOSHADER_glDeleteProgram | ||
|
||
|
||
void MOJOSHADER_glDeleteShader(const MOJOSHADER_glShader *shader) | ||
{ | ||
shader_unref(shader); | ||
} // MOJOSHADER_glDeleteShader | ||
|
||
|
||
void MOJOSHADER_glDeinit(void) | ||
{ | ||
MOJOSHADER_glBindProgram(NULL); | ||
|
||
profile = NULL; | ||
malloc_fn = NULL; | ||
free_fn = NULL; | ||
malloc_data = NULL; | ||
|
||
// !!! FIXME: NULL entry points. | ||
} // MOJOSHADER_glDeinit | ||
|
||
// end of mojoshader_opengl.c ... | ||
|