Skip to content

Commit

Permalink
Add direct resource access functions for buffers, shaders and textures
Browse files Browse the repository at this point in the history
  • Loading branch information
minexew committed Nov 29, 2014
1 parent 6afb53a commit e6f5313
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 29 deletions.
25 changes: 25 additions & 0 deletions libctrgl/include/gl.h
Expand Up @@ -33,6 +33,26 @@
* Special thanks to Smealum for blessing us with code exec in the first place.
*/

/*
* NOTE: Functions such as glInitBufferCTR and glShutdownBufferCTR (also called "direct resource access")
* can be used to avoid an additional memory allocation done by their glGen* and glCreate* equivalents.
* This makes code a tiny bit more efficient at the cost of diverging from OpenGL, which may or may not
* be an acceptable trade-off for your application.
* With the correct compiler and linker flags, the allocating variants of the functions, if not used by
* your program, will not be linked in at all, thereby slightly reducing code size.
*
* glInit*CTR takes a pointer to a user-allocated data structure and returns a value to be used
* with regular GL functions for that class of resource. This value is guaranteed to be the same
* as the provided pointer, cast to GLuint.
*
* Similarly, glShutdown*CTR releases all data allocated by the resource, but leaves the actual structure
* intact.
*
* If you decide to use these functions, you take on the responsibility to keep you code in sync,
* as a breakage may happen anytime. This especially applies to accessing the structure fields directly.
* Oh, and as always, no NULL checks are being done, in the ctrGL spirit of "crash early, crash often".
*/

#ifndef CTRGL_H
#define CTRGL_H

Expand Down Expand Up @@ -132,6 +152,8 @@ void glTexImage2D(GLenum target, /* must be GL_TEXTURE_2D */
GLenum type, /* must be GL_UNSIGNED_BYTE */
const GLvoid* data);

GLuint glInitTextureCTR(GLtextureCTR* tex);
void glShutdownTextureCTR(GLtextureCTR* tex);
void glNamedTexImage2DCTR(GLuint texture, GLint level, GLint internalFormat,
GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type,
const GLvoid* data); /* arguments: see glTexImage2D */
Expand Down Expand Up @@ -184,6 +206,9 @@ void* glMapNamedBufferRange(GLuint buffer,
GLboolean glUnmapBuffer(GLenum target);
GLboolean glUnmapNamedBuffer(GLuint buffer);

GLuint glInitBufferCTR(GLbufferCTR* buf);
void glShutdownBufferCTR(GLbufferCTR* buf);

/* **** VERTEX ARRAYS **** */
void glVertexFormatCTR(GLuint numAttribs, GLuint vertexSize);
void glVertexAttribCTR(GLuint index, GLint size, GLenum type);
Expand Down
15 changes: 8 additions & 7 deletions libctrgl/include/gl_ctr.h
Expand Up @@ -61,6 +61,14 @@ typedef struct
}
GLvertexAttribCTR;

/* **** VERTEX BUFFERS **** */
typedef struct
{
void* data;
size_t size;
}
GLbufferCTR;

/* **** STATE **** */

typedef struct
Expand All @@ -84,13 +92,6 @@ typedef struct
}
GLblendStateCTR;

typedef struct
{
void* data;
size_t size;
}
GLbufferCTR;

typedef struct
{
GLenum cullFace : 1;
Expand Down
100 changes: 78 additions & 22 deletions libctrgl/source/gl.c
Expand Up @@ -204,16 +204,38 @@ void glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum d
}

/* **** TEXTURES **** */
GLuint glInitTextureCTR(GLtextureCTR* tex)
{
tex->w = 0;
tex->h = 0;
tex->data = NULL;

return (GLuint) tex;
}

void glShutdownTextureCTR(GLtextureCTR* tex)
{
int i;

for (i = 0; i < NUM_TEXUNITS; i++)
if (tex == texturingState.texUnits[i].boundTexture)
{
texturingState.texUnits[i].boundTexture = NULL;
dirtyState |= GL_TEXTURING_CTR;
dirtyTexUnits |= (1 << i);
}

linearFree(tex->data);
}

