Skip to content

Commit

Permalink
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
icculus committed Apr 26, 2008
1 parent c880b58 commit 7ddbd36
Showing 1 changed file with 368 additions and 0 deletions.
368 changes: 368 additions & 0 deletions mojoshader_opengl.c
@@ -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 ...

0 comments on commit 7ddbd36

Please sign in to comment.