Gawain: fixups & progress for batch API
This commit is contained in:
parent
dabbe6eb22
commit
e53ab2b9ec
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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*);
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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*);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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*);
|
||||
|
||||
|
|
Loading…
Reference in New Issue