Buffer vertex maps;

This commit is contained in:
bjorn 2016-09-17 17:52:52 -07:00
parent d3ba10a129
commit 32d7562d8e
5 changed files with 130 additions and 9 deletions

View File

@ -5,6 +5,7 @@
void lovrBufferDestroy(Buffer* buffer) {
glDeleteBuffers(1, &buffer->vbo);
glDeleteVertexArrays(1, &buffer->vao);
vec_deinit(&buffer->map);
free(buffer->data);
free(buffer);
}
@ -12,7 +13,23 @@ void lovrBufferDestroy(Buffer* buffer) {
void lovrBufferDraw(Buffer* buffer) {
glBindVertexArray(buffer->vao);
glEnableVertexAttribArray(0);
glDrawArrays(buffer->drawMode, buffer->rangeStart, buffer->rangeCount);
int usingIbo = buffer->map.length > 0;
int start, count;
if (buffer->isRangeEnabled) {
start = buffer->rangeStart;
count = buffer->rangeCount;
} else {
start = 0;
count = usingIbo ? buffer->map.length : buffer->size;
}
if (usingIbo) {
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer->ibo);
glDrawElements(buffer->drawMode, count, GL_UNSIGNED_INT, (GLvoid*) NULL + start);
} else {
glDrawArrays(buffer->drawMode, start, count);
}
glDisableVertexAttribArray(0);
}
@ -46,17 +63,47 @@ void lovrBufferSetVertex(Buffer* buffer, int index, float x, float y, float z) {
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
}
unsigned int* lovrBufferGetVertexMap(Buffer* buffer, int* count) {
*count = buffer->map.length;
return buffer->map.data;
}
void lovrBufferSetVertexMap(Buffer* buffer, unsigned int* map, int count) {
if (count == 0 || !map) {
vec_clear(&buffer->map);
glDeleteBuffers(1, &buffer->ibo);
buffer->ibo = 0;
} else if (!buffer->ibo) {
glGenBuffers(1, &buffer->ibo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer->ibo);
}
vec_clear(&buffer->map);
vec_reserve(&buffer->map, count);
vec_pusharr(&buffer->map, map, count);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, count * sizeof(unsigned int), buffer->map.data, GL_STATIC_DRAW);
}
char lovrBufferIsRangeEnabled(Buffer* buffer) {
return buffer->isRangeEnabled;
}
void lovrBufferSetRangeEnabled(Buffer* buffer, char isEnabled) {
buffer->isRangeEnabled = isEnabled;
}
void lovrBufferGetDrawRange(Buffer* buffer, int* start, int* end) {
*start = buffer->rangeStart + 1;
*end = buffer->rangeStart + 1 + buffer->rangeCount;
*start = buffer->rangeStart;
*end = buffer->rangeStart + buffer->rangeCount - 1;
}
int lovrBufferSetDrawRange(Buffer* buffer, int rangeStart, int rangeEnd) {
if (rangeStart <= 0 || rangeEnd <= 0 || rangeStart > rangeEnd) {
if (rangeStart < 0 || rangeEnd < 0 || rangeStart > rangeEnd) {
return 1;
}
buffer->rangeStart = rangeStart - 1;
buffer->rangeStart = rangeStart;
buffer->rangeCount = rangeEnd - rangeStart + 1;
return 0;
}

View File

@ -1,4 +1,5 @@
#include "../glfw.h"
#include "../vendor/vec/vec.h"
#ifndef LOVR_BUFFER_TYPES
#define LOVR_BUFFER_TYPES
@ -15,6 +16,8 @@ typedef enum {
BUFFER_STREAM = GL_STREAM_DRAW
} BufferUsage;
typedef vec_t(unsigned int) vec_uint_t;
typedef struct {
int size;
GLfloat* data;
@ -22,6 +25,9 @@ typedef struct {
BufferUsage usage;
GLuint vao;
GLuint vbo;
GLuint ibo;
vec_uint_t map;
char isRangeEnabled;
int rangeStart;
int rangeCount;
} Buffer;
@ -34,5 +40,7 @@ int lovrBufferSetDrawMode(Buffer* buffer, BufferDrawMode drawMode);
int lovrBufferGetVertexCount(Buffer* buffer);
void lovrBufferGetVertex(Buffer* buffer, int index, float* x, float* y, float* z);
void lovrBufferSetVertex(Buffer* buffer, int index, float x, float y, float z);
unsigned int* lovrBufferGetVertexMap(Buffer* buffer, int* count);
void lovrBufferSetVertexMap(Buffer* buffer, unsigned int* map, int count);
void lovrBufferGetDrawRange(Buffer* buffer, int* start, int* count);
int lovrBufferSetDrawRange(Buffer* buffer, int start, int count);

View File

@ -68,6 +68,10 @@ Buffer* lovrGraphicsNewBuffer(int size, BufferDrawMode drawMode, BufferUsage usa
buffer->usage = usage;
buffer->size = size;
buffer->data = malloc(buffer->size * 3 * sizeof(GLfloat));
buffer->vao = 0;
buffer->vbo = 0;
buffer->ibo = 0;
buffer->isRangeEnabled = 0;
buffer->rangeStart = 0;
buffer->rangeCount = buffer->size;
@ -77,6 +81,8 @@ Buffer* lovrGraphicsNewBuffer(int size, BufferDrawMode drawMode, BufferUsage usa
glGenVertexArrays(1, &buffer->vao);
vec_init(&buffer->map);
return buffer;
}

View File

@ -28,6 +28,8 @@ const luaL_Reg lovrBuffer[] = {
{ "getVertexCount", l_lovrBufferGetVertexCount },
{ "getVertex", l_lovrBufferGetVertex },
{ "setVertex", l_lovrBufferSetVertex },
{ "getVertexMap", l_lovrBufferGetVertexMap },
{ "setVertexMap", l_lovrBufferSetVertexMap },
{ "getDrawMode", l_lovrBufferGetDrawMode },
{ "setDrawMode", l_lovrBufferSetDrawMode },
{ "getDrawRange", l_lovrBufferGetDrawRange },
@ -111,19 +113,75 @@ int l_lovrBufferSetVertex(lua_State* L) {
return 0;
}
int l_lovrBufferGetVertexMap(lua_State* L) {
Buffer* buffer = luax_checkbuffer(L, 1);
int count;
unsigned int* indices = lovrBufferGetVertexMap(buffer, &count);
if (count == 0) {
lua_pushnil(L);
return 1;
}
lua_newtable(L);
for (int i = 0; i < count; i++) {
lua_pushinteger(L, indices[i]);
lua_rawseti(L, -2, i + 1);
}
return 1;
}
int l_lovrBufferSetVertexMap(lua_State* L) {
Buffer* buffer = luax_checkbuffer(L, 1);
if (lua_isnoneornil(L, 2)) {
lovrBufferSetVertexMap(buffer, NULL, 0);
return 0;
}
luaL_checktype(L, 2, LUA_TTABLE);
int count = lua_objlen(L, 2);
unsigned int* indices = malloc(count * sizeof(int));
for (int i = 0; i < count; i++) {
lua_rawgeti(L, 2, i + 1);
if (!lua_isnumber(L, -1)) {
return luaL_error(L, "Buffer vertex map index #%d must be numeric", i);
}
indices[i] = lua_tonumber(L, -1) - 1;
lua_pop(L, 1);
}
lovrBufferSetVertexMap(buffer, indices, count);
free(indices);
return 0;
}
int l_lovrBufferGetDrawRange(lua_State* L) {
Buffer* buffer = luax_checkbuffer(L, 1);
if (lovrBufferIsRangeEnabled(buffer)) {
lua_pushnil(L);
return 1;
}
int start, end;
lovrBufferGetDrawRange(buffer, &start, &end);
lua_pushinteger(L, start);
lua_pushinteger(L, end);
lua_pushinteger(L, start + 1);
lua_pushinteger(L, end + 1);
return 2;
}
int l_lovrBufferSetDrawRange(lua_State* L) {
Buffer* buffer = luax_checkbuffer(L, 1);
int rangeStart = luaL_checkinteger(L, 2);
int rangeEnd = luaL_checkinteger(L, 3);
if (lua_isnoneornil(L, 2)) {
lovrBufferSetRangeEnabled(buffer, 0);
return 0;
}
lovrBufferSetRangeEnabled(buffer, 1);
int rangeStart = luaL_checkinteger(L, 2) - 1;
int rangeEnd = luaL_checkinteger(L, 3) - 1;
if (lovrBufferSetDrawRange(buffer, rangeStart, rangeEnd)) {
return luaL_error(L, "Invalid buffer draw range (%d, %d)", rangeStart, rangeEnd);
}

View File

@ -12,6 +12,8 @@ int l_lovrBufferDraw(lua_State* L);
int l_lovrBufferGetVertexCount(lua_State* L);
int l_lovrBufferGetVertex(lua_State* L);
int l_lovrBufferSetVertex(lua_State* L);
int l_lovrBufferGetVertexMap(lua_State* L);
int l_lovrBufferSetVertexMap(lua_State* L);
int l_lovrBufferGetDrawMode(lua_State* L);
int l_lovrBufferSetDrawMode(lua_State* L);
int l_lovrBufferGetDrawRange(lua_State* L);