void glGenTextures(GLsizei n, GLuint* textures)
{
GLtextureCTR* tex;

while (n-- > 0)
{
tex = (GLtextureCTR*) malloc(sizeof(GLtextureCTR));
tex->w = 0;
tex->h = 0;
tex->data = 0;
glInitTextureCTR(tex);

*textures = (GLuint) tex;
textures++;
Expand All @@ -223,7 +245,6 @@ void glGenTextures(GLsizei n, GLuint* textures)
void glDeleteTextures(GLsizei n, const GLuint* textures)
{
GLtextureCTR* tex;
int i;

for (; n > 0; n--, textures++)
{
Expand All @@ -232,15 +253,7 @@ void glDeleteTextures(GLsizei n, const GLuint* textures)
if (tex == NULL)
continue;

for (i = 0; i < NUM_TEXUNITS; i++)
if (tex == texturingState.texUnits[i].boundTexture)
{
texturingState.texUnits[i].boundTexture = NULL;
dirtyState |= GL_TEXTURING_CTR;
dirtyTexUnits |= (1 << i);
}

linearFree(tex->data);
glShutdownTextureCTR(tex);
free(tex);
}
}
Expand Down Expand Up @@ -310,18 +323,49 @@ void glTexEnvubvCTR(GLenum target, GLenum pname, const GLubyte* params)
}

/* **** SHADERS **** */
GLuint glInitProgramCTR(GLprogramCTR* prog)
{
prog->dvlb = NULL;
prog->projectionUniform = -1;
prog->modelviewUniform = -1;

return (GLuint) prog;
}

void glShutdownProgramCTR(GLprogramCTR* prog)
{
if (shaderState.program == prog)
{
shaderState.program = NULL;
dirtyState |= GL_SHADER_PROGRAM_CTR;
}

SHDR_FreeDVLB(prog->dvlb);
}

GLuint glCreateProgram(void)
{
GLprogramCTR* prog;

prog = (GLprogramCTR*) malloc(sizeof(GLprogramCTR));
prog->dvlb = NULL;
prog->projectionUniform = -1;
prog->modelviewUniform = -1;
glInitProgramCTR(prog);

return (GLuint) prog;
}

void glDeleteProgram(GLuint program)
{
GLprogramCTR* prog;

prog = (GLprogramCTR*) program;

if (prog == NULL)
return;

glShutdownProgramCTR(prog);
free(prog);
}

void glUseProgram(GLuint program)
{
GLprogramCTR* prog;
Expand Down Expand Up @@ -419,15 +463,30 @@ void glVertexAttribCTR(GLuint index, GLint size, GLenum type)
}

/* **** BUFFERS **** */
GLuint glInitBufferCTR(GLbufferCTR* buf)
{
buf->data = NULL;
buf->size = 0;

return (GLuint) buf;
}

void glShutdownBufferCTR(GLbufferCTR* buf)
{
if (buf == boundBuffer)
boundBuffer = NULL;

linearFree(buf->data);
}

void glGenBuffers(GLsizei n, GLuint* buffers)
{
GLbufferCTR* buf;

while (n-- > 0)
{
buf = (GLbufferCTR*) malloc(sizeof(GLbufferCTR));
buf->data = NULL;
buf->size = 0;
glInitBufferCTR(buf);

*buffers = (GLuint) buf;
buffers++;
Expand All @@ -445,10 +504,7 @@ void glDeleteBuffers(GLsizei n, const GLuint* buffers)
if (buf == NULL)
continue;

if (buf == boundBuffer)
boundBuffer = NULL;

linearFree(buf->data);
glShutdownBufferCTR(buf);
free(buf);
}
}
Expand Down

0 comments on commit e6f5313

Please sign in to comment.