DrawMeshInstanced takes transforms as Buffer.

This commit is contained in:
jussi
2025-08-30 16:41:05 +03:00
parent 15deeccc4b
commit de672a85d2
9 changed files with 50 additions and 56 deletions

8
API.md
View File

@@ -5726,7 +5726,7 @@ Decode Base64 string data
> code = RL.ComputeCRC32( Buffer data ) > code = RL.ComputeCRC32( Buffer data )
Compute CRC32 hash code. Note! Buffer should be type BUFFER_UNSIGNED_CHAR Compute CRC32 hash code.
- Failure return false - Failure return false
- Success return int - Success return int
@@ -5735,7 +5735,7 @@ Compute CRC32 hash code. Note! Buffer should be type BUFFER_UNSIGNED_CHAR
> code = RL.ComputeMD5( Buffer data ) > code = RL.ComputeMD5( Buffer data )
Compute MD5 hash code, returns static int[4] (16 bytes). Note! Buffer should be type BUFFER_UNSIGNED_CHAR Compute MD5 hash code, returns static int[4] (16 bytes).
- Failure return false - Failure return false
- Success return int{4} - Success return int{4}
@@ -5744,7 +5744,7 @@ Compute MD5 hash code, returns static int[4] (16 bytes). Note! Buffer should be
> code = RL.ComputeSHA1( Buffer data ) > code = RL.ComputeSHA1( Buffer data )
Compute SHA1 hash code, returns static int[5] (20 bytes). Note! Buffer should be type BUFFER_UNSIGNED_CHAR Compute SHA1 hash code, returns static int[5] (20 bytes).
- Failure return false - Failure return false
- Success return int{5} - Success return int{5}
@@ -8746,7 +8746,7 @@ Draw a 3d mesh with material and transform
--- ---
> RL.DrawMeshInstanced( Mesh mesh, Material material, Matrix{} transforms, int instances ) > RL.DrawMeshInstanced( Mesh mesh, Material material, Buffer transforms, int instances )
Draw multiple mesh instances with material and different transforms Draw multiple mesh instances with material and different transforms

View File

@@ -33,6 +33,9 @@ List of some MISSING features that are planned to be included. For specific func
* v0.9 * v0.9
* v1.0
* raylib 6.0
## Usage ## Usage
Application needs 'main.lua' or 'main' file as entry point. ReiLua executable will first look it from same directory. Alternatively, path to the folder where "main.lua" is located can be given as argument. There are seven Lua functions that the framework will call, 'RL.init', 'RL.update', 'RL.draw', 'RL.event', 'RL.log', 'RL.exit' and 'RL.config'. Application needs 'main.lua' or 'main' file as entry point. ReiLua executable will first look it from same directory. Alternatively, path to the folder where "main.lua" is located can be given as argument. There are seven Lua functions that the framework will call, 'RL.init', 'RL.update', 'RL.draw', 'RL.event', 'RL.log', 'RL.exit' and 'RL.config'.

View File

@@ -2349,21 +2349,21 @@ function RL.EncodeDataBase64( data ) end
---@return any outputSize ---@return any outputSize
function RL.DecodeDataBase64( data ) end function RL.DecodeDataBase64( data ) end
---Compute CRC32 hash code. Note! Buffer should be type BUFFER_UNSIGNED_CHAR ---Compute CRC32 hash code.
---- Failure return false ---- Failure return false
---- Success return int ---- Success return int
---@param data any ---@param data any
---@return any code ---@return any code
function RL.ComputeCRC32( data ) end function RL.ComputeCRC32( data ) end
---Compute MD5 hash code, returns static int[4] (16 bytes). Note! Buffer should be type BUFFER_UNSIGNED_CHAR ---Compute MD5 hash code, returns static int[4] (16 bytes).
---- Failure return false ---- Failure return false
---- Success return int{4} ---- Success return int{4}
---@param data any ---@param data any
---@return any code ---@return any code
function RL.ComputeMD5( data ) end function RL.ComputeMD5( data ) end
---Compute SHA1 hash code, returns static int[5] (20 bytes). Note! Buffer should be type BUFFER_UNSIGNED_CHAR ---Compute SHA1 hash code, returns static int[5] (20 bytes).
---- Failure return false ---- Failure return false
---- Success return int{5} ---- Success return int{5}
---@param data any ---@param data any
@@ -5250,7 +5250,7 @@ function RL.DrawMesh( mesh, material, transform ) end
---Draw multiple mesh instances with material and different transforms ---Draw multiple mesh instances with material and different transforms
---@param mesh any ---@param mesh any
---@param material any ---@param material any
---@param transforms table ---@param transforms any
---@param instances integer ---@param instances integer
---@return any RL.DrawMeshInstanced ---@return any RL.DrawMeshInstanced
function RL.DrawMeshInstanced( mesh, material, transforms, instances ) end function RL.DrawMeshInstanced( mesh, material, transforms, instances ) end

