summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--API.md27
-rw-r--r--doc_parser.lua15
-rw-r--r--examples/heightmap/main.lua3
-rw-r--r--examples/lightmap/main.lua92
-rw-r--r--examples/resources/images/lightmap.pngbin0 -> 717 bytes
-rw-r--r--examples/resources/images/tile.pngbin0 -> 3043 bytes
-rw-r--r--examples/resources/shaders/glsl330/lightmap.fs22
-rw-r--r--examples/resources/shaders/glsl330/lightmap.vs31
-rw-r--r--include/models.h1
-rw-r--r--src/lua_core.c1
-rw-r--r--src/models.c435
11 files changed, 487 insertions, 140 deletions
diff --git a/API.md b/API.md
index b4e23f4..486e1cf 100644
--- a/API.md
+++ b/API.md
@@ -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
new file mode 100644
index 0000000..35754e6
--- /dev/null
+++ b/examples/resources/images/lightmap.png
Binary files differ
diff --git a/examples/resources/images/tile.png b/examples/resources/images/tile.png
new file mode 100644
index 0000000..25aec8a
--- /dev/null
+++ b/examples/resources/images/tile.png
Binary files differ
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;
}