mirror of https://github.com/bjornbytes/lovr.git
Buffer vertex maps;
This commit is contained in:
parent
d3ba10a129
commit
32d7562d8e
|
@ -5,6 +5,7 @@
|
||||||
void lovrBufferDestroy(Buffer* buffer) {
|
void lovrBufferDestroy(Buffer* buffer) {
|
||||||
glDeleteBuffers(1, &buffer->vbo);
|
glDeleteBuffers(1, &buffer->vbo);
|
||||||
glDeleteVertexArrays(1, &buffer->vao);
|
glDeleteVertexArrays(1, &buffer->vao);
|
||||||
|
vec_deinit(&buffer->map);
|
||||||
free(buffer->data);
|
free(buffer->data);
|
||||||
free(buffer);
|
free(buffer);
|
||||||
}
|
}
|
||||||
|
@ -12,7 +13,23 @@ void lovrBufferDestroy(Buffer* buffer) {
|
||||||
void lovrBufferDraw(Buffer* buffer) {
|
void lovrBufferDraw(Buffer* buffer) {
|
||||||
glBindVertexArray(buffer->vao);
|
glBindVertexArray(buffer->vao);
|
||||||
glEnableVertexAttribArray(0);
|
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);
|
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);
|
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) {
|
void lovrBufferGetDrawRange(Buffer* buffer, int* start, int* end) {
|
||||||
*start = buffer->rangeStart + 1;
|
*start = buffer->rangeStart;
|
||||||
*end = buffer->rangeStart + 1 + buffer->rangeCount;
|
*end = buffer->rangeStart + buffer->rangeCount - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int lovrBufferSetDrawRange(Buffer* buffer, int rangeStart, int rangeEnd) {
|
int lovrBufferSetDrawRange(Buffer* buffer, int rangeStart, int rangeEnd) {
|
||||||
if (rangeStart <= 0 || rangeEnd <= 0 || rangeStart > rangeEnd) {
|
if (rangeStart < 0 || rangeEnd < 0 || rangeStart > rangeEnd) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer->rangeStart = rangeStart - 1;
|
buffer->rangeStart = rangeStart;
|
||||||
buffer->rangeCount = rangeEnd - rangeStart + 1;
|
buffer->rangeCount = rangeEnd - rangeStart + 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include "../glfw.h"
|
#include "../glfw.h"
|
||||||
|
#include "../vendor/vec/vec.h"
|
||||||
|
|
||||||
#ifndef LOVR_BUFFER_TYPES
|
#ifndef LOVR_BUFFER_TYPES
|
||||||
#define LOVR_BUFFER_TYPES
|
#define LOVR_BUFFER_TYPES
|
||||||
|
@ -15,6 +16,8 @@ typedef enum {
|
||||||
BUFFER_STREAM = GL_STREAM_DRAW
|
BUFFER_STREAM = GL_STREAM_DRAW
|
||||||
} BufferUsage;
|
} BufferUsage;
|
||||||
|
|
||||||
|
typedef vec_t(unsigned int) vec_uint_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int size;
|
int size;
|
||||||
GLfloat* data;
|
GLfloat* data;
|
||||||
|
@ -22,6 +25,9 @@ typedef struct {
|
||||||
BufferUsage usage;
|
BufferUsage usage;
|
||||||
GLuint vao;
|
GLuint vao;
|
||||||
GLuint vbo;
|
GLuint vbo;
|
||||||
|
GLuint ibo;
|
||||||
|
vec_uint_t map;
|
||||||
|
char isRangeEnabled;
|
||||||
int rangeStart;
|
int rangeStart;
|
||||||
int rangeCount;
|
int rangeCount;
|
||||||
} Buffer;
|
} Buffer;
|
||||||
|
@ -34,5 +40,7 @@ int lovrBufferSetDrawMode(Buffer* buffer, BufferDrawMode drawMode);
|
||||||
int lovrBufferGetVertexCount(Buffer* buffer);
|
int lovrBufferGetVertexCount(Buffer* buffer);
|
||||||
void lovrBufferGetVertex(Buffer* buffer, int index, float* x, float* y, float* z);
|
void lovrBufferGetVertex(Buffer* buffer, int index, float* x, float* y, float* z);
|
||||||
void lovrBufferSetVertex(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);
|
void lovrBufferGetDrawRange(Buffer* buffer, int* start, int* count);
|
||||||
int lovrBufferSetDrawRange(Buffer* buffer, int start, int count);
|
int lovrBufferSetDrawRange(Buffer* buffer, int start, int count);
|
||||||
|
|
|
@ -68,6 +68,10 @@ Buffer* lovrGraphicsNewBuffer(int size, BufferDrawMode drawMode, BufferUsage usa
|
||||||
buffer->usage = usage;
|
buffer->usage = usage;
|
||||||
buffer->size = size;
|
buffer->size = size;
|
||||||
buffer->data = malloc(buffer->size * 3 * sizeof(GLfloat));
|
buffer->data = malloc(buffer->size * 3 * sizeof(GLfloat));
|
||||||
|
buffer->vao = 0;
|
||||||
|
buffer->vbo = 0;
|
||||||
|
buffer->ibo = 0;
|
||||||
|
buffer->isRangeEnabled = 0;
|
||||||
buffer->rangeStart = 0;
|
buffer->rangeStart = 0;
|
||||||
buffer->rangeCount = buffer->size;
|
buffer->rangeCount = buffer->size;
|
||||||
|
|
||||||
|
@ -77,6 +81,8 @@ Buffer* lovrGraphicsNewBuffer(int size, BufferDrawMode drawMode, BufferUsage usa
|
||||||
|
|
||||||
glGenVertexArrays(1, &buffer->vao);
|
glGenVertexArrays(1, &buffer->vao);
|
||||||
|
|
||||||
|
vec_init(&buffer->map);
|
||||||
|
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,8 @@ const luaL_Reg lovrBuffer[] = {
|
||||||
{ "getVertexCount", l_lovrBufferGetVertexCount },
|
{ "getVertexCount", l_lovrBufferGetVertexCount },
|
||||||
{ "getVertex", l_lovrBufferGetVertex },
|
{ "getVertex", l_lovrBufferGetVertex },
|
||||||
{ "setVertex", l_lovrBufferSetVertex },
|
{ "setVertex", l_lovrBufferSetVertex },
|
||||||
|
{ "getVertexMap", l_lovrBufferGetVertexMap },
|
||||||
|
{ "setVertexMap", l_lovrBufferSetVertexMap },
|
||||||
{ "getDrawMode", l_lovrBufferGetDrawMode },
|
{ "getDrawMode", l_lovrBufferGetDrawMode },
|
||||||
{ "setDrawMode", l_lovrBufferSetDrawMode },
|
{ "setDrawMode", l_lovrBufferSetDrawMode },
|
||||||
{ "getDrawRange", l_lovrBufferGetDrawRange },
|
{ "getDrawRange", l_lovrBufferGetDrawRange },
|
||||||
|
@ -111,19 +113,75 @@ int l_lovrBufferSetVertex(lua_State* L) {
|
||||||
return 0;
|
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) {
|
int l_lovrBufferGetDrawRange(lua_State* L) {
|
||||||
Buffer* buffer = luax_checkbuffer(L, 1);
|
Buffer* buffer = luax_checkbuffer(L, 1);
|
||||||
|
if (lovrBufferIsRangeEnabled(buffer)) {
|
||||||
|
lua_pushnil(L);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
int start, end;
|
int start, end;
|
||||||
lovrBufferGetDrawRange(buffer, &start, &end);
|
lovrBufferGetDrawRange(buffer, &start, &end);
|
||||||
lua_pushinteger(L, start);
|
lua_pushinteger(L, start + 1);
|
||||||
lua_pushinteger(L, end);
|
lua_pushinteger(L, end + 1);
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
int l_lovrBufferSetDrawRange(lua_State* L) {
|
int l_lovrBufferSetDrawRange(lua_State* L) {
|
||||||
Buffer* buffer = luax_checkbuffer(L, 1);
|
Buffer* buffer = luax_checkbuffer(L, 1);
|
||||||
int rangeStart = luaL_checkinteger(L, 2);
|
if (lua_isnoneornil(L, 2)) {
|
||||||
int rangeEnd = luaL_checkinteger(L, 3);
|
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)) {
|
if (lovrBufferSetDrawRange(buffer, rangeStart, rangeEnd)) {
|
||||||
return luaL_error(L, "Invalid buffer draw range (%d, %d)", rangeStart, rangeEnd);
|
return luaL_error(L, "Invalid buffer draw range (%d, %d)", rangeStart, rangeEnd);
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,8 @@ int l_lovrBufferDraw(lua_State* L);
|
||||||
int l_lovrBufferGetVertexCount(lua_State* L);
|
int l_lovrBufferGetVertexCount(lua_State* L);
|
||||||
int l_lovrBufferGetVertex(lua_State* L);
|
int l_lovrBufferGetVertex(lua_State* L);
|
||||||
int l_lovrBufferSetVertex(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_lovrBufferGetDrawMode(lua_State* L);
|
||||||
int l_lovrBufferSetDrawMode(lua_State* L);
|
int l_lovrBufferSetDrawMode(lua_State* L);
|
||||||
int l_lovrBufferGetDrawRange(lua_State* L);
|
int l_lovrBufferGetDrawRange(lua_State* L);
|
||||||
|
|
Loading…
Reference in New Issue