View File

@@ -55,6 +55,7 @@ DETAILED CHANGES:
- FIXED: uluaGet* pops lua stack correctly when userdata given in table. - FIXED: uluaGet* pops lua stack correctly when userdata given in table.
- ADDED: MeasureTextBoxed. - ADDED: MeasureTextBoxed.
- CHANGE: DrawTextBoxedEx to DrawTextBoxed. - CHANGE: DrawTextBoxedEx to DrawTextBoxed.
- CHANGE: DrawMeshInstanced takes transforms as Buffer. Much better performance.
------------------------------------------------------------------------ ------------------------------------------------------------------------
Release: ReiLua version 0.8.0 Using Raylib 5.0 and Forked Raygui 4.0 Release: ReiLua version 0.8.0 Using Raylib 5.0 and Forked Raygui 4.0

View File

@@ -8,10 +8,14 @@
Modified by Jussi Viitala (@nullstare) for ReiLua style. Modified by Jussi Viitala (@nullstare) for ReiLua style.
]] ]]
package.path = package.path..";"..RL.GetBasePath().."../resources/lib/?.lua"
Matrix = require( "matrix" )
local MAX_INSTANCES = 10000 local MAX_INSTANCES = 10000
local cube local cube
local transforms = {} local transformsBuf
local camera local camera
local shader local shader
@@ -41,6 +45,9 @@ function RL.init()
-- Define mesh to be instanced -- Define mesh to be instanced
cube = RL.GenMeshCube( { 1, 1, 1 } ) cube = RL.GenMeshCube( { 1, 1, 1 } )
transformsBuf = RL.LoadBufferFormatted( MAX_INSTANCES * 16, RL.BUFFER_FLOAT, 0 )
local bufPos = 0
-- Translate and rotate cubes randomly -- Translate and rotate cubes randomly
for i = 1, MAX_INSTANCES do for i = 1, MAX_INSTANCES do
local translation = RL.MatrixTranslate( { math.random( -50, 50 ), math.random( -50, 50 ), math.random( -50, 50 ) } ) local translation = RL.MatrixTranslate( { math.random( -50, 50 ), math.random( -50, 50 ), math.random( -50, 50 ) } )
@@ -48,7 +55,8 @@ function RL.init()
local angle = math.rad( math.random( 0, 10 ) ) local angle = math.rad( math.random( 0, 10 ) )
local rotation = RL.MatrixRotate( axis, angle ) local rotation = RL.MatrixRotate( axis, angle )
table.insert( transforms, RL.MatrixMultiply( rotation, translation ) ) RL.SetBufferData( transformsBuf, bufPos, Matrix:temp( RL.MatrixMultiply( rotation, translation ) ):arr() )
bufPos = bufPos + 16
end end
-- Load lighting shader -- Load lighting shader
@@ -101,7 +109,7 @@ function RL.draw()
-- Draw meshes instanced using material containing instancing shader (RED + lighting), -- Draw meshes instanced using material containing instancing shader (RED + lighting),
-- transforms[] for the instances should be provided, they are dynamically -- transforms[] for the instances should be provided, they are dynamically
-- updated in GPU every frame, so we can animate the different mesh instances -- updated in GPU every frame, so we can animate the different mesh instances
RL.DrawMeshInstanced( cube, matInstances, transforms, MAX_INSTANCES ) RL.DrawMeshInstanced( cube, matInstances, transformsBuf, MAX_INSTANCES )
-- Draw cube mesh with default material (BLUE) -- Draw cube mesh with default material (BLUE)
RL.DrawMesh( cube, matDefault, RL.MatrixTranslate( { 10.0, 0.0, 0.0 } ) ) RL.DrawMesh( cube, matDefault, RL.MatrixTranslate( { 10.0, 0.0, 0.0 } ) )
@@ -113,4 +121,5 @@ end
function RL.exit() function RL.exit()
RL.UnloadMaterial( matInstances, true ) RL.UnloadMaterial( matInstances, true )
RL.UnloadMesh( cube ) RL.UnloadMesh( cube )
RL.UnloadBuffer( transformsBuf )
end end

