Gawain: flesh out VertexBuffer
create, specify, fill with data
This commit is contained in:
parent
df7be04ca6
commit
110d68ca1d
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue