Gawain: fixups & progress for batch API

This commit is contained in:
Mike Erwin 2016-10-23 23:16:54 -04:00
parent dabbe6eb22
commit e53ab2b9ec
6 changed files with 125 additions and 11 deletions

View File

@ -12,6 +12,10 @@
#include "batch.h"
#include <stdlib.h>
// necessary functions from matrix API
extern void gpuBindMatrices(GLuint program);
extern bool gpuMatricesDirty(void); // how best to use this here?
Batch* Batch_create(GLenum prim_type, VertexBuffer* verts, ElementList* elem)
{
#if TRUST_NO_ONE
@ -30,30 +34,54 @@ Batch* Batch_create(GLenum prim_type, VertexBuffer* verts, ElementList* elem)
return batch;
}
void Batch_discard(Batch* batch)
{
// TODO: clean up
}
void Batch_discard_all(Batch* batch)
{
VertexBuffer_discard(batch->verts);
if (batch->elem)
ElementList_discard(batch->elem);
Batch_discard(batch);
}
void Batch_set_program(Batch* batch, GLuint program)
{
#if TRUST_NO_ONE
assert(glIsProgram(program));
#endif
batch->program = program;
batch->program_dirty = true;
}
static void Batch_update_program_bindings(Batch* batch)
{
#if TRUST_NO_ONE
assert(glIsProgram(batch->program));
#endif
const VertexFormat* format = &batch->verts->format;
const unsigned attrib_ct = format->attrib_ct;
const unsigned stride = format->stride;
// disable all as a precaution
// why are we not using prev_attrib_enabled_bits?? see immediate.c
for (unsigned a_idx = 0; a_idx < MAX_VERTEX_ATTRIBS; ++a_idx)
glDisableVertexAttribArray(a_idx);
VertexBuffer_use(batch->verts);
for (unsigned a_idx = 0; a_idx < attrib_ct; ++a_idx)
{
const Attrib* a = format->attribs + a_idx;
const GLvoid* pointer = (const GLubyte*)0 + a->offset;
const unsigned loc = glGetAttribLocation(batch->program, a->name);
const GLint loc = glGetAttribLocation(batch->program, a->name);
#if TRUST_NO_ONE
assert(loc != -1);
#endif
glEnableVertexAttribArray(loc);
@ -74,6 +102,60 @@ static void Batch_update_program_bindings(Batch* batch)
batch->program_dirty = false;
}
static void Batch_use_program(Batch* batch)
{
if (!batch->program_in_use)
{
glUseProgram(batch->program);
batch->program_in_use = true;
}
}
static void Batch_done_using_program(Batch* batch)
{
if (batch->program_in_use)
{
glUseProgram(0);
batch->program_in_use = false;
}
}
void Batch_Uniform1b(Batch* batch, const char* name, bool value)
{
int loc = glGetUniformLocation(batch->program, name);
#if TRUST_NO_ONE
assert(loc != -1);
#endif
Batch_use_program(batch);
glUniform1i(loc, value ? GL_TRUE : GL_FALSE);
}
void Batch_Uniform3fv(Batch* batch, const char* name, const float data[3])
{
int loc = glGetUniformLocation(batch->program, name);
#if TRUST_NO_ONE
assert(loc != -1);
#endif
Batch_use_program(batch);
glUniform3fv(loc, 1, data);
}
void Batch_Uniform4fv(Batch* batch, const char* name, const float data[4])
{
int loc = glGetUniformLocation(batch->program, name);
#if TRUST_NO_ONE
assert(loc != -1);
#endif
Batch_use_program(batch);
glUniform4fv(loc, 1, data);
}
static void Batch_prime(Batch* batch)
{
glGenVertexArrays(1, &batch->vao_id);
@ -91,6 +173,7 @@ void Batch_draw(Batch* batch)
{
#if TRUST_NO_ONE
assert(batch->phase == READY_TO_DRAW);
assert(glIsProgram(batch->program));
#endif
if (batch->vao_id)
@ -101,7 +184,9 @@ void Batch_draw(Batch* batch)
if (batch->program_dirty)
Batch_update_program_bindings(batch);
glUseProgram(batch->program);
Batch_use_program(batch);
gpuBindMatrices(batch->program);
if (batch->elem)
{
@ -119,6 +204,6 @@ void Batch_draw(Batch* batch)
else
glDrawArrays(batch->prim_type, 0, batch->verts->vertex_ct);
glUseProgram(0);
Batch_done_using_program(batch);
glBindVertexArray(0);
}

View File

@ -31,6 +31,7 @@ typedef struct {
GLuint vao_id; // remembers all geometry state (vertex attrib bindings & element buffer)
BatchPhase phase;
bool program_dirty;
bool program_in_use;
// state
GLuint program;
@ -38,13 +39,19 @@ typedef struct {
Batch* Batch_create(GLenum prim_type, VertexBuffer*, ElementList*);
// TODO: void Batch_discard(Batch*);
// must first decide how sharing of vertex buffers & index buffers should work
void Batch_discard(Batch*); // verts & elem are not discarded
void Batch_discard_all(Batch*); // including verts & elem
void Batch_set_program(Batch*, GLuint program);
// Entire batch draws with one shader program, but can be redrawn later with another program.
// Vertex shader's inputs must be compatible with the batch's vertex format.
void Batch_Uniform1b(Batch*, const char* name, bool value);
// void Batch_Uniform1f(Batch*, float value);
// void Batch_Uniform4f(Batch*, float x, float y, float z, float w);
void Batch_Uniform3fv(Batch*, const char* name, const float data[3]);
void Batch_Uniform4fv(Batch*, const char* name, const float data[4]);
void Batch_draw(Batch*);

View File

@ -204,7 +204,14 @@ static void squeeze_indices_short(const unsigned values[], ElementList* elem)
#endif // TRACK_INDEX_RANGE
void ElementList_build(ElementListBuilder* builder, ElementList* elem)
ElementList* ElementList_build(ElementListBuilder* builder)
{
ElementList* elem = calloc(1, sizeof(ElementList));
ElementList_build_in_place(builder, elem);
return elem;
}
void ElementList_build_in_place(ElementListBuilder* builder, ElementList* elem)
{
#if TRUST_NO_ONE
assert(builder->data != NULL);
@ -260,3 +267,8 @@ void ElementList_build(ElementListBuilder* builder, ElementList* elem)
builder->data = NULL;
// other fields are safe to leave
}
void ElementList_discard(ElementList* elem)
{
// TODO: clean up
}

View File

@ -52,4 +52,7 @@ void add_point_vertex(ElementListBuilder*, unsigned v);
void add_line_vertices(ElementListBuilder*, unsigned v1, unsigned v2);
void add_triangle_vertices(ElementListBuilder*, unsigned v1, unsigned v2, unsigned v3);
void ElementList_build(ElementListBuilder*, ElementList*);
ElementList* ElementList_build(ElementListBuilder*);
void ElementList_build_in_place(ElementListBuilder*, ElementList*);
void ElementList_discard(ElementList*);

View File

@ -47,6 +47,11 @@ void VertexBuffer_init_with_format(VertexBuffer* verts, const VertexFormat* form
VertexFormat_pack(&verts->format);
}
void VertexBuffer_discard(VertexBuffer* verts)
{
// TODO: clean up
}
unsigned VertexBuffer_size(const VertexBuffer* verts)
{
return vertex_buffer_size(&verts->format, verts->vertex_ct);

View File

@ -32,6 +32,8 @@ typedef struct {
VertexBuffer* VertexBuffer_create(void);
VertexBuffer* VertexBuffer_create_with_format(const VertexFormat*);
void VertexBuffer_discard(VertexBuffer*);
void VertexBuffer_init(VertexBuffer*);
void VertexBuffer_init_with_format(VertexBuffer*, const VertexFormat*);