View File

@@ -58,6 +58,15 @@ function Matrix:set( m )
self:copyMatrix( m ) self:copyMatrix( m )
end end
function Matrix:arr()
return {
self[1][1], self[2][1], self[3][1], self[4][1],
self[1][2], self[2][2], self[3][2], self[4][2],
self[1][3], self[2][3], self[3][3], self[4][3],
self[1][4], self[2][4], self[3][4], self[4][4],
}
end
function Matrix:serialize() function Matrix:serialize()
local str = { "Matrix:new({" } local str = { "Matrix:new({" }

View File

@@ -2201,7 +2201,7 @@ int lcoreDecodeDataBase64( lua_State* L ) {
/* /*
> code = RL.ComputeCRC32( Buffer data ) > code = RL.ComputeCRC32( Buffer data )
Compute CRC32 hash code. Note! Buffer should be type BUFFER_UNSIGNED_CHAR Compute CRC32 hash code.
- Failure return false - Failure return false
- Success return int - Success return int
@@ -2209,12 +2209,7 @@ Compute CRC32 hash code. Note! Buffer should be type BUFFER_UNSIGNED_CHAR
int lcoreComputeCRC32( lua_State* L ) { int lcoreComputeCRC32( lua_State* L ) {
Buffer* buffer = uluaGetBuffer( L, 1 ); Buffer* buffer = uluaGetBuffer( L, 1 );
if ( buffer->type == BUFFER_UNSIGNED_CHAR ) { lua_pushinteger( L, ComputeCRC32( buffer->data, buffer->size ) );
lua_pushinteger( L, ComputeCRC32( buffer->data, buffer->size ) );
}
else {
lua_pushboolean( L, false );
}
return 1; return 1;
} }
@@ -2222,7 +2217,7 @@ int lcoreComputeCRC32( lua_State* L ) {
/* /*
> code = RL.ComputeMD5( Buffer data ) > code = RL.ComputeMD5( Buffer data )
Compute MD5 hash code, returns static int[4] (16 bytes). Note! Buffer should be type BUFFER_UNSIGNED_CHAR Compute MD5 hash code, returns static int[4] (16 bytes).
- Failure return false - Failure return false
- Success return int{4} - Success return int{4}
@@ -2230,17 +2225,12 @@ Compute MD5 hash code, returns static int[4] (16 bytes). Note! Buffer should be
int lcoreComputeMD5( lua_State* L ) { int lcoreComputeMD5( lua_State* L ) {
Buffer* buffer = uluaGetBuffer( L, 1 ); Buffer* buffer = uluaGetBuffer( L, 1 );
if ( buffer->type == BUFFER_UNSIGNED_CHAR ) { unsigned int* code = ComputeMD5( buffer->data, buffer->size );
unsigned int* code = ComputeMD5( buffer->data, buffer->size ); lua_createtable( L, 4, 0 );
lua_createtable( L, 4, 0 );
for ( unsigned int i = 0; i < 4; i++ ) { for ( unsigned int i = 0; i < 4; i++ ) {
lua_pushinteger( L, code[i] ); lua_pushinteger( L, code[i] );
lua_rawseti( L, -2, i + 1 ); lua_rawseti( L, -2, i + 1 );
}
}
else {
lua_pushboolean( L, false );
} }
return 1; return 1;
@@ -2249,7 +2239,7 @@ int lcoreComputeMD5( lua_State* L ) {
/* /*
> code = RL.ComputeSHA1( Buffer data ) > code = RL.ComputeSHA1( Buffer data )
Compute SHA1 hash code, returns static int[5] (20 bytes). Note! Buffer should be type BUFFER_UNSIGNED_CHAR Compute SHA1 hash code, returns static int[5] (20 bytes).
- Failure return false - Failure return false
- Success return int{5} - Success return int{5}
@@ -2257,17 +2247,12 @@ Compute SHA1 hash code, returns static int[5] (20 bytes). Note! Buffer should be
int lcoreComputeSHA1( lua_State* L ) { int lcoreComputeSHA1( lua_State* L ) {
Buffer* buffer = uluaGetBuffer( L, 1 ); Buffer* buffer = uluaGetBuffer( L, 1 );
if ( buffer->type == BUFFER_UNSIGNED_CHAR ) { unsigned int* code = ComputeSHA1( buffer->data, buffer->size );
unsigned int* code = ComputeSHA1( buffer->data, buffer->size ); lua_createtable( L, 5, 0 );
lua_createtable( L, 5, 0 );
for ( unsigned int i = 0; i < 5; i++ ) { for ( unsigned int i = 0; i < 5; i++ ) {
lua_pushinteger( L, code[i] ); lua_pushinteger( L, code[i] );
lua_rawseti( L, -2, i + 1 ); lua_rawseti( L, -2, i + 1 );
}
}
else {
lua_pushboolean( L, false );
} }
return 1; return 1;

View File

@@ -1145,29 +1145,17 @@ int lmodelsDrawMesh( lua_State* L ) {
} }
/* /*
> RL.DrawMeshInstanced( Mesh mesh, Material material, Matrix{} transforms, int instances ) > RL.DrawMeshInstanced( Mesh mesh, Material material, Buffer transforms, int instances )
Draw multiple mesh instances with material and different transforms Draw multiple mesh instances with material and different transforms
*/ */
int lmodelsDrawMeshInstanced( lua_State* L ) { int lmodelsDrawMeshInstanced( lua_State* L ) {
Mesh* mesh = uluaGetMesh( L, 1 ); Mesh* mesh = uluaGetMesh( L, 1 );
Material* material = uluaGetMaterial( L, 2 ); Material* material = uluaGetMaterial( L, 2 );
luaL_checktype( L, 3, LUA_TTABLE ); Buffer* transforms = uluaGetBuffer( L, 3 );
int instances = luaL_checkinteger( L, 4 ); int instances = luaL_checkinteger( L, 4 );
Matrix transforms[ instances ]; DrawMeshInstanced( *mesh, *material, (Matrix*)transforms->data, instances );
int t = 3, i = 0;
lua_pushnil( L );
while ( lua_next( L, t ) != 0 ) {
if ( lua_istable( L, -1 ) ) {
transforms[i] = uluaGetMatrix( L, lua_gettop( L ) );
}
i++;
lua_pop( L, 1 );
}
DrawMeshInstanced( *mesh, *material, transforms, instances );
return 0; return 0;
} }

View File

@@ -99,7 +99,6 @@ int lcoreGetKeyScancode( lua_State* L ) {
Called when the window is resized. Type GLFW_WINDOW_SIZE_EVENT Called when the window is resized. Type GLFW_WINDOW_SIZE_EVENT
*/ */
static void windowSizeEvent( GLFWwindow* window, int width, int height ) { static void windowSizeEvent( GLFWwindow* window, int width, int height ) {
// GLFWwindowsizefun windowSizeEvent( GLFWwindow* window, int width, int height ) {
/* Pass through to raylib callback. */ /* Pass through to raylib callback. */
state->raylibWindowSizeCallback( window, width, height ); state->raylibWindowSizeCallback( window, width, height );