Gawain: flesh out VertexBuffer

create, specify, fill with data
This commit is contained in:
Mike Erwin 2016-09-14 16:28:16 +02:00
parent df7be04ca6
commit 110d68ca1d
2 changed files with 98 additions and 4 deletions

View File

@ -10,5 +10,82 @@
// the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
#include "vertex_buffer.h"
#include <stdlib.h>
#include <string.h>
// TODO: implement C functions
VertexBuffer* create_VertexBuffer()
{
VertexBuffer* verts = malloc(sizeof(VertexBuffer));
init_VertexBuffer(verts);
return verts;
}
void init_VertexBuffer(VertexBuffer* verts)
{
memset(verts, 0, sizeof(VertexBuffer));
}
void allocate_vertex_data(VertexBuffer* verts, unsigned v_ct)
{
VertexFormat* format = &verts->format;
if (!format->packed)
pack(format);
verts->vertex_ct = v_ct;
// Data initially lives in main memory. Will be transferred to VRAM when we "prime" it.
verts->data = malloc(vertex_buffer_size(format, v_ct));
}
void setAttrib(VertexBuffer* verts, unsigned a_idx, unsigned v_idx, const void* data)
{
const VertexFormat* format = &verts->format;
const Attrib* a = format->attribs + a_idx;
#if TRUST_NO_ONE
assert(a_idx < format->attrib_ct);
assert(v_idx < verts->vertex_ct);
assert(verts->data != NULL); // data must be in main mem
#endif
memcpy((GLubyte*)verts->data + a->offset + v_idx * format->stride, data, a->sz);
}
void fillAttrib(VertexBuffer* verts, unsigned a_idx, const void* data)
{
const VertexFormat* format = &verts->format;
const Attrib* a = format->attribs + a_idx;
#if TRUST_NO_ONE
assert(a_idx < format->attrib_ct);
#endif
const unsigned stride = a->sz; // tightly packed input data
fillAttribStride(verts, a_idx, stride, data);
}
void fillAttribStride(VertexBuffer* verts, unsigned a_idx, unsigned stride, const void* data)
{
const VertexFormat* format = &verts->format;
const Attrib* a = format->attribs + a_idx;
#if TRUST_NO_ONE
assert(a_idx < format->attrib_ct);
assert(verts->data != NULL); // data must be in main mem
#endif
const unsigned vertex_ct = verts->vertex_ct;
if (format->attrib_ct == 1 && stride == format->stride)
{
// we can copy it all at once
memcpy(verts->data, data, vertex_ct * a->sz);
}
else
{
// we must copy it per vertex
for (unsigned v = 0; v < vertex_ct; ++v)
memcpy((GLubyte*)verts->data + a->offset + v * format->stride, (const GLubyte*)data + v * stride, a->sz);
}
}

View File

@ -13,6 +13,15 @@
#include "vertex_format.h"
// How to create a VertexBuffer:
// 1) verts = create_VertexBuffer() or init_VertexBuffer(verts)
// 2) add_attrib(verts->format, ...)
// 3) allocate_vertex_data(verts, vertex_ct) <-- finalizes/packs vertex format
// 4) fillAttrib(verts, pos, application_pos_buffer)
// 5) prime_VertexBuffer(verts);
// Is VertexBuffer always used as part of a Batch?
typedef struct {
VertexFormat format;
unsigned vertex_ct;
@ -20,8 +29,13 @@ typedef struct {
GLuint vbo_id; // 0 indicates not yet sent to VRAM
} VertexBuffer;
VertexBuffer* create_VertexBuffer(VertexFormat*, unsigned v_ct); // create means allocate, then init
void init_VertexBuffer(VertexBuffer*, VertexFormat*, unsigned v_ct);
VertexBuffer* create_VertexBuffer(void); // create means allocate, then init
void init_VertexBuffer(VertexBuffer*);
// TODO: use copy of existing format
// void init_VertexBuffer_with_format(VertexBuffer*, VertexFormat*);
void allocate_vertex_data(VertexBuffer*, unsigned v_ct);
// The most important setAttrib variant is the untyped one. Get it right first.
// It takes a void* so the app developer is responsible for matching their app data types
@ -29,9 +43,12 @@ void init_VertexBuffer(VertexBuffer*, VertexFormat*, unsigned v_ct);
// should not be a problem.
void setAttrib(VertexBuffer*, unsigned a_idx, unsigned v_idx, const void* data);
void fillAttrib(VertexBuffer*, unsigned a_idx, const void* data);
void fillAttrib(VertexBuffer*, unsigned a_idx, const void* data); // tightly packed, non interleaved input data
void fillAttribStride(VertexBuffer*, unsigned a_idx, unsigned stride, const void* data);
// TODO: decide whether to keep the functions below
// doesn't immediate mode satisfy these needs?
// void setAttrib1f(unsigned a_idx, unsigned v_idx, float x);
// void setAttrib2f(unsigned a_idx, unsigned v_idx, float x, float y);
// void setAttrib3f(unsigned a_idx, unsigned v_idx, float x, float y, float z);