From 56c365c8cc88455d69df42e7842c986e760c776e Mon Sep 17 00:00:00 2001 From: jussi Date: Thu, 26 Oct 2023 20:09:16 +0300 Subject: Buffer userdata object and rlgl Vertex buffers management. --- src/core.c | 74 ++++++++++++++++ src/gl.c | 2 +- src/lua_core.c | 30 +++++++ src/rlgl.c | 268 +++++++++++++++++++++++++++++++++++++++++++-------------- 4 files changed, 310 insertions(+), 64 deletions(-) (limited to 'src') diff --git a/src/core.c b/src/core.c index a4bd9cd..e49c84d 100644 --- a/src/core.c +++ b/src/core.c @@ -3558,3 +3558,77 @@ int lcoreGetScreenToWorld2D( lua_State *L ) { return 1; } + +/* +> buffer = RL.LoadBuffer( data{} buffer, int type ) + +Creates buffer as userdata. Type should be one of the Buffer types + +- Failure return false +- Success return Buffer +*/ +int lcoreLoadBuffer( lua_State *L ) { + if ( !lua_istable( L, 1 ) || !lua_isnumber( L, 2 ) ) { + TraceLog( state->logLevelInvalid, "%s", "Bad call of function. RL.LoadBuffer( data{} buffer, int type )" ); + lua_pushboolean( L, false ); + return 1; + } + int type = lua_tointeger( L, 2 ); + Buffer *buffer = lua_newuserdata( L, sizeof( Buffer ) ); + int len = uluaGetTableLenIndex( L, 1 ); + + switch ( type ) { + case BUFFER_UNSIGNED_CHAR: + buffer->size = len * sizeof( unsigned char ); + break; + case BUFFER_UNSIGNED_SHORT: + buffer->size = len * sizeof( unsigned short ); + break; + case BUFFER_UNSIGNED_INT: + buffer->size = len * sizeof( unsigned int ); + break; + case BUFFER_FLOAT: + buffer->size = len * sizeof( float ); + break; + default: + break; + } + buffer->data = malloc( buffer->size ); + + int t = 1; + int i = 0; + unsigned char *up = buffer->data; + unsigned short *sp = buffer->data; + unsigned int *ip = buffer->data; + float *fp = buffer->data; + + lua_pushnil( L ); + + while ( lua_next( L, t ) != 0 ) { + switch ( type ) { + case BUFFER_UNSIGNED_CHAR: + *up = (unsigned char)lua_tointeger( L, -1 ); + up++; + break; + case BUFFER_UNSIGNED_SHORT: + *sp = (unsigned short)lua_tointeger( L, -1 ); + up++; + break; + case BUFFER_UNSIGNED_INT: + *ip = (unsigned int)lua_tointeger( L, -1 ); + up++; + break; + case BUFFER_FLOAT: + *fp = (float)lua_tonumber( L, -1 ); + fp++; + break; + default: + break; + } + lua_pop( L, 1 ); + i++; + } + luaL_setmetatable( L, "Buffer" ); + + return 1; +} diff --git a/src/gl.c b/src/gl.c index a6e0e0e..36a0637 100644 --- a/src/gl.c +++ b/src/gl.c @@ -58,4 +58,4 @@ int lglBlitFramebuffer( lua_State *L ) { lua_pushboolean( L, true ); return 1; -} \ No newline at end of file +} diff --git a/src/lua_core.c b/src/lua_core.c index f8b25bb..1d6372b 100644 --- a/src/lua_core.c +++ b/src/lua_core.c @@ -618,6 +618,11 @@ static void defineGlobals() { assignGlobalInt( GLFW_RELEASE, "GLFW_RELEASE" ); assignGlobalInt( GLFW_PRESS, "GLFW_PRESS" ); assignGlobalInt( GLFW_REPEAT, "GLFW_REPEAT" ); + /* CBuffer Data Types */ + assignGlobalInt( BUFFER_UNSIGNED_CHAR, "BUFFER_UNSIGNED_CHAR" ); + assignGlobalInt( BUFFER_UNSIGNED_SHORT, "BUFFER_UNSIGNED_SHORT" ); + assignGlobalInt( BUFFER_UNSIGNED_INT, "BUFFER_UNSIGNED_INT" ); + assignGlobalInt( BUFFER_FLOAT, "BUFFER_FLOAT" ); /* Window Events. */ assignGlobalInt( EVENT_WINDOW_SIZE, "EVENT_WINDOW_SIZE" ); assignGlobalInt( EVENT_WINDOW_MAXIMIZE, "EVENT_WINDOW_MAXIMIZE" ); @@ -636,6 +641,21 @@ static void defineGlobals() { lua_pop( L, -1 ); } +static int freeBuffer( lua_State *L ) { + Buffer *buffer = luaL_checkudata ( L, 1, "Buffer" ); + free( buffer->data ); +} + +static void defineCBuffer() { + lua_State *L = state->luaState; + + luaL_newmetatable( L, "Buffer" ); + lua_pushvalue( L, -1 ); + lua_setfield( L, -2, "__index" ); + lua_pushcfunction( L, freeBuffer ); + lua_setfield( L, -2, "__gc" ); +} + // Custom logging funtion. static void logCustom( int logLevel, const char *text, va_list args ) { char string[ STRING_LEN ] = {'\0'}; @@ -1019,6 +1039,7 @@ bool luaInit( int argn, const char **argc ) { return false; } defineGlobals(); + defineCBuffer(); /* Set arguments. */ lua_getglobal( L, "RL" ); @@ -1235,6 +1256,7 @@ void luaRegister() { assingGlobalFunction( "SetLogLevelInvalid", lcoreSetLogLevelInvalid ); assingGlobalFunction( "GetLogLevelInvalid", lcoreGetLogLevelInvalid ); assingGlobalFunction( "OpenURL", lcoreOpenURL ); + assingGlobalFunction( "LoadBuffer", lcoreLoadBuffer ); /* Cursor. */ assingGlobalFunction( "ShowCursor", lcoreShowCursor ); assingGlobalFunction( "HideCursor", lcoreHideCursor ); @@ -1944,10 +1966,18 @@ void luaRegister() { /* Vertex buffers management. */ assingGlobalFunction( "rlLoadVertexArray", lrlglLoadVertexArray ); assingGlobalFunction( "rlLoadVertexBuffer", lrlglLoadVertexBuffer ); + assingGlobalFunction( "rlLoadVertexBufferElement", lrlglLoadVertexBufferElement ); + assingGlobalFunction( "rlUpdateVertexBuffer", lrlglUpdateVertexBuffer ); + assingGlobalFunction( "rlUpdateVertexBufferElements", lrlglUpdateVertexBufferElements ); assingGlobalFunction( "rlUnloadVertexArray", lrlglUnloadVertexArray ); assingGlobalFunction( "rlUnloadVertexBuffer", lrlglUnloadVertexBuffer ); assingGlobalFunction( "rlSetVertexAttribute", lrlglSetVertexAttribute ); + assingGlobalFunction( "rlSetVertexAttributeDivisor", lrlglSetVertexAttributeDivisor ); + assingGlobalFunction( "rlSetVertexAttributeDefault", lrlglSetVertexAttributeDefault ); assingGlobalFunction( "rlDrawVertexArray", lrlglDrawVertexArray ); + assingGlobalFunction( "rlDrawVertexArrayElements", lrlglDrawVertexArrayElements ); + assingGlobalFunction( "rlDrawVertexArrayInstanced", lrlglDrawVertexArrayInstanced ); + assingGlobalFunction( "rlDrawVertexArrayElementsInstanced", lrlglDrawVertexArrayElementsInstanced ); /* Textures management. */ assingGlobalFunction( "rlLoadTexture", lrlglLoadTexture ); assingGlobalFunction( "rlLoadTextureDepth", lrlglLoadTextureDepth ); diff --git a/src/rlgl.c b/src/rlgl.c index b369047..6f5ece1 100644 --- a/src/rlgl.c +++ b/src/rlgl.c @@ -3,58 +3,6 @@ #include "lua_core.h" #include "lrlgl.h" -static void* getVertexBuffer( lua_State *L, int *type, unsigned int *size ) { - *type = lua_tointeger( L, 2 ); - size_t len = uluaGetTableLenIndex( L, 1 ); - unsigned char *uByteArray; - float *floatArray; - - switch ( *type ) { - case RL_UNSIGNED_BYTE: - *size = len * sizeof( unsigned char ); - uByteArray = MemAlloc( *size ); - break; - case RL_FLOAT: - *size = len * sizeof( float ); - floatArray = MemAlloc( *size ); - break; - default: - break; - } - - int t = 1; - int i = 0; - lua_pushnil( L ); - - while ( lua_next( L, t ) != 0 ) { - switch ( *type ) { - case RL_UNSIGNED_BYTE: - uByteArray[i] = lua_tointeger( L, -1 ); - break; - case RL_FLOAT: - floatArray[i] = lua_tointeger( L, -1 ); - break; - default: - break; - } - - lua_pop( L, 1 ); - i++; - } - - switch ( *type ) { - case RL_UNSIGNED_BYTE: - return uByteArray; - break; - case RL_FLOAT: - return floatArray; - break; - default: - return NULL; - break; - } -} - /* ## RLGL - Matrix operations */ @@ -1308,29 +1256,93 @@ int lrlglLoadVertexArray( lua_State *L ) { } /* -> vboId = RL.rlLoadVertexBuffer( Buffer{} buffer, int type, bool dynamic ) +> vboId = RL.rlLoadVertexBuffer( Buffer buffer, bool dynamic ) -Load a vertex buffer attribute. Type should be RL_UNSIGNED_BYTE or RL_FLOAT +Load a vertex buffer attribute - Failure return -1 - Success return int */ int lrlglLoadVertexBuffer( lua_State *L ) { - if ( !lua_istable( L, 1 ) || !lua_isnumber( L, 2 ) || !lua_isboolean( L, 3 ) ) { - TraceLog( state->logLevelInvalid, "%s", "Bad call of function. RL.rlLoadVertexBuffer( Buffer{} buffer, int type, bool dynamic )" ); + if ( !lua_isuserdata( L, 1 ) || !lua_isboolean( L, 2 ) ) { + TraceLog( state->logLevelInvalid, "%s", "Bad call of function. RL.rlLoadVertexBuffer( Buffer buffer, bool dynamic )" ); + lua_pushinteger( L, -1 ); + return 1; + } + Buffer *buffer = luaL_checkudata( L, 1, "Buffer" ); + bool dynamic = lua_tointeger( L, 2 ); + + lua_pushinteger( L, rlLoadVertexBuffer( buffer->data, buffer->size, dynamic ) ); + + return 1; +} + +/* +> vboId = RL.rlLoadVertexBufferElement( Buffer buffer, bool dynamic ) + +Load a new attributes element buffer + +- Failure return -1 +- Success return int +*/ +int lrlglLoadVertexBufferElement( lua_State *L ) { + if ( !lua_isuserdata( L, 1 ) || !lua_isboolean( L, 2 ) ) { + TraceLog( state->logLevelInvalid, "%s", "Bad call of function. RL.rlLoadVertexBufferElement( Buffer buffer, bool dynamic )" ); lua_pushinteger( L, -1 ); return 1; } - unsigned int size = 0; - int type = 0; - void *vertexBuffer = getVertexBuffer( L, &type, &size ); - bool dynamic = lua_tointeger( L, 3 ); + Buffer *buffer = luaL_checkudata( L, 1, "Buffer" ); + bool dynamic = lua_tointeger( L, 2 ); + + lua_pushinteger( L, rlLoadVertexBufferElement( buffer->data, buffer->size, dynamic ) ); + + return 1; +} + +/* +> success = RL.rlUpdateVertexBuffer( int bufferId, Buffer buffer, int offset ) + +Update GPU buffer with new data + +- Failure return false +- Success return true +*/ +int lrlglUpdateVertexBuffer( lua_State *L ) { + if ( !lua_isnumber( L, 1 ) || !lua_isuserdata( L, 2 ) || !lua_isnumber( L, 3 ) ) { + TraceLog( state->logLevelInvalid, "%s", "Bad call of function. RL.rlUpdateVertexBuffer( int bufferId, Buffer buffer, int offset )" ); + lua_pushboolean( L, false ); + return 1; + } + int bufferId = lua_tointeger( L, 1 ); + Buffer *buffer = luaL_checkudata( L, 2, "Buffer" ); + int offset = lua_tointeger( L, 3 ); + + rlUpdateVertexBuffer( bufferId, buffer->data, buffer->size, offset ); + lua_pushboolean( L, true ); + + return 1; +} - lua_pushinteger( L, rlLoadVertexBuffer( vertexBuffer, size, dynamic ) ); +/* +> success = RL.rlUpdateVertexBufferElements( int id, Buffer buffer, int offset ) + +Update vertex buffer elements with new data - if ( vertexBuffer != NULL ) { - MemFree( vertexBuffer ); +- Failure return false +- Success return true +*/ +int lrlglUpdateVertexBufferElements( lua_State *L ) { + if ( !lua_isnumber( L, 1 ) || !lua_isuserdata( L, 2 ) || !lua_isnumber( L, 3 ) ) { + TraceLog( state->logLevelInvalid, "%s", "Bad call of function. RL.rlUpdateVertexBufferElements( int id, Buffer buffer, int offset )" ); + lua_pushboolean( L, false ); + return 1; } + int bufferId = lua_tointeger( L, 1 ); + Buffer *buffer = luaL_checkudata( L, 2, "Buffer" ); + int offset = lua_tointeger( L, 3 ); + + rlUpdateVertexBufferElements( bufferId, buffer->data, buffer->size, offset ); + lua_pushboolean( L, true ); return 1; } @@ -1403,6 +1415,63 @@ int lrlglSetVertexAttribute( lua_State *L ) { return 1; } +/* +> success = RL.rlSetVertexAttributeDivisor( int index, int divisor ) + +Set vertex attribute divisor + +- Failure return false +- Success return true +*/ +int lrlglSetVertexAttributeDivisor( lua_State *L ) { + if ( !lua_isnumber( L, 1 ) || !lua_isnumber( L, 2 ) ) { + TraceLog( state->logLevelInvalid, "%s", "Bad call of function. RL.rlSetVertexAttributeDivisor( int index, int divisor )" ); + lua_pushboolean( L, false ); + return 1; + } + unsigned int index = (unsigned int)lua_tointeger( L, 1 ); + int divisor = lua_tointeger( L, 2 ); + + rlSetVertexAttributeDivisor( index, divisor ); + lua_pushboolean( L, true ); + + return 1; +} + +/* +> success = RL.rlSetVertexAttributeDefault( int locIndex, float{} value, int attribType ) + +Set vertex attribute default value + +- Failure return false +- Success return true +*/ +int lrlglSetVertexAttributeDefault( lua_State *L ) { + if ( !lua_isnumber( L, 1 ) || !lua_istable( L, 2 ) || !lua_isnumber( L, 3 ) ) { + TraceLog( state->logLevelInvalid, "%s", "Bad call of function. RL.rlSetVertexAttributeDefault( int locIndex, float{} value, int attribType )" ); + lua_pushboolean( L, false ); + return 1; + } + int locIndex = lua_tointeger( L, 1 ); + int attribType = lua_tointeger( L, 3 ); + int count = uluaGetTableLenIndex( L, 2 ); + float value[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; + + int t = 2; + int i = 0; + lua_pushnil( L ); + + while ( lua_next( L, t ) != 0 ) { + value[i] = lua_tonumber( L, -1 ); + lua_pop( L, 1 ); + i++; + } + rlSetVertexAttributeDefault( locIndex, value, attribType, count ); + lua_pushboolean( L, true ); + + return 1; +} + /* > success = RL.rlDrawVertexArray( int offset, int count ) @@ -1426,6 +1495,79 @@ int lrlglDrawVertexArray( lua_State *L ) { return 1; } +/* +> success = RL.rlDrawVertexArrayElements( int offset, int count, Buffer buffer ) + +Draw vertex array elements + +- Failure return false +- Success return true +*/ +int lrlglDrawVertexArrayElements( lua_State *L ) { + if ( !lua_isnumber( L, 1 ) || !lua_isnumber( L, 2 ) || !lua_isuserdata( L, 3 ) ) { + TraceLog( state->logLevelInvalid, "%s", "Bad call of function. RL.rlDrawVertexArrayElements( int offset, int count, Buffer buffer )" ); + lua_pushboolean( L, false ); + return 1; + } + int offset = lua_tointeger( L, 1 ); + int count = lua_tointeger( L, 2 ); + Buffer *buffer = luaL_checkudata( L, 3, "Buffer" ); + + rlDrawVertexArrayElements( offset, count, buffer->data ); + lua_pushboolean( L, true ); + + return 1; +} + +/* +> success = RL.rlDrawVertexArrayInstanced( int offset, int count, int instances ) + +Draw vertex array instanced + +- Failure return false +- Success return true +*/ +int lrlglDrawVertexArrayInstanced( lua_State *L ) { + if ( !lua_isnumber( L, 1 ) || !lua_isnumber( L, 2 ) || !lua_isnumber( L, 3 ) ) { + TraceLog( state->logLevelInvalid, "%s", "Bad call of function. RL.rlDrawVertexArrayInstanced( int offset, int count, int instances )" ); + lua_pushboolean( L, false ); + return 1; + } + int offset = lua_tointeger( L, 1 ); + int count = lua_tointeger( L, 2 ); + int instances = lua_tointeger( L, 3 ); + + rlDrawVertexArrayInstanced( offset, count, instances ); + lua_pushboolean( L, true ); + + return 1; +} + +/* +> success = RL.rlDrawVertexArrayElementsInstanced( int offset, int count, Buffer buffer, int instances ) + +Draw vertex array elements instanced + +- Failure return false +- Success return true +*/ +int lrlglDrawVertexArrayElementsInstanced( lua_State *L ) { + if ( !lua_isnumber( L, 1 ) || !lua_isnumber( L, 2 ) || !lua_isuserdata( L, 3 ) || !lua_isnumber( L, 4 ) ) { + TraceLog( state->logLevelInvalid, "%s", "Bad call of function. RL.rlDrawVertexArrayElementsInstanced( int offset, int count, Buffer buffer, int instances )" ); + lua_pushboolean( L, false ); + return 1; + } + int offset = lua_tointeger( L, 1 ); + int count = lua_tointeger( L, 2 ); + Buffer *buffer = luaL_checkudata( L, 3, "Buffer" ); + int instances = lua_tointeger( L, 4 ); + + rlDrawVertexArrayElementsInstanced( offset, count, buffer->data, instances ); + lua_pushboolean( L, true ); + + return 1; +} + /* ## RLGL - Textures management */ -- cgit v1.2.3