diff options
| author | jussi | 2022-05-16 13:44:10 +0300 |
|---|---|---|
| committer | jussi | 2022-05-16 13:44:10 +0300 |
| commit | 59ea29d8ff9dad751659a0a42d76a5534f7b4b97 (patch) | |
| tree | 96a901dd2f9884e901b78bdd93c62fe2fe5d9e44 | |
| parent | b034aa01dc0ca443eba7c7b12ead7732c3e32240 (diff) | |
| download | reilua-enhanced-59ea29d8ff9dad751659a0a42d76a5534f7b4b97.tar.gz reilua-enhanced-59ea29d8ff9dad751659a0a42d76a5534f7b4b97.tar.bz2 reilua-enhanced-59ea29d8ff9dad751659a0a42d76a5534f7b4b97.zip | |
New GenMeshCustom, UpdateMesh and lightmap example.
| -rw-r--r-- | API.md | 27 | ||||
| -rw-r--r-- | doc_parser.lua | 15 | ||||
| -rw-r--r-- | examples/heightmap/main.lua | 3 | ||||
| -rw-r--r-- | examples/lightmap/main.lua | 92 | ||||
| -rw-r--r-- | examples/resources/images/lightmap.png | bin | 0 -> 717 bytes | |||
| -rw-r--r-- | examples/resources/images/tile.png | bin | 0 -> 3043 bytes | |||
| -rw-r--r-- | examples/resources/shaders/glsl330/lightmap.fs | 22 | ||||
| -rw-r--r-- | examples/resources/shaders/glsl330/lightmap.vs | 31 | ||||
| -rw-r--r-- | include/models.h | 1 | ||||
| -rw-r--r-- | src/lua_core.c | 1 | ||||
| -rw-r--r-- | src/models.c | 435 |
11 files changed, 487 insertions, 140 deletions
@@ -635,6 +635,18 @@ int id. Defines 3d camera position/orientation int id. Vertex data defining a mesh +``` +mesh{} = { + vertices = { Vector3, ... }, + texcoords = { Vector2, ... }, + texcoords2 = { Vector2, ... }, + normals = { Vector3, ... }, + tangents = { Vector4, ... }, + colors = { Color, ... }, + indices = { int, ... }, +} +``` + --- > Material = MaterialId @@ -642,7 +654,7 @@ int id. Vertex data defining a mesh int id. Material type ``` -table = { +material{} = { shader = Shader, maps = { { @@ -3200,15 +3212,24 @@ Generate heightmap mesh from image data --- -> mesh = RL_GenMeshCustom( Vector3{} vertices, Vector2{} texCoords, Vector3{} normals ) +> mesh = RL_GenMeshCustom( Mesh{}, bool dynamic ) -Generate custom mesh +Generate custom mesh from vertex attribute data and uploads it into a VAO ( if supported ) and VBO - Failure return -1 - Success return int --- +> success = RL_UpdateMesh( Mesh{} ) + +Update mesh vertex data in GPU. ( Mainly intented to be used with custom meshes ) + +- Failure return false +- Success return true + +--- + > success = RL_UnloadMesh( Mesh mesh ) Unload mesh data from CPU and GPU diff --git a/doc_parser.lua b/doc_parser.lua index 19b69c9..a32ed7b 100644 --- a/doc_parser.lua +++ b/doc_parser.lua @@ -95,11 +95,22 @@ int id. Font type, includes texture and chars data\n\n---\n" ) apiFile:write( "\n> Camera = CameraId\n\ int id. Defines 3d camera position/orientation\n\n---\n" ) apiFile:write( "\n> Mesh = MeshId\n\ -int id. Vertex data defining a mesh\n\n---\n" ) +int id. Vertex data defining a mesh\n\ +```\ +mesh{} = {\ + vertices = { Vector3, ... },\ + texcoords = { Vector2, ... },\ + texcoords2 = { Vector2, ... },\ + normals = { Vector3, ... },\ + tangents = { Vector4, ... },\ + colors = { Color, ... },\ + indices = { int, ... },\ +}\ +```\n\n---\n" ) apiFile:write( "\n> Material = MaterialId\n\ int id. Material type\n\ ```\ -table = {\ +material{} = {\ shader = Shader,\ maps = {\ {\ diff --git a/examples/heightmap/main.lua b/examples/heightmap/main.lua index ecc6993..899ab72 100644 --- a/examples/heightmap/main.lua +++ b/examples/heightmap/main.lua @@ -7,6 +7,7 @@ local tilesetTex = -1 local heigthImage = -1 local mesh = -1 local material = -1 +local lightmap = -1 local grassRec = { 6 * TILE_SIZE, 0 * TILE_SIZE, TILE_SIZE, TILE_SIZE } local dirtRec = { 4 * TILE_SIZE, 0 * TILE_SIZE, TILE_SIZE, TILE_SIZE } @@ -64,6 +65,8 @@ function init() material = RL_LoadMaterialDefault() RL_SetTextureSource( TEXTURE_SOURCE_RENDER_TEXTURE ) + -- RL_GenTextureMipmaps( groundTexture ) + -- RL_SetTextureFilter( groundTexture, TEXTURE_FILTER_TRILINEAR ) RL_SetMaterialTexture( material, MATERIAL_MAP_ALBEDO, groundTexture ) RL_SetTextureSource( TEXTURE_SOURCE_TEXTURE ) diff --git a/examples/lightmap/main.lua b/examples/lightmap/main.lua new file mode 100644 index 0000000..eb81d96 --- /dev/null +++ b/examples/lightmap/main.lua @@ -0,0 +1,92 @@ +local PLANE_SIZE = 8 + +local monitor = 0 +local camera = -1 +local tileTexture = -1 +local mesh = -1 +local material = -1 +local lightmap = -1 +local shader = -1 + +local matrix = {} + +function init() + local mPos = RL_GetMonitorPosition( monitor ) + local mSize = RL_GetMonitorSize( monitor ) + local winSize = RL_GetWindowSize() + + RL_SetWindowState( FLAG_WINDOW_RESIZABLE ) + RL_SetWindowPosition( { mPos[1] + mSize[1] / 2 - winSize[1] / 2, mPos[2] + mSize[2] / 2 - winSize[2] / 2 } ) + + camera = RL_CreateCamera3D() + RL_SetCamera3DPosition( camera, { 0, 8, 16 } ) + RL_SetCamera3DTarget( camera, { 0, 0, 0 } ) + RL_SetCamera3DUp( camera, { 0, 2, 0 } ) + RL_SetCamera3DMode( camera, CAMERA_FREE ) + + local ts = PLANE_SIZE + local meshData = { + vertices = { { 0, 0, 0 }, { 0, 0, PLANE_SIZE }, { PLANE_SIZE, 0, PLANE_SIZE }, + { 0, 0, 0 }, { PLANE_SIZE, 0, PLANE_SIZE }, { PLANE_SIZE, 0, 0 } }, + texcoords = { { 0, 0 }, { 0, ts }, { ts, ts }, + { 0, 0 }, { ts, ts }, { ts, 0 } }, + texcoords2 = { { 0, 0 }, { 0, 1 }, { 1, 1 }, + { 0, 0 }, { 1, 1 }, { 1, 0 } }, + colors = { WHITE, WHITE, WHITE, + WHITE, WHITE, WHITE }, + normals = { { 0, 1, 0 }, { 0, 1, 0 }, { 0, 1, 0 }, + { 0, 1, 0 }, { 0, 1, 0 }, { 0, 1, 0 } }, + } + mesh = RL_GenMeshCustom( meshData, true ) + + -- local meshEdit = { + -- vertices = { { 0, 1, 0 }, { 0, 0, PLANE_SIZE }, { PLANE_SIZE, 0, PLANE_SIZE }, + -- { 0, 1, 0 }, { PLANE_SIZE, 0, PLANE_SIZE }, { PLANE_SIZE, 0, 0 } }, + -- } + -- RL_UpdateMesh( mesh, meshEdit ) + + tileTexture = RL_LoadTexture( RL_GetBasePath().."../resources/images/tile.png" ) + RL_GenTextureMipmaps( tileTexture ) + RL_SetTextureFilter( tileTexture, TEXTURE_FILTER_TRILINEAR ) + lightmap = RL_LoadTexture( RL_GetBasePath().."../resources/images/lightmap.png" ) + RL_GenTextureMipmaps( lightmap ) + RL_SetTextureFilter( lightmap, TEXTURE_FILTER_TRILINEAR ) + RL_SetTextureWrap( lightmap, TEXTURE_WRAP_CLAMP ) + + shader = RL_LoadShader( RL_GetBasePath().."../resources/shaders/glsl330/lightmap.vs", + RL_GetBasePath().."../resources/shaders/glsl330/lightmap.fs" ) + + local materialData = { + shader = shader, + maps = { + { + MATERIAL_MAP_ALBEDO, + { + texture = tileTexture, + color = WHITE, + value = 1.0, + }, + }, + { + MATERIAL_MAP_METALNESS, + { + texture = lightmap, + color = WHITE, + value = 1.0, + }, + }, + }, + } + material = RL_CreateMaterial( materialData ) + + matrix = RL_MatrixMultiply( RL_MatrixIdentity(), RL_MatrixTranslate( { -4, 0, -4 } ) ) +end + +function draw() + RL_ClearBackground( { 25, 50, 50 } ) + RL_UpdateCamera3D( camera ) + + RL_BeginMode3D( camera ) + RL_DrawMesh( mesh, material, matrix ) + RL_EndMode3D() +end diff --git a/examples/resources/images/lightmap.png b/examples/resources/images/lightmap.png Binary files differnew file mode 100644 index 0000000..35754e6 --- /dev/null +++ b/examples/resources/images/lightmap.png diff --git a/examples/resources/images/tile.png b/examples/resources/images/tile.png Binary files differnew file mode 100644 index 0000000..25aec8a --- /dev/null +++ b/examples/resources/images/tile.png diff --git a/examples/resources/shaders/glsl330/lightmap.fs b/examples/resources/shaders/glsl330/lightmap.fs new file mode 100644 index 0000000..aa821f3 --- /dev/null +++ b/examples/resources/shaders/glsl330/lightmap.fs @@ -0,0 +1,22 @@ +#version 330 +// Input vertex attributes (from vertex shader) +in vec2 fragTexCoord; +in vec2 fragTexCoord2; +in vec3 fragPosition; +in vec4 fragColor; +in vec3 fragNormal; + +// Input uniform values +uniform sampler2D texture0; +uniform sampler2D texture1; + +// Output fragment color +out vec4 finalColor; + +void main() { + // Texel color fetching from texture sampler + vec4 texelColor = texture( texture0, fragTexCoord ); + vec4 texelColor2 = texture( texture1, fragTexCoord2 ); + vec3 normal = normalize( fragNormal ); + finalColor = texelColor * texelColor2; +} diff --git a/examples/resources/shaders/glsl330/lightmap.vs b/examples/resources/shaders/glsl330/lightmap.vs new file mode 100644 index 0000000..dec46fe --- /dev/null +++ b/examples/resources/shaders/glsl330/lightmap.vs @@ -0,0 +1,31 @@ +#version 330 +// Input vertex attributes +in vec3 vertexPosition; +in vec2 vertexTexCoord; +in vec2 vertexTexCoord2; +in vec3 vertexNormal; +// in vec4 vertexColor; + +// Input uniform values +uniform mat4 mvp; +uniform mat4 matModel; +uniform mat4 matNormal; + +// Output vertex attributes (to fragment shader) +out vec3 fragPosition; +out vec2 fragTexCoord; +out vec2 fragTexCoord2; +// out vec4 fragColor; +out vec3 fragNormal; + +void main() { + // Send vertex attributes to fragment shader + fragPosition = vec3( matModel * vec4( vertexPosition, 1.0 ) ); + fragTexCoord = vertexTexCoord; + fragTexCoord2 = vertexTexCoord2; + // fragColor = vertexColor; + fragNormal = normalize( vec3( matNormal * vec4( vertexNormal, 1.0 ) ) ); + + // Calculate final vertex position + gl_Position = mvp * vec4( vertexPosition, 1.0 ); +} diff --git a/include/models.h b/include/models.h index d002807..15dae09 100644 --- a/include/models.h +++ b/include/models.h @@ -30,6 +30,7 @@ int lmodelsGenMeshTorus( lua_State *L ); int lmodelsGenMeshKnot( lua_State *L ); int lmodelsGenMeshHeightmap( lua_State *L ); int lmodelsGenMeshCustom( lua_State *L ); +int lmodelsUpdateMesh( lua_State *L ); int lmodelsUnloadMesh( lua_State *L ); int lmodelsDrawMesh( lua_State *L ); int lmodelsDrawMeshInstanced( lua_State *L ); diff --git a/src/lua_core.c b/src/lua_core.c index da385da..21788ba 100644 --- a/src/lua_core.c +++ b/src/lua_core.c @@ -771,6 +771,7 @@ void luaRegister() { lua_register( L, "RL_GenMeshKnot", lmodelsGenMeshKnot ); lua_register( L, "RL_GenMeshHeightmap", lmodelsGenMeshHeightmap ); lua_register( L, "RL_GenMeshCustom", lmodelsGenMeshCustom ); + lua_register( L, "RL_UpdateMesh", lmodelsUpdateMesh ); lua_register( L, "RL_UnloadMesh", lmodelsUnloadMesh ); lua_register( L, "RL_DrawMesh", lmodelsDrawMesh ); lua_register( L, "RL_DrawMeshInstanced", lmodelsDrawMeshInstanced ); diff --git a/src/models.c b/src/models.c index 3fe2e45..fab32ab 100644 --- a/src/models.c +++ b/src/models.c @@ -106,6 +106,20 @@ static bool validAnimation( size_t id ) { } } +static int newMesh() { + int i = 0; + + for ( i = 0; i < state->meshCount; i++ ) { + if ( state->meshes[i] == NULL ) { + break; + } + } + state->meshes[i] = malloc( sizeof( Mesh ) ); + checkMeshRealloc( i ); + + return i; +} + /* ## Models - Basic */ @@ -683,14 +697,8 @@ int lmodelsGenMeshPoly( lua_State *L ) { } float radius = lua_tonumber( L, -1 ); int sides = lua_tointeger( L, -2 ); - int i = 0; + int i = newMesh(); - for ( i = 0; i < state->meshCount; i++ ) { - if ( state->meshes[i] == NULL ) { - break; - } - } - state->meshes[i] = malloc( sizeof( Mesh ) ); *state->meshes[i] = GenMeshPoly( sides, radius ); lua_pushinteger( L, i ); checkMeshRealloc( i ); @@ -716,14 +724,8 @@ int lmodelsGenMeshPlane( lua_State *L ) { int resX = lua_tointeger( L, -2 ); float length = lua_tonumber( L, -3 ); float width = lua_tonumber( L, -4 ); - int i = 0; + int i = newMesh(); - for ( i = 0; i < state->meshCount; i++ ) { - if ( state->meshes[i] == NULL ) { - break; - } - } - state->meshes[i] = malloc( sizeof( Mesh ) ); *state->meshes[i] = GenMeshPlane( width, length, resX, resZ ); lua_pushinteger( L, i ); checkMeshRealloc( i ); @@ -746,14 +748,8 @@ int lmodelsGenMeshCube( lua_State *L ) { return 1; } Vector3 size = uluaGetVector3( L ); - int i = 0; + int i = newMesh(); - for ( i = 0; i < state->meshCount; i++ ) { - if ( state->meshes[i] == NULL ) { - break; - } - } - state->meshes[i] = malloc( sizeof( Mesh ) ); *state->meshes[i] = GenMeshCube( size.x, size.y, size.z ); lua_pushinteger( L, i ); checkMeshRealloc( i ); @@ -778,14 +774,8 @@ int lmodelsGenMeshSphere( lua_State *L ) { int slices = lua_tointeger( L, -1 ); int rings = lua_tointeger( L, -2 ); float radius = lua_tonumber( L, -3 ); - int i = 0; + int i = newMesh(); - for ( i = 0; i < state->meshCount; i++ ) { - if ( state->meshes[i] == NULL ) { - break; - } - } - state->meshes[i] = malloc( sizeof( Mesh ) ); *state->meshes[i] = GenMeshSphere( radius, rings, slices ); lua_pushinteger( L, i ); checkMeshRealloc( i ); @@ -810,14 +800,8 @@ int lmodelsGenMeshCylinder( lua_State *L ) { int slices = lua_tointeger( L, -1 ); float height = lua_tonumber( L, -2 ); float radius = lua_tonumber( L, -3 ); - int i = 0; + int i = newMesh(); - for ( i = 0; i < state->meshCount; i++ ) { - if ( state->meshes[i] == NULL ) { - break; - } - } - state->meshes[i] = malloc( sizeof( Mesh ) ); *state->meshes[i] = GenMeshCylinder( radius, height, slices); lua_pushinteger( L, i ); checkMeshRealloc( i ); @@ -842,14 +826,8 @@ int lmodelsGenMeshCone( lua_State *L ) { int slices = lua_tointeger( L, -1 ); float height = lua_tonumber( L, -2 ); float radius = lua_tonumber( L, -3 ); - int i = 0; - - for ( i = 0; i < state->meshCount; i++ ) { - if ( state->meshes[i] == NULL ) { - break; - } - } - state->meshes[i] = malloc( sizeof( Mesh ) ); + int i = newMesh(); + *state->meshes[i] = GenMeshCone( radius, height, slices); lua_pushinteger( L, i ); checkMeshRealloc( i ); @@ -875,14 +853,8 @@ int lmodelsGenMeshTorus( lua_State *L ) { int radSeg = lua_tointeger( L, -2 ); float size = lua_tonumber( L, -3 ); float radius = lua_tonumber( L, -4 ); - int i = 0; - - for ( i = 0; i < state->meshCount; i++ ) { - if ( state->meshes[i] == NULL ) { - break; - } - } - state->meshes[i] = malloc( sizeof( Mesh ) ); + int i = newMesh(); + *state->meshes[i] = GenMeshTorus( radius, size, radSeg, sides ); lua_pushinteger( L, i ); checkMeshRealloc( i ); @@ -908,14 +880,8 @@ int lmodelsGenMeshKnot( lua_State *L ) { int radSeg = lua_tointeger( L, -2 ); float size = lua_tonumber( L, -3 ); float radius = lua_tonumber( L, -4 ); - int i = 0; - - for ( i = 0; i < state->meshCount; i++ ) { - if ( state->meshes[i] == NULL ) { - break; - } - } - state->meshes[i] = malloc( sizeof( Mesh ) ); + int i = newMesh(); + *state->meshes[i] = GenMeshKnot( radius, size, radSeg, sides ); lua_pushinteger( L, i ); checkMeshRealloc( i ); @@ -945,16 +911,9 @@ int lmodelsGenMeshHeightmap( lua_State *L ) { lua_pushboolean( L, false ); return 1; } - Image *heightmap = state->images[ imageId ]; - int i = 0; - - for ( i = 0; i < state->meshCount; i++ ) { - if ( state->meshes[i] == NULL ) { - break; - } - } - state->meshes[i] = malloc( sizeof( Mesh ) ); + int i = newMesh(); + *state->meshes[i] = GenMeshHeightmap( *heightmap, size ); lua_pushinteger( L, i ); checkMeshRealloc( i ); @@ -963,100 +922,306 @@ int lmodelsGenMeshHeightmap( lua_State *L ) { } /* -> mesh = RL_GenMeshCustom( Vector3{} vertices, Vector2{} texCoords, Vector3{} normals ) +> mesh = RL_GenMeshCustom( Mesh{}, bool dynamic ) -Generate custom mesh +Generate custom mesh from vertex attribute data and uploads it into a VAO ( if supported ) and VBO - Failure return -1 - Success return int */ int lmodelsGenMeshCustom( lua_State *L ) { - if ( !lua_istable( L, -3 ) || !lua_istable( L, -2 ) || !lua_istable( L, -1 ) ) { - TraceLog( LOG_WARNING, "%s", "Bad call of function. RL_GenMeshCustom( Vector3{} vertices, Vector2{} texCoords, Vector3{} normals )" ); + if ( !lua_istable( L, -2 ) || !lua_isboolean( L, -1 ) ) { + TraceLog( LOG_WARNING, "%s", "Bad call of function. RL_GenMeshCustom( Mesh{}, bool dynamic )" ); lua_pushinteger( L, -1 ); return 1; } Mesh mesh = { 0 }; - size_t len = uluaGetTableLen( L ); - mesh.vertexCount = len * 3; - mesh.triangleCount = len; + bool dynamic = lua_toboolean( L, -1 ); + lua_pop( L, 1 ); - mesh.vertices = (float*)MemAlloc( mesh.vertexCount * 3 * sizeof(float) ); - mesh.texcoords = (float*)MemAlloc( mesh.vertexCount * 2 * sizeof(float) ); - mesh.normals = (float*)MemAlloc( mesh.vertexCount * 3 * sizeof(float) ); - mesh.colors = (unsigned char*)MemAlloc( mesh.vertexCount * 4 * sizeof(unsigned char) ); + int t = lua_gettop( L ); + lua_pushnil( L ); - /* Normals. */ + while ( lua_next( L, t ) != 0 ) { + if ( strcmp( "vertices", (char*)lua_tostring( L, -2 ) ) == 0 && lua_istable( L, -1 ) ) { + size_t len = uluaGetTableLen( L ); - int t = lua_gettop( L ), i = 0; - lua_pushnil( L ); + mesh.vertexCount = len; + mesh.triangleCount = len / 3; + mesh.vertices = (float*)MemAlloc( len * 3 * sizeof(float) ); - while ( lua_next( L, t ) != 0 ) { - if ( lua_istable( L, -1 ) ) { - Vector3 vec = uluaGetVector3( L ); - mesh.normals[(i*3)+0] = vec.x; - mesh.normals[(i*3)+1] = vec.y; - mesh.normals[(i*3)+2] = vec.z; - } - i++; - lua_pop( L, 1 ); - } - lua_pop( L, 1 ); + int t2 = lua_gettop( L ); + int i = 0; + lua_pushnil( L ); - /* TexCoords. */ + while ( lua_next( L, t2 ) != 0 ) { + Vector3 vec = uluaGetVector3( L ); - t = lua_gettop( L ); - i = 0; - lua_pushnil( L ); + mesh.vertices[(i*3)+0] = vec.x; + mesh.vertices[(i*3)+1] = vec.y; + mesh.vertices[(i*3)+2] = vec.z; + i++; + lua_pop( L, 1 ); + } + } + else if ( strcmp( "texcoords", (char*)lua_tostring( L, -2 ) ) == 0 && lua_istable( L, -1 ) ) { + size_t len = uluaGetTableLen( L ); - while ( lua_next( L, t ) != 0 ) { - if ( lua_istable( L, -1 ) ) { - Vector2 vec = uluaGetVector2( L ); - mesh.texcoords[(i*2)+0] = vec.x; - mesh.texcoords[(i*2)+1] = vec.y; - } - i++; - lua_pop( L, 1 ); - } - lua_pop( L, 1 ); + mesh.texcoords = (float*)MemAlloc( len * 2 * sizeof(float) ); - /* Vertices. */ + int t2 = lua_gettop( L ); + int i = 0; + lua_pushnil( L ); - t = lua_gettop( L ); - i = 0; - lua_pushnil( L ); + while ( lua_next( L, t2 ) != 0 ) { + Vector2 vec = uluaGetVector2( L ); + + mesh.texcoords[(i*2)+0] = vec.x; + mesh.texcoords[(i*2)+1] = vec.y; + i++; + lua_pop( L, 1 ); + } + } + else if ( strcmp( "texcoords2", (char*)lua_tostring( L, -2 ) ) == 0 && lua_istable( L, -1 ) ) { + size_t len = uluaGetTableLen( L ); + + mesh.texcoords2 = (float*)MemAlloc( len * 2 * sizeof(float) ); + + int t2 = lua_gettop( L ); + int i = 0; + lua_pushnil( L ); + + while ( lua_next( L, t2 ) != 0 ) { + Vector2 vec = uluaGetVector2( L ); + + mesh.texcoords2[(i*2)+0] = vec.x; + mesh.texcoords2[(i*2)+1] = vec.y; + i++; + lua_pop( L, 1 ); + } + } + else if ( strcmp( "normals", (char*)lua_tostring( L, -2 ) ) == 0 && lua_istable( L, -1 ) ) { + size_t len = uluaGetTableLen( L ); + + mesh.normals = (float*)MemAlloc( len * 3 * sizeof(float) ); + + int t2 = lua_gettop( L ); + int i = 0; + lua_pushnil( L ); + + while ( lua_next( L, t2 ) != 0 ) { + Vector3 vec = uluaGetVector3( L ); + + mesh.normals[(i*3)+0] = vec.x; + mesh.normals[(i*3)+1] = vec.y; + mesh.normals[(i*3)+2] = vec.z; + i++; + lua_pop( L, 1 ); + } + } + else if ( strcmp( "tangents", (char*)lua_tostring( L, -2 ) ) == 0 && lua_istable( L, -1 ) ) { + size_t len = uluaGetTableLen( L ); + + mesh.tangents = (float*)MemAlloc( len * 4 * sizeof(float) ); + + int t2 = lua_gettop( L ); + int i = 0; + lua_pushnil( L ); + + while ( lua_next( L, t2 ) != 0 ) { + Vector4 vec = uluaGetVector4( L ); + + mesh.tangents[(i*4)+0] = vec.x; + mesh.tangents[(i*4)+1] = vec.y; + mesh.tangents[(i*4)+2] = vec.z; + mesh.tangents[(i*4)+3] = vec.w; + i++; + lua_pop( L, 1 ); + } + } + else if ( strcmp( "colors", (char*)lua_tostring( L, -2 ) ) == 0 && lua_istable( L, -1 ) ) { + size_t len = uluaGetTableLen( L ); + + mesh.colors = (unsigned char*)MemAlloc( len * 4 * sizeof(unsigned char) ); + + int t2 = lua_gettop( L ); + int i = 0; + lua_pushnil( L ); + + while ( lua_next( L, t2 ) != 0 ) { + Color color = uluaGetColor( L ); + + mesh.colors[(i*4)+0] = color.r; + mesh.colors[(i*4)+1] = color.g; + mesh.colors[(i*4)+2] = color.b; + mesh.colors[(i*4)+3] = color.a; + i++; + lua_pop( L, 1 ); + } + } + else if ( strcmp( "indices", (char*)lua_tostring( L, -2 ) ) == 0 && lua_istable( L, -1 ) ) { + size_t len = uluaGetTableLen( L ); + + mesh.indices = (unsigned short*)MemAlloc( len * sizeof(unsigned short) ); + + int t2 = lua_gettop( L ); + int i = 0; + lua_pushnil( L ); + + while ( lua_next( L, t2 ) != 0 ) { + mesh.indices[i] = (unsigned short)lua_tointeger( L, -1 ); + i++; + lua_pop( L, 1 ); + } + } + lua_pop( L, 1 ); + } + UploadMesh( &mesh, dynamic ); + + int i = newMesh(); + + *state->meshes[i] = mesh; + lua_pushinteger( L, i ); + checkMeshRealloc( i ); + + return 1; +} + +/* +> success = RL_UpdateMesh( Mesh{} ) + +Update mesh vertex data in GPU. ( Mainly intented to be used with custom meshes ) + +- Failure return false +- Success return true +*/ +int lmodelsUpdateMesh( lua_State *L ) { + if ( !lua_isnumber( L, -2 ) || !lua_istable( L, -1 ) ) { + TraceLog( LOG_WARNING, "%s", "Bad call of function. RL_UpdateMesh( Mesh{} )" ); + lua_pushboolean( L, false ); + return 1; + } + size_t meshId = lua_tointeger( L, -1 ); + + if ( !validMesh( meshId ) ) { + lua_pushboolean( L, false ); + return 1; + } + Mesh *mesh = state->meshes[ meshId ]; + + int t = lua_gettop( L ); + lua_pushnil( L ); while ( lua_next( L, t ) != 0 ) { - if ( lua_istable( L, -1 ) ) { - Vector3 vec = uluaGetVector3( L ); - mesh.vertices[(i*3)+0] = vec.x; - mesh.vertices[(i*3)+1] = vec.y; - mesh.vertices[(i*3)+2] = vec.z; - - mesh.colors[(i*4)+0] = (unsigned char)255; - mesh.colors[(i*4)+1] = (unsigned char)255; - mesh.colors[(i*4)+2] = (unsigned char)255; - mesh.colors[(i*4)+3] = (unsigned char)255; - } - i++; - lua_pop( L, 1 ); - } - lua_pop( L, 1 ); + if ( strcmp( "vertices", (char*)lua_tostring( L, -2 ) ) == 0 && lua_istable( L, -1 ) ) { + size_t len = uluaGetTableLen( L ); + Vector3 data[ len ]; - UploadMesh( &mesh, false ); + int t2 = lua_gettop( L ); + int i = 0; + lua_pushnil( L ); - int j = 0; + while ( lua_next( L, t2 ) != 0 && i < mesh->vertexCount ) { + data[i] = uluaGetVector3( L ); + i++; + lua_pop( L, 1 ); + } + UpdateMeshBuffer( *mesh, 0, (void*)data, len * 3 * sizeof( float ), 0 ); + } + else if ( strcmp( "texcoords", (char*)lua_tostring( L, -2 ) ) == 0 && lua_istable( L, -1 ) ) { + size_t len = uluaGetTableLen( L ); + Vector2 data[ len ]; - for ( j = 0; j < state->meshCount; j++ ) { - if ( state->meshes[j] == NULL ) { - break; + int t2 = lua_gettop( L ); + int i = 0; + lua_pushnil( L ); + + while ( lua_next( L, t2 ) != 0 ) { + data[i] = uluaGetVector2( L ); + i++; + lua_pop( L, 1 ); + } + UpdateMeshBuffer( *mesh, 1, (void*)data, len * 2 * sizeof( float ), 0 ); + } + else if ( strcmp( "texcoords2", (char*)lua_tostring( L, -2 ) ) == 0 && lua_istable( L, -1 ) ) { + size_t len = uluaGetTableLen( L ); + Vector2 data[ len ]; + + int t2 = lua_gettop( L ); + int i = 0; + lua_pushnil( L ); + + while ( lua_next( L, t2 ) != 0 ) { + data[i] = uluaGetVector2( L ); + i++; + lua_pop( L, 1 ); + } + UpdateMeshBuffer( *mesh, 5, (void*)data, len * 2 * sizeof( float ), 0 ); } + else if ( strcmp( "normals", (char*)lua_tostring( L, -2 ) ) == 0 && lua_istable( L, -1 ) ) { + size_t len = uluaGetTableLen( L ); + Vector3 data[ len ]; + + int t2 = lua_gettop( L ); + int i = 0; + lua_pushnil( L ); + + while ( lua_next( L, t2 ) != 0 ) { + data[i] = uluaGetVector3( L ); + i++; + lua_pop( L, 1 ); + } + UpdateMeshBuffer( *mesh, 2, (void*)data, len * 3 * sizeof( float ), 0 ); + } + else if ( strcmp( "tangents", (char*)lua_tostring( L, -2 ) ) == 0 && lua_istable( L, -1 ) ) { + size_t len = uluaGetTableLen( L ); + Vector4 data[ len ]; + + int t2 = lua_gettop( L ); + int i = 0; + lua_pushnil( L ); + + while ( lua_next( L, t2 ) != 0 ) { + data[i] = uluaGetVector4( L ); + i++; + lua_pop( L, 1 ); + } + UpdateMeshBuffer( *mesh, 4, (void*)data, len * 4 * sizeof( float ), 0 ); + } + else if ( strcmp( "colors", (char*)lua_tostring( L, -2 ) ) == 0 && lua_istable( L, -1 ) ) { + size_t len = uluaGetTableLen( L ); + Color data[ len ]; + + int t2 = lua_gettop( L ); + int i = 0; + lua_pushnil( L ); + + while ( lua_next( L, t2 ) != 0 ) { + data[i] = uluaGetColor( L ); + i++; + lua_pop( L, 1 ); + } + UpdateMeshBuffer( *mesh, 3, (void*)data, len * 4 * sizeof(unsigned char), 0 ); + } + else if ( strcmp( "indices", (char*)lua_tostring( L, -2 ) ) == 0 && lua_istable( L, -1 ) ) { + size_t len = uluaGetTableLen( L ); + unsigned short data[ len ]; + + int t2 = lua_gettop( L ); + int i = 0; + lua_pushnil( L ); + + while ( lua_next( L, t2 ) != 0 ) { + data[i] = (unsigned short)lua_tointeger( L, -1 ); + i++; + lua_pop( L, 1 ); + } + UpdateMeshBuffer( *mesh, 6, (void*)data, len * sizeof(unsigned short), 0 ); + } + lua_pop( L, 1 ); } - state->meshes[j] = malloc( sizeof( Mesh ) ); - *state->meshes[j] = mesh; - lua_pushinteger( L, j ); - checkMeshRealloc( j ); + lua_pushboolean( L, true ); return 1; } |
