diff options
37 files changed, 853 insertions, 646 deletions
@@ -45,16 +45,6 @@ This function will be called on program close. Cleanup could be done here. Arguments are stored in 'RL.arg' array. -## Default objects - -> RL.defaultFont - -Default Font object - -> RL.defaultMaterial - -Default Material object - ## Types Raylib structs in Lua @@ -1804,6 +1794,20 @@ Load Buffer. Type should be one of the Buffer types --- +> RL.UnloadBuffer( Buffer buffer ) + +Unload buffer data + +--- + +> enabled = RL.IsGCUnloadEnabled() + +Check if Lua garbage collection is set to unload object data + +- Success return bool + +--- + ## Core - Cursor --- @@ -1918,6 +1922,14 @@ NOTE: Set nil if no shader --- +> isReady = RL.IsShaderReady( Shader shader ) + +Check if a shader is ready + +- Success return bool + +--- + > RL.BeginShaderMode( Shader shader ) Begin custom shader drawing @@ -1986,6 +1998,12 @@ NOTE: Even one value should be in table --- +> RL.UnloadShader( Shader shader ) + +Unload shader from GPU memory (VRAM) + +--- + ## Core - Input-related Keyboard --- @@ -3106,6 +3124,20 @@ Load image from screen buffer and (screenshot) --- +> isReady = RL.IsImageReady( Image image ) + +Check if an image is ready + +- Success return bool + +--- + +> RL.UnloadImage( Image image ) + +Unload image from CPU memory (RAM) + +--- + > success = RL.ExportImage( Image image, string fileName ) Export image data to file, returns true on success @@ -3543,6 +3575,26 @@ Check if a texture is ready --- +> RL.UnloadTexture( Texture texture ) + +Unload texture from GPU memory (VRAM) + +--- + +> isReady = RL.IsRenderTextureReady( RenderTexture target ) + +Check if a render texture is ready + +- Success return bool + +--- + +> RL.UnloadRenderTexture( RenderTexture target ) + +Unload render texture from GPU memory (VRAM) + +--- + > RL.UpdateTexture( Texture texture, int{} pixels ) Update GPU texture with new data @@ -3801,7 +3853,7 @@ Get pixel data size in bytes for certain format > RL.GetFontDefault() -Get the default Font +Get the default Font. Return as lightuserdata --- @@ -3831,6 +3883,20 @@ Load font from Image ( XNA style) --- +> isReady = RL.IsFontReady( Font font ) + +Check if a font is ready + +- Success return bool + +--- + +> RL.UnloadFont( Font font ) + +Unload font from GPU memory (VRAM) + +--- + ## Text - Draw --- @@ -3891,7 +3957,7 @@ Get font padding around the glyph characters > texture = RL.GetFontTexture( Font font ) -Get font texture atlas containing the glyphs. +Get font texture atlas containing the glyphs. Returns as lightuserdata - Success return Texture @@ -4106,6 +4172,12 @@ Note! Mainly intented to be used with custom meshes. --- +> RL.UnloadMesh( Mesh mesh ) + +Unload mesh data from CPU and GPU + +--- + > RL.DrawMesh( Mesh mesh, Material material, Matrix transform ) Draw a 3d mesh with material and transform @@ -4154,9 +4226,17 @@ Compute mesh tangents --- +> material = RL.GetMaterialDefault() + +Default material for reference. Return as lightuserdata + +- Success return Material + +--- + > material = RL.LoadMaterialDefault() -Load default material +Load default material as new object - Success return Material @@ -4170,6 +4250,20 @@ Load material from table. See material table definition --- +> isReady = RL.IsMaterialReady( Material material ) + +Check if a material is ready + +- Success return bool + +--- + +> RL.UnloadMaterial( Material material ) + +Unload material from GPU memory (VRAM) + +--- + > RL.SetMaterialTexture( Material material, int mapType, Texture texture ) Set texture for a material map type (MATERIAL_MAP_ALBEDO, MATERIAL_MAP_METALNESS...) @@ -4228,7 +4322,7 @@ Get color from material map type Get material shader -- Success return Shader. Returns as lightuserdata +- Success return Shader. Return as lightuserdata --- @@ -4261,6 +4355,20 @@ Load model from generated mesh (Default material) --- +> isReady = RL.IsModelReady( Model model ) + +Check if a model is ready + +- Success return bool + +--- + +> RL.UnloadModel( Model model ) + +Unload model (including meshes) from memory (RAM and/or VRAM) + +--- + > RL.DrawModel( Model model, Vector3 position, float scale, Color tint ) Draw a model (With texture if set) @@ -4460,6 +4568,14 @@ Load wave data from file --- +> isReady = RL.IsWaveReady( Wave wave ) + +Checks if wave data is ready + +- Success return bool + +--- + > sound = RL.LoadSoundFromWave( Wave wave ) Load sound from wave data @@ -4468,6 +4584,26 @@ Load sound from wave data --- +> isReady = RL.IsSoundReady( Sound sound ) + +Checks if a sound is ready + +- Success return bool + +--- + +> RL.UnloadWave( Wave wave ) + +Unload wave data + +--- + +> RL.UnloadSound( Sound sound ) + +Unload sound + +--- + > success = RL.ExportWave( Wave wave, string fileName ) Export wave data to file, returns true on success @@ -4570,6 +4706,20 @@ Load music stream from file --- +> isReady = RL.IsMusicReady( Music music ) + +Checks if a music stream is ready + +- Success return bool + +--- + +> RL.UnloadMusicStream( Music music ) + +Unload music stream + +--- + > RL.PlayMusicStream( Music music ) Start music playing diff --git a/CMakeLists.txt b/CMakeLists.txt index 3b4b51d..0827e0b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,6 +8,7 @@ set( CMAKE_C_STANDARD 99 ) # Requires C99 standard option( SHARED "Build using dynamic libraries." off ) option( LUAJIT "Use LuaJIT." off ) +option( GC_UNLOAD "Lua garbage collector unloads objects. If off, object unloading should be handled manually." on ) if( NOT CMAKE_BUILD_TYPE ) SET( CMAKE_BUILD_TYPE Release CACHE STRING @@ -15,6 +16,10 @@ if( NOT CMAKE_BUILD_TYPE ) FORCE ) endif() +if( GC_UNLOAD ) + set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DGC_UNLOAD" ) +endif() + file( GLOB SOURCES src/*.c ) include_directories( include ) diff --git a/ReiLua_API.lua b/ReiLua_API.lua index fa5fef6..7996ad3 100644 --- a/ReiLua_API.lua +++ b/ReiLua_API.lua @@ -945,6 +945,16 @@ function RL.OpenURL( url ) end ---@return any buffer function RL.LoadBuffer( buffer, type ) end +---Unload buffer data +---@param buffer any +---@return any RL.UnloadBuffer +function RL.UnloadBuffer( buffer ) end + +---Check if Lua garbage collection is set to unload object data +---- Success return bool +---@return any enabled +function RL.IsGCUnloadEnabled() end + -- Core - Cursor ---Shows cursor @@ -1026,6 +1036,12 @@ function RL.LoadShader( vsFileName, fsFileName ) end ---@return any shader function RL.LoadShaderFromMemory( vsCode, fsCode ) end +---Check if a shader is ready +---- Success return bool +---@param shader any +---@return any isReady +function RL.IsShaderReady( shader ) end + ---Begin custom shader drawing ---@param shader any ---@return any RL.BeginShaderMode @@ -1096,6 +1112,11 @@ function RL.SetShaderValue( shader, locIndex, values, uniformType ) end ---@return any RL.SetShaderValueV function RL.SetShaderValueV( shader, locIndex, values, uniformType, count ) end +---Unload shader from GPU memory (VRAM) +---@param shader any +---@return any RL.UnloadShader +function RL.UnloadShader( shader ) end + -- Core - Input-related Keyboard ---Detect if a key has been pressed once @@ -2095,6 +2116,17 @@ function RL.LoadImageFromTexture( texture ) end ---@return any image function RL.LoadImageFromScreen() end +---Check if an image is ready +---- Success return bool +---@param image any +---@return any isReady +function RL.IsImageReady( image ) end + +---Unload image from CPU memory (RAM) +---@param image any +---@return any RL.UnloadImage +function RL.UnloadImage( image ) end + ---Export image data to file, returns true on success ---- Success return bool ---@param image any @@ -2507,6 +2539,22 @@ function RL.LoadRenderTextureFromData( renderTextureData ) end ---@return any isReady function RL.IsTextureReady( texture ) end +---Unload texture from GPU memory (VRAM) +---@param texture any +---@return any RL.UnloadTexture +function RL.UnloadTexture( texture ) end + +---Check if a render texture is ready +---- Success return bool +---@param target any +---@return any isReady +function RL.IsRenderTextureReady( target ) end + +---Unload render texture from GPU memory (VRAM) +---@param target any +---@return any RL.UnloadRenderTexture +function RL.UnloadRenderTexture( target ) end + ---Update GPU texture with new data ---NOTE! Should be TEXTURE_TYPE_TEXTURE. Pixel should be in format { { 255, 255, 255, 255 }... } depending on the pixel format ---@param texture any @@ -2731,7 +2779,7 @@ function RL.GetPixelDataSize( width, height, format ) end -- Text - Loading ----Get the default Font +---Get the default Font. Return as lightuserdata ---@return any RL.GetFontDefault function RL.GetFontDefault() end @@ -2759,6 +2807,17 @@ function RL.LoadFontEx( fileName, fontSize, fontChars ) end ---@return any font function RL.LoadFontFromImage( image, key, firstChar ) end +---Check if a font is ready +---- Success return bool +---@param font any +---@return any isReady +function RL.IsFontReady( font ) end + +---Unload font from GPU memory (VRAM) +---@param font any +---@return any RL.UnloadFont +function RL.UnloadFont( font ) end + -- Text - Draw ---Draw current FPS @@ -2817,7 +2876,7 @@ function RL.GetFontGlyphCount( font ) end ---@return any glyphPadding function RL.GetFontGlyphPadding( font ) end ----Get font texture atlas containing the glyphs. +---Get font texture atlas containing the glyphs. Returns as lightuserdata ---- Success return Texture ---@param font any ---@return any texture @@ -3068,6 +3127,11 @@ function RL.GenMeshCustom( meshData, dynamic ) end ---@return any RL.UpdateMesh function RL.UpdateMesh( mesh, meshData ) end +---Unload mesh data from CPU and GPU +---@param mesh any +---@return any RL.UnloadMesh +function RL.UnloadMesh( mesh ) end + ---Draw a 3d mesh with material and transform ---@param mesh any ---@param material any @@ -3112,7 +3176,12 @@ function RL.GenMeshTangents( mesh ) end -- Models - Material ----Load default material +---Default material for reference. Return as lightuserdata +---- Success return Material +---@return any material +function RL.GetMaterialDefault() end + +---Load default material as new object ---- Success return Material ---@return any material function RL.LoadMaterialDefault() end @@ -3123,6 +3192,17 @@ function RL.LoadMaterialDefault() end ---@return any material function RL.CreateMaterial( materialData ) end +---Check if a material is ready +---- Success return bool +---@param material any +---@return any isReady +function RL.IsMaterialReady( material ) end + +---Unload material from GPU memory (VRAM) +---@param material any +---@return any RL.UnloadMaterial +function RL.UnloadMaterial( material ) end + ---Set texture for a material map type (MATERIAL_MAP_ALBEDO, MATERIAL_MAP_METALNESS...) ---@param material any ---@param mapType integer @@ -3178,7 +3258,7 @@ function RL.GetMaterialColor( material, mapType ) end function RL.GetMaterialValue( material, mapType ) end ---Get material shader ----- Success return Shader. Returns as lightuserdata +---- Success return Shader. Return as lightuserdata ---@param material any ---@return any shader function RL.GetMaterialShader( material ) end @@ -3204,6 +3284,17 @@ function RL.LoadModel( fileName ) end ---@return any model function RL.LoadModelFromMesh( mesh ) end +---Check if a model is ready +---- Success return bool +---@param model any +---@return any isReady +function RL.IsModelReady( model ) end + +---Unload model (including meshes) from memory (RAM and/or VRAM) +---@param model any +---@return any RL.UnloadModel +function RL.UnloadModel( model ) end + ---Draw a model (With texture if set) ---@param model any ---@param position table @@ -3406,12 +3497,34 @@ function RL.LoadSound( fileName ) end ---@return any wave function RL.LoadWave( fileName ) end +---Checks if wave data is ready +---- Success return bool +---@param wave any +---@return any isReady +function RL.IsWaveReady( wave ) end + ---Load sound from wave data ---- Success return Sound ---@param wave any ---@return any sound function RL.LoadSoundFromWave( wave ) end +---Checks if a sound is ready +---- Success return bool +---@param sound any +---@return any isReady +function RL.IsSoundReady( sound ) end + +---Unload wave data +---@param wave any +---@return any RL.UnloadWave +function RL.UnloadWave( wave ) end + +---Unload sound +---@param sound any +---@return any RL.UnloadSound +function RL.UnloadSound( sound ) end + ---Export wave data to file, returns true on success ---- Success return bool ---@param wave any @@ -3501,6 +3614,17 @@ function RL.WaveCrop( wave, initSample, finalSample ) end ---@return any music function RL.LoadMusicStream( fileName ) end +---Checks if a music stream is ready +---- Success return bool +---@param music any +---@return any isReady +function RL.IsMusicReady( music ) end + +---Unload music stream +---@param music any +---@return any RL.UnloadMusicStream +function RL.UnloadMusicStream( music ) end + ---Start music playing ---@param music any ---@return any RL.PlayMusicStream @@ -3,25 +3,26 @@ Release: ReiLua version 0.6.0 Using Raylib 4.5 ------------------------------------------------------------------------ KEY CHANGES: - CHANGED: Switch from ID based objects to userdata. - - REMOVED: Unload* functions since unloading is now handled by Lua garbage collection. + - CHANGED: Object unloading is handled by Lua garbage collection by default. - CHANGED: Rely mostly on luaL_check* functions for arg checking. - CHANGED: ModelAnimations are changed to separate ModelAnimation types as in Raylib. - - ADDED: LoadTextureFromData. - - ADDED: LoadRenderTextureFromData. - ADDED: Userdata objects can be referenced with lightuserdata. + - ADDED: GC_UNLOAD build time define for enabling/disabling Lua garbage collection for objects. + Can be checked with IsGCUnloadEnabled DETAILED CHANGES: - CHANGED: GenImageColor now takes Vector2 as size. - - REMOVED: UnloadImage. - - REMOVED: UnloadTexture. - - REMOVED: GetTextureType and texture type DEFINES. + - REMOVED: GetTextureType and texture type enums. - ADDED: GetRenderTextureTexture and GetRenderTextureDepthTexture. - REMOVED: UnloadCamera2D and UnloadCamera3D. - - REMOVED: UnloadShader. - - REMOVED: UnloadFont. - ADDED: LoadFontEx takes also fontChars. - - REMOVED: UnloadWave and UnloadSound. - - REMOVED: UnloadMesh, UnloadMaterial, UnloadModel and UnloadModelAnimations. + - ADDED: LoadTextureFromData. + - ADDED: LoadRenderTextureFromData. + - ADDED: IsRenderTextureReady, IsMaterialReady, IsFontReady, IsModelReady, IsShaderReady, + IsImageReady, IsWaveReady, IsSoundReady and IsMusicReady. + - ADDED: UnloadBuffer. + - ADDED: GetMaterialDefault returns lightuserdata reference to default material. + - REMOVED: Some examples. ------------------------------------------------------------------------ Release: ReiLua version 0.5.0 Using Raylib 4.5 @@ -5,11 +5,6 @@ Backlog { * rlgl * Shaders management * Compute shader management - * Platformer example physics process for true framerate independence. - * Extend color lib functionality. - * Global variable descriptions for API. - - * IsWaveReady and other Is* ready functions. * Text * Codepoints? * Audio @@ -18,8 +13,15 @@ Backlog { * Compression/Encoding functionality. * SetWindowIcons. * Models - * LoadMaterials (Load materials from model file) - * LoadMaterialsFromModel (Could then for example edit and set back to model) + * LoadMaterials (Load materials from model file). + * LoadMaterialsFromModel (Could then for example edit and set back to model). + + * Extend color lib functionality. + * Global variable descriptions for API. + + * Examples + * Improve Dungeon crawler example by generating custom mesh instead of drawing 3D quads. + * Platformer example physics process for true framerate independence. } Bugs { @@ -125,16 +125,6 @@ luaApiFile:write( apiFile:write( "\n## Arguments\n" ) apiFile:write( "\nArguments are stored in 'RL.arg' array.\n" ) --- Default objects. - -apiFile:write( "\n## Default objects\n" ) -apiFile:write( "\n> RL.defaultFont\n\nDefault Font object\n" ) -apiFile:write( "\n> RL.defaultMaterial\n\nDefault Material object\n" ) - --- luaApiFile:write( "\n--Default objects\n\n" ) --- luaApiFile:write( "--Default Font object\nRL.defaultFont = RL.GetFontDefault()\n" ) --- luaApiFile:write( "--Default Material object\nRL.defaultMaterial\n" ) - -- Types. apiFile:write( "\n## Types\n\ diff --git a/examples/ReiLuaGui_test/main.lua b/examples/ReiLuaGui_test/main.lua deleted file mode 100644 index 8ea6563..0000000 --- a/examples/ReiLuaGui_test/main.lua +++ /dev/null @@ -1,160 +0,0 @@ -package.path = package.path..";"..RL.GetBasePath().."../resources/lib/?.lua" - -util = require( "utillib" ) -Vec2 = require( "vector2" ) -Rect = require( "rectangle" ) -Color = require( "color" ) -Gui = require( "gui" ) - -local container = {} --- local circleTexture = RL.LoadTexture( RL.GetBasePath().."../resources/images/circle.png" ) -local circleTexture = RL.LoadTexture( RL.GetBasePath().."../resources/images/plain-circle.png" ) -local checkTexture = RL.LoadTexture( RL.GetBasePath().."../resources/images/check-mark.png" ) -local borderTexture = RL.LoadTexture( RL.GetBasePath().."../resources/images/ui_border.png" ) -local textInput - -RL.GenTextureMipmaps( circleTexture ) -RL.GenTextureMipmaps( checkTexture ) -RL.SetTextureFilter( circleTexture, RL.TEXTURE_FILTER_TRILINEAR ) -RL.SetTextureFilter( checkTexture, RL.TEXTURE_FILTER_TRILINEAR ) - -function initGui() - -- local label = Gui.label:new( { text = "Dog", bounds = { 32, 32, 96, 96 }, drawBounds = true, Haling = Gui.ALING.CENTER, Valing = Gui.ALING.TOP } ) - local panel = Gui.element:new( { bounds = Rect:new( 60, 32, 128, 128 ), drawBounds = true } ) - - container = Gui.container:new( { - bounds = Rect:new( 256, 120, 128, 128 ), - -- spacing = 14, - -- drawScrollRect = true, - -- HAling = Gui.ALING.RIGHT, - -- HAling = Gui.ALING.CENTER, - -- type = Gui.CONTAINER.HORIZONTAL, - -- VAling = Gui.ALING.CENTER, - -- type = Gui.CONTAINER.GRID, - -- columns = 2, - -- rows = 2, - scrollable = true, - showScrollbar = true, - } ) - - -- local container = Gui.container:new( { bounds = Rect:new( 256, 120, 128, 128 ), drawBounds = true, type = Gui.CONTAINER.HORIZONTAL } ) - - -- local itemBounds = { 0, 0, container.bounds.width - container.spacing * 2, 36 } - local itemBounds = Rect:new( 0, 0, 64, 36 ) - - local dog = Gui.element:new( { - bounds = Rect:new( 0, 0, 128, 36 ), - onClicked = function() panel:setPosition( Vec2:new( 290, 120 ) ) end, - onMouseOver = function( self ) self.items[1].color = RL.RED end, - notMouseOver = function( self ) self.items[1].color = RL.BLACK end, - drawBounds = true, - } ) - - dog:add( Gui.text:new( { text = "Dog", HAling = Gui.ALING.LEFT } ) ) - - dog:add( Gui.texture:new( { - bounds = dog.bounds:clone(), - texture = borderTexture, - HAling = Gui.ALING.CENTER, - VAling = Gui.ALING.CENTER, - visible = true, - nPatchInfo = { source = { 0, 0, 24, 24 }, left = 8, top = 8, right = 8, bottom = 8, layout = RL.NPATCH_NINE_PATCH }, - } ) ) - - dog:add( Gui.texture:new( { bounds = Rect:new( 0, 0, 24, 24 ), texture = circleTexture, HAling = Gui.ALING.RIGHT, color = Color:new( 150, 150, 255 ) } ) ) - dog:add( Gui.texture:new( { bounds = Rect:new( 0, 0, 24, 24 ), texture = checkTexture, HAling = Gui.ALING.RIGHT, visible = true } ) ) - -- dog:add( Gui.text:new( { text = "Cat", HAling = Gui.ALING.RIGHT } ) ) - -- dog:add( Gui.shape:new( { bounds = Rect:new( 0, 0, 128, 36 ), shape = Gui.SHAPE.RECTANGLE_ROUNDED, color = Color:new( GREEN ) } ) ) - - container:add( dog ) - - -- container:add( Gui.element:new( { - -- text = "Cat", - -- bounds = Rect:new( 0, 0, 78, 24 ), - -- onClicked = function() panel:setPosition( Vec2:new( 290, 120 ) ) end, - -- onMouseOver = function( self ) self.color = RED end, - -- notMouseOver = function( self ) self.color = BLACK end, - -- drawBounds = true, - -- } ) ) - - for i = 1, 5 do - local element = Gui.element:new( { - bounds = Rect:new( 0, 0, 120, 30 ), - onClicked = function() panel:setPosition( Vec2:new( 340, 380 ) ) end, - onMouseOver = function( self ) self.color = Color:new( RL.DARKBLUE ) end, - notMouseOver = function( self ) self.color = Color:new( RL.LIGHTGRAY ) end, - drawBounds = true, - } ) - - element:add( Gui.text:new( { text = "Giraffe" } ) ) - container:add( element ) - end - - local container2 = Gui.container:new( { - bounds = Rect:new( 0, 0, 154, 64 ), - type = Gui.CONTAINER.HORIZONTAL, - } ) - - local element = Gui.element:new( { - bounds = itemBounds:clone(), - onMouseOver = function( self ) self.color = Color:new( RL.DARKBLUE ) end, - notMouseOver = function( self ) self.color = Color:new( RL.LIGHTGRAY ) end, - drawBounds = true, - } ) - element:add( Gui.text:new( { text = "Dog" } ) ) - container2:add( element ) - - element = Gui.element:new( { - bounds = Rect:new( 0, 0, 78, 24 ), - -- bounds = Rect:new( 0, 0, 78, 64 ), - onMouseOver = function( self ) self.color = Color:new( RL.DARKBLUE ) end, - notMouseOver = function( self ) self.color = Color:new( RL.LIGHTGRAY ) end, - drawBounds = true, - } ) - element:add( Gui.text:new( { text = "Cat" } ) ) - container2:add( element ) - - container:add( container2 ) - - panel:set2Top() - - -- Text input. - - textInput = Gui.element:new( { - bounds = Rect:new( 64, 360, 300, 32 ), - drawBounds = true, - color = Color:new( RL.LIGHTGRAY ), - onClicked = function() Gui.setInputFocus( textInput ) end, - inputFocus = function() textInput.color = Color:new( RL.BLUE ) end, - -- inputFocus = function() container:delete() end, - -- inputFocus = function() panel:set2Back() end, - inputUnfocus = function() textInput.color = Color:new( RL.LIGHTGRAY ) end, - } ) - - textInput:add( Gui.text:new( { text = "", maxTextLen = 16, allowLineBreak = false } ) ) -end - -function RL.init() - local monitor = 0 - local mPos = RL.GetMonitorPosition( monitor ) - local mSize = RL.GetMonitorSize( monitor ) - winSize = RL.GetScreenSize() - - RL.SetWindowTitle( "ReiLuaGui Test" ) - RL.SetWindowState( RL.FLAG_WINDOW_RESIZABLE ) - RL.SetWindowState( RL.FLAG_VSYNC_HINT ) - RL.SetWindowSize( winSize ) - RL.SetWindowPosition( { mPos[1] + mSize[1] / 2 - winSize[1] / 2, mPos[2] + mSize[2] / 2 - winSize[2] / 2 } ) - - initGui() -end - -function RL.process( delta ) - Gui.process( Vec2:new( RL.GetMousePosition() ) ) -end - -function RL.draw() - RL.ClearBackground( RL.RAYWHITE ) - - Gui.draw() -end diff --git a/examples/basic_lighting/main.lua b/examples/basic_lighting/main.lua index d85291e..0d7b77c 100644 --- a/examples/basic_lighting/main.lua +++ b/examples/basic_lighting/main.lua @@ -136,5 +136,5 @@ function RL.draw() camera:endMode3D() - RL.DrawText( RL.defaultFont, "Use keys [Y][R][G][B] to toggle lights", { 10, 10 }, 20, 4, RL.DARKGRAY ) + RL.DrawText( RL.GetFontDefault(), "Use keys [Y][R][G][B] to toggle lights", { 10, 10 }, 20, 4, RL.DARKGRAY ) end diff --git a/examples/bunnymark/main.lua b/examples/bunnymark/main.lua index 9f877e6..03f53ad 100644 --- a/examples/bunnymark/main.lua +++ b/examples/bunnymark/main.lua @@ -83,7 +83,7 @@ function RL.draw() end RL.DrawRectangle( { 0, 0, screenWidth, 40 }, RL.BLACK) - RL.DrawText( RL.defaultFont, "bunnies: " .. #bunnies, { 120, 10 }, 20, 2, RL.GREEN ) - RL.DrawText( RL.defaultFont, "batched draw calls: " .. math.ceil( 1 + #bunnies / MAX_BATCH_ELEMENTS ), { 320, 10 }, 20, 2, RL.RED ) + RL.DrawText( RL.GetFontDefault(), "bunnies: " .. #bunnies, { 120, 10 }, 20, 2, RL.GREEN ) + RL.DrawText( RL.GetFontDefault(), "batched draw calls: " .. math.ceil( 1 + #bunnies / MAX_BATCH_ELEMENTS ), { 320, 10 }, 20, 2, RL.RED ) RL.DrawFPS( { 10, 10 } ) end diff --git a/examples/events/main.lua b/examples/events/main.lua index 8a8fb34..052edc1 100644 --- a/examples/events/main.lua +++ b/examples/events/main.lua @@ -100,5 +100,5 @@ function RL.draw() RL.ClearBackground( RL.RED ) end - RL.DrawText( RL.defaultFont, text, textPos, 20, 2, RL.BLACK ) + RL.DrawText( RL.GetFontDefault(), text, textPos, 20, 2, RL.BLACK ) end diff --git a/examples/free_camera3d/main.lua b/examples/free_camera3d/main.lua index 6478ebb..4881cc5 100644 --- a/examples/free_camera3d/main.lua +++ b/examples/free_camera3d/main.lua @@ -68,5 +68,6 @@ function RL.draw() text = text.."\nPress T to toggle target visible.\nVisible: "..tostring( targetVisible ) - RL.DrawText( RL.defaultFont, text, { 16, 16 }, 30, 4, RL.WHITE ) + -- RL.DrawText( RL.defaultFont, text, { 16, 16 }, 30, 4, RL.WHITE ) + RL.DrawText( RL.GetFontDefault(), text, { 16, 16 }, 30, 4, RL.WHITE ) end diff --git a/examples/gui/main.lua b/examples/gui/main.lua index 01e063e..371d35d 100644 --- a/examples/gui/main.lua +++ b/examples/gui/main.lua @@ -26,7 +26,7 @@ function RL.init() local mSize = RL.GetMonitorSize( monitor ) local winSize = { 1920, 1080 } - RL.GuiSetFont( RL.defaultFont ) + RL.GuiSetFont( RL.GetFontDefault() ) RL.SetWindowState( RL.FLAG_WINDOW_RESIZABLE ) RL.SetWindowState( RL.FLAG_VSYNC_HINT ) RL.SetWindowSize( winSize ) diff --git a/examples/image_draw/main.lua b/examples/image_draw/main.lua index ac8e7e6..ba8881a 100644 --- a/examples/image_draw/main.lua +++ b/examples/image_draw/main.lua @@ -1,9 +1,9 @@ local monitor = 0 -local texture = -1 -local image = -1 -local catImage = -1 -local catCopy = -1 -local textImage = -1 +local texture = nil +local image = nil +local catImage = nil +local catCopy = nil +local textImage = nil function RL.init() local mPos = RL.GetMonitorPosition( monitor ) @@ -24,14 +24,14 @@ function RL.init() RL.ImageDrawRectangle( image, { 120, 64, 32, 64 }, RL.BLUE ) RL.ImageDrawRectangleLines( image, { 160, 64, 32, 64 }, 2.0, RL.BLUE ) RL.ImageDraw( image, catImage, { 143, 25, 230, 250 }, { 200, 200, 230, 250 }, RL.WHITE ) - RL.ImageDrawTextEx( image, RL.defaultFont, "Hello", { 300, 32 }, 48.0, 1.0, RL.WHITE ) + RL.ImageDrawTextEx( image, RL.GetFontDefault(), "Hello", { 300, 32 }, 48.0, 1.0, RL.WHITE ) local src = { 80, 70, 96, 96 } catCopy = RL.ImageFromImage( catImage, src ) RL.ImageDraw( image, catCopy, src, { 600, 200, src[3], src[4] }, RL.WHITE ) - textImage = RL.ImageText( RL.defaultFont, "Cat", 10, 4, RL.WHITE ) + textImage = RL.ImageText( RL.GetFontDefault(), "Cat", 10, 4, RL.WHITE ) local imageSize = RL.GetImageSize( textImage ) RL.ImageDraw( image, textImage, { 0, 0, imageSize[1], imageSize[2] }, { 250, 40, imageSize[1], imageSize[2] }, RL.WHITE ) diff --git a/examples/iqm_test/main.lua b/examples/iqm_test/main.lua index 229c1c4..22341a4 100644 --- a/examples/iqm_test/main.lua +++ b/examples/iqm_test/main.lua @@ -80,7 +80,7 @@ function RL.draw() RL.DrawModelEx( model, { 0, 0, 0 }, { 1.0, 0.0, 0.0 }, -90.0, { 1.0, 1.0, 1.0 }, RL.WHITE ) RL.EndMode3D() - RL.DrawText( RL.defaultFont, + RL.DrawText( RL.GetFontDefault(), "Enter: Change animation\ Space: Play animation\ Up arrow: Inreace animation speed\ diff --git a/examples/lightmap/main.lua b/examples/lightmap/main.lua index 6d946a5..56b6772 100644 --- a/examples/lightmap/main.lua +++ b/examples/lightmap/main.lua @@ -5,12 +5,12 @@ Cam3D = require( "camera3d" ) 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 camera = {} +local tileTexture = nil +local mesh = nil +local material = nil +local lightmap = nil +local shader = nil local matrix = {} @@ -80,8 +80,6 @@ function RL.init() } material = RL.CreateMaterial( materialData ) - print( "material", material ) - matrix = RL.MatrixMultiply( RL.MatrixIdentity(), RL.MatrixTranslate( { -4, 0, -4 } ) ) end @@ -99,18 +97,8 @@ end function RL.draw() RL.ClearBackground( { 25, 50, 50 } ) - -- RL.UpdateCamera3D( camera, RL.CAMERA_ORBITAL ) - -- RL.UpdateCamera3D( camera, RL.CAMERA_FREE ) - -- RL.UpdateCamera3D( camera, RL.CAMERA_FIRST_PERSON ) camera:beginMode3D() RL.DrawMesh( mesh, material, matrix ) camera:endMode3D() end - -function RL.exit() - material = nil - collectgarbage( "collect" ) - tileTexture = nil - collectgarbage( "collect" ) -end
\ No newline at end of file diff --git a/examples/pixelated/main.lua b/examples/pixelated/main.lua deleted file mode 100644 index 174b2b9..0000000 --- a/examples/pixelated/main.lua +++ /dev/null @@ -1,54 +0,0 @@ -local tex = -1 -local pos = { 32, 32 } -local speed = 60.0 -local monitor = 0 -local mPos = RL.GetMonitorPosition( monitor ) -local mSize = RL.GetMonitorSize( monitor ) -local framebuffer = nil -local res = { 320, 180 } -local scale = 5 -local winSize = { res[1] * scale, res[2] * scale } - -function RL.init() - RL.SetWindowState( RL.FLAG_WINDOW_RESIZABLE ) - RL.SetWindowState( RL.FLAG_VSYNC_HINT ) - RL.SetWindowPosition( { mPos[1] + mSize[1] / 2 - winSize[1] / 2, mPos[2] + mSize[2] / 2 - winSize[2] / 2 } ) - RL.SetWindowSize( winSize ) - tex = RL.LoadTexture( RL.GetBasePath().."../resources/images/cat.png" ) - -- Create framebuffer. - framebuffer = RL.LoadRenderTexture( res ) -end - -function RL.process( delta ) - if RL.IsKeyDown( RL.KEY_RIGHT ) then - pos[1] = pos[1] + delta * speed - elseif RL.IsKeyDown( RL.KEY_LEFT ) then - pos[1] = pos[1] - delta * speed - end - - if RL.IsKeyDown( RL.KEY_UP ) then - pos[2] = pos[2] - delta * speed - elseif RL.IsKeyDown( RL.KEY_DOWN ) then - pos[2] = pos[2] + delta * speed - end - - if RL.IsWindowResized() then - winSize = RL.GetScreenSize() - end -end - -function RL.draw() - RL.ClearBackground( { 0, 0, 0 } ) - - RL.BeginTextureMode( framebuffer ) - RL.ClearBackground( { 100, 150, 100 } ) - RL.DrawPixel( { 100, 100 }, { 255, 50, 100 } ) - RL.DrawLine( { 120, 100 }, { 140, 150 }, 2.4, { 255, 150, 255 } ) - RL.DrawRectangle( { 200, 120, 40, 50 }, { 100, 170, 255 } ) - RL.DrawTexturePro( tex, { 166, 138, 128, 128 }, { pos[1], pos[2], 128, 128 }, { 16, 16 }, 0.0, RL.WHITE ) - RL.DrawText( RL.defaultFont, "Cat MIAU!!", { 16, 32 }, 10, 1, { 255, 180, 155 } ) - RL.DrawTriangle( { 0, 32 }, { 32, 16 }, { 0, 0 }, RL.RED ) - RL.EndTextureMode() - - RL.DrawTexturePro( RL.GetRenderTextureTexture( framebuffer ), { 0, 0, res[1], -res[2] }, { 0, 0, winSize[1], winSize[2] }, { 0, 0 }, 0.0, { 255, 255, 255 } ) -end diff --git a/examples/point_triangle_collision/main.lua b/examples/point_triangle_collision/main.lua deleted file mode 100644 index 9a302dc..0000000 --- a/examples/point_triangle_collision/main.lua +++ /dev/null @@ -1,120 +0,0 @@ -package.path = package.path..";"..RL.GetBasePath().."../resources/lib/?.lua" - -util = require "utillib" -Vec2 = require "vector2" -Vec3 = require "vector3" - -local MOVE_SPEED = 0.5 - -local monitor = 0 -local camera = -1 -local tri = { - a = Vec3:new( 0, 0, 0 ), - -- a = Vec3:new( 0, 1, 0 ), - b = Vec3:new( 0, 0, 2 ), - c = Vec3:new( 1, 0, 0 ), - normal = Vec3:new( 0, 0, 0 ), -} -local point = { - pos = Vec3:new( 0.2, 0.3, 0.2 ), - radius = 0.05, - lineLen = 0.5, - color = RL.RED, -} - -local debugText = "" - -local function calcNormal( tri ) - tri.normal = Vec3:new( RL.Vector3Normalize( RL.Vector3CrossProduct( tri.b - tri.a, tri.c - tri.a ) ) ) -end - -function RL.init() - local mPos = RL.GetMonitorPosition( monitor ) - local mSize = RL.GetMonitorSize( monitor ) - local winSize = { 1920, 1080 } - - RL.SetWindowState( RL.FLAG_WINDOW_RESIZABLE ) - RL.SetWindowState( RL.FLAG_VSYNC_HINT ) - RL.SetWindowPosition( { mPos[1] + mSize[1] / 2 - winSize[1] / 2, mPos[2] + mSize[2] / 2 - winSize[2] / 2 } ) - RL.SetWindowSize( winSize ) - camera = RL.CreateCamera3D() - RL.SetCamera3DPosition( camera, { 0, 1, 2 } ) - RL.SetCamera3DTarget( camera, { 0, 0, 0 } ) - RL.SetCamera3DUp( camera, { 0, 1, 0 } ) - - calcNormal( tri ) -end - -local function checkCollisionPointTriangle( p, a, b, c, n ) - local result = Vec3:new( 0, 0, 0 ) - - local v0 = Vec3:new( b.x - a.x, b.y - a.y, b.z - a.z ) -- Vector3Subtract( b, a ) - local v1 = Vec3:new( c.x - a.x, c.y - a.y, c.z - a.z ) -- Vector3Subtract( c, a ) - local v2 = Vec3:new( p.x - a.x, p.y - a.y, p.z - a.z ) -- Vector3Subtract( p, a ) - local d00 = v0.x * v0.x + v0.y * v0.y + v0.z * v0.z -- Vector3DotProduct( v0, v0 ) - local d01 = v0.x * v1.x + v0.y * v1.y + v0.z * v1.z -- Vector3DotProduct( v0, v1 ) - local d11 = v1.x * v1.x + v1.y * v1.y + v1.z * v1.z -- Vector3DotProduct( v1, v1 ) - local d20 = v2.x * v0.x + v2.y * v0.y + v2.z * v0.z -- Vector3DotProduct( v2, v0 ) - local d21 = v2.x * v1.x + v2.y * v1.y + v2.z * v1.z -- Vector3DotProduct( v2, v1 ) - - local denom = d00 * d11 - d01 * d01 - local distance = v2.x * n.x + v2.y * n.y + v2.z * n.z -- Vector3DotProduct( v2, n ) - - debugText = debugText.."distance "..distance.."\n" - debugText = debugText.."v0 "..v0.x..", "..v0.y..", "..v0.z.."\n" - debugText = debugText.."v1 "..v1.x..", "..v1.y..", "..v1.z.."\n" - debugText = debugText.."v2 "..v2.x..", "..v2.y..", "..v2.z.."\n" - - result.y = ( d11 * d20 - d01 * d21) / denom - result.z = ( d00 * d21 - d01 * d20) / denom - result.x = 1.0 - ( result.z + result.y ) - - debugText = debugText.."result "..result.x..", "..result.y..", "..result.z.."\n" - - return 0.0 < result.x and 0.0 < result.y and 0.0 < result.z and distance < 0.0, distance -end - -function RL.process( delta ) - debugText = "" - - if RL.IsKeyDown( string.byte( "D" ) ) then - point.pos.x = point.pos.x + MOVE_SPEED * delta - elseif RL.IsKeyDown( string.byte( "A" ) ) then - point.pos.x = point.pos.x - MOVE_SPEED * delta - end - if RL.IsKeyDown( string.byte( "S" ) ) then - point.pos.z = point.pos.z + MOVE_SPEED * delta - elseif RL.IsKeyDown( string.byte( "W" ) ) then - point.pos.z = point.pos.z - MOVE_SPEED * delta - end - if RL.IsKeyDown( string.byte( "R" ) ) then - point.pos.y = point.pos.y + MOVE_SPEED * delta - elseif RL.IsKeyDown( string.byte( "F" ) ) then - point.pos.y = point.pos.y - MOVE_SPEED * delta - end - - if checkCollisionPointTriangle( point.pos, tri.a, tri.b, tri.c, tri.normal ) then - point.color = RL.RED - else - point.color = RL.GREEN - end -end - -function RL.draw() - RL.ClearBackground( { 100, 150, 100 } ) - - RL.BeginMode3D( camera ) - RL.DrawGrid( 8, 1 ) - RL.DrawTriangle3D( tri.a, tri.b, tri.c, { 200, 100, 100 } ) - - RL.DrawLine3D( { point.pos.x - point.lineLen, point.pos.y, point.pos.z }, - { point.pos.x + point.lineLen, point.pos.y, point.pos.z }, RL.BLUE ) - RL.DrawLine3D( { point.pos.x, point.pos.y - point.lineLen, point.pos.z }, - { point.pos.x, point.pos.y + point.lineLen, point.pos.z }, RL.BLUE ) - RL.DrawLine3D( { point.pos.x, point.pos.y, point.pos.z - point.lineLen }, - { point.pos.x, point.pos.y, point.pos.z + point.lineLen }, RL.BLUE ) - RL.DrawSphereWires( point.pos, point.radius, 3, 8, point.color ) - RL.EndMode3D() - - RL.DrawText( RL.defaultFont, debugText, { 10, 10 }, 30, 4, RL.WHITE ) -end diff --git a/examples/pong/main.lua b/examples/pong/main.lua index 80c4346..4dd3462 100644 --- a/examples/pong/main.lua +++ b/examples/pong/main.lua @@ -1,5 +1,11 @@ +-- Pong example using Vector2 library. + +package.path = package.path..";"..RL.GetBasePath().."../resources/lib/?.lua" + +Vec2 = require "vector2" + -- Settings. -local winSize = { 800, 600 } +local winSize = Vec2:new( 800, 600 ) local monitor = 0 -- Constants. @@ -8,54 +14,54 @@ local BALL_SPEED = 330 -- Game objects. local playerLeft = { - pos = { 0, 0 }, - size = { 10, 70 }, + pos = Vec2:new( 0, 0 ), + size = Vec2:new( 10, 70 ), score = 0, } local playerRight = { - pos = { 0, 0 }, - size = { 10, 70 }, + pos = Vec2:new( 0, 0 ), + size = Vec2:new( 10, 70 ), score = 0, } local ball = { - pos = { 0, 0 }, + pos = Vec2:new( 0, 0 ), radius = 8.0, - vel = { 0, 0 }, + vel = Vec2:new( 0, 0 ), } local function reset() -- Initialize player positions. - playerLeft.pos[1] = playerLeft.size[1] - playerLeft.pos[2] = winSize[2] / 2 - playerLeft.size[2] / 2 - - playerRight.pos[1] = winSize[1] - playerRight.size[1] * 2 - playerRight.pos[2] = winSize[2] / 2 - playerRight.size[2] / 2 + playerLeft.pos.x = playerLeft.size.x + playerLeft.pos.y = winSize.y / 2 - playerLeft.size.y / 2 + + playerRight.pos.x = winSize.x - playerRight.size.x * 2 + playerRight.pos.y = winSize.y / 2 - playerRight.size.y / 2 -- Set ball to center. - ball.pos = { winSize[1] / 2, winSize[2] / 2 } + ball.pos:set( winSize.x / 2, winSize.y / 2 ) -- Short for if math random result 1, set BALL_SPEED otherwise set -BALL_SPEED. -- Could be replaced by normal if statement for easier readability. - ball.vel[1] = math.random( 0, 1 ) == 1 and BALL_SPEED or -BALL_SPEED + ball.vel.x = math.random( 0, 1 ) == 1 and BALL_SPEED or -BALL_SPEED -- Start slow. - ball.vel[2] = 0 + ball.vel.y = 0 end local function ballHit( padPos, padSize ) - ball.vel[1] = -ball.vel[1] + ball.vel.x = -ball.vel.x - local padCenter = padPos[2] + padSize[2] / 2 - local relHitPos = ball.pos[2] - padCenter - ball.vel[2] = BALL_SPEED * relHitPos / padSize[2] * 2 + local padCenter = padPos.y + padSize.y / 2 + local relHitPos = ball.pos.y - padCenter + ball.vel.y = BALL_SPEED * relHitPos / padSize.y * 2 end function RL.init() -- Set window to center of monitor. - local mPos = RL.GetMonitorPosition( monitor ) - local mSize = RL.GetMonitorSize( monitor ) + local mPos = Vec2:new( RL.GetMonitorPosition( monitor ) ) + local mSize = Vec2:new( RL.GetMonitorSize( monitor ) ) - RL.SetWindowState( RL.FLAG_VSYNC_HINT ) + RL.SetConfigFlags( RL.FLAG_VSYNC_HINT ) RL.SetWindowSize( winSize ) - RL.SetWindowPosition( { mPos[1] + mSize[1] / 2 - winSize[1] / 2, mPos[2] + mSize[2] / 2 - winSize[2] / 2 } ) + RL.SetWindowPosition( { mPos.x + mSize.x / 2 - winSize.x / 2, mPos.y + mSize.y / 2 - winSize.y / 2 } ) RL.SetWindowTitle( "Pong" ) -- Initialize ball pos. @@ -65,46 +71,45 @@ end function RL.process( delta ) -- Left player controls. - if RL.IsKeyDown( string.byte( "W" ) ) and 0 < playerLeft.pos[2] then - playerLeft.pos[2] = playerLeft.pos[2] - PLAYER_SPEED * delta - elseif RL.IsKeyDown( string.byte( "S" ) ) and playerLeft.pos[2] + playerLeft.size[2] < winSize[2] then - playerLeft.pos[2] = playerLeft.pos[2] + PLAYER_SPEED * delta + if RL.IsKeyDown( RL.KEY_W ) and 0 < playerLeft.pos.y then + playerLeft.pos.y = playerLeft.pos.y - PLAYER_SPEED * delta + elseif RL.IsKeyDown( RL.KEY_S ) and playerLeft.pos.y + playerLeft.size.y < winSize.y then + playerLeft.pos.y = playerLeft.pos.y + PLAYER_SPEED * delta end -- Right player controls. - if RL.IsKeyDown( RL.KEY_UP ) and 0 < playerRight.pos[2] then - playerRight.pos[2] = playerRight.pos[2] - PLAYER_SPEED * delta - elseif RL.IsKeyDown( RL.KEY_DOWN ) and playerRight.pos[2] + playerRight.size[2] < winSize[2] then - playerRight.pos[2] = playerRight.pos[2] + PLAYER_SPEED * delta + if RL.IsKeyDown( RL.KEY_UP ) and 0 < playerRight.pos.y then + playerRight.pos.y = playerRight.pos.y - PLAYER_SPEED * delta + elseif RL.IsKeyDown( RL.KEY_DOWN ) and playerRight.pos.y + playerRight.size.y < winSize.y then + playerRight.pos.y = playerRight.pos.y + PLAYER_SPEED * delta end -- Move ball. - ball.pos = { ball.pos[1] + ball.vel[1] * delta, - ball.pos[2] + ball.vel[2] * delta } + ball.pos = ball.pos + ball.vel:scale( delta ) -- Bounce from window edge. - if ( ball.pos[2] < ball.radius and ball.vel[2] < 0 ) - or ( winSize[2] < ball.pos[2] + ball.radius and 0 < ball.vel[2] ) then - ball.vel[2] = -ball.vel[2] + if ( ball.pos.y < ball.radius and ball.vel.y < 0 ) + or ( winSize.y < ball.pos.y + ball.radius and 0 < ball.vel.y ) then + ball.vel.y = -ball.vel.y end -- Bounce from players. - local playerLeftRect = { playerLeft.pos[1], playerLeft.pos[2], - playerLeft.size[1], playerLeft.size[2] } - local playerRightRect = { playerRight.pos[1], playerRight.pos[2], - playerRight.size[1], playerRight.size[2] } + local playerLeftRect = { playerLeft.pos.x, playerLeft.pos.y, + playerLeft.size.x, playerLeft.size.y } + local playerRightRect = { playerRight.pos.x, playerRight.pos.y, + playerRight.size.x, playerRight.size.y } - if RL.CheckCollisionCircleRec( ball.pos, ball.radius, playerLeftRect ) and ball.vel[1] < 0 then + if RL.CheckCollisionCircleRec( ball.pos, ball.radius, playerLeftRect ) and ball.vel.x < 0 then ballHit( playerLeft.pos, playerLeft.size ) - elseif RL.CheckCollisionCircleRec( ball.pos, ball.radius, playerRightRect ) and 0 < ball.vel[1] then + elseif RL.CheckCollisionCircleRec( ball.pos, ball.radius, playerRightRect ) and 0 < ball.vel.x then ballHit( playerRight.pos, playerRight.size ) end -- Score. - if ball.pos[1] < 0 then + if ball.pos.x < 0 then playerRight.score = playerRight.score + 1 reset() - elseif winSize[1] < ball.pos[1] then + elseif winSize.x < ball.pos.x then playerLeft.score = playerLeft.score + 1 reset() end @@ -114,14 +119,14 @@ function RL.draw() RL.ClearBackground( RL.BLACK ) -- Draw players. - RL.DrawRectangle( { playerLeft.pos[1], playerLeft.pos[2], playerLeft.size[1], playerLeft.size[2] }, RL.WHITE ) - RL.DrawRectangle( { playerRight.pos[1], playerRight.pos[2], playerRight.size[1], playerRight.size[2] }, RL.WHITE ) + RL.DrawRectangle( { playerLeft.pos.x, playerLeft.pos.y, playerLeft.size.x, playerLeft.size.y }, RL.WHITE ) + RL.DrawRectangle( { playerRight.pos.x, playerRight.pos.y, playerRight.size.x, playerRight.size.y }, RL.WHITE ) -- Draw ball. Ball position will be the center in drawCircle. RL.DrawCircle( ball.pos, ball.radius, RL.WHITE ) - -- Draw scire - RL.DrawText( RL.defaultFont, playerLeft.score, { 50, 10 }, 40, 2, RL.WHITE ) - local rightTextSize = RL.MeasureText( RL.defaultFont, playerRight.score, 40, 2 ) - RL.DrawText( RL.defaultFont, playerRight.score, { winSize[1] - 50 - rightTextSize[1], 10 }, 40, 2, RL.WHITE ) + -- Draw score. + RL.DrawText( RL.GetFontDefault(), tostring( playerLeft.score ), { 50, 10 }, 40, 2, RL.WHITE ) + local rightTextSize = Vec2:new( RL.MeasureText( RL.GetFontDefault(), tostring( playerRight.score ), 40, 2 ) ) + RL.DrawText( RL.GetFontDefault(), tostring( playerRight.score ), { winSize.x - 50 - rightTextSize.x, 10 }, 40, 2, RL.WHITE ) end diff --git a/examples/pong_vec/main.lua b/examples/pong_vec/main.lua deleted file mode 100644 index 0b8ff62..0000000 --- a/examples/pong_vec/main.lua +++ /dev/null @@ -1,132 +0,0 @@ --- Pong example using Vector2 library. - -package.path = package.path..";"..RL.GetBasePath().."../resources/lib/?.lua" - -Vec2 = require "vector2" - --- Settings. -local winSize = Vec2:new( 800, 600 ) -local monitor = 0 - --- Constants. -local PLAYER_SPEED = 300 -local BALL_SPEED = 330 - --- Game objects. -local playerLeft = { - pos = Vec2:new( 0, 0 ), - size = Vec2:new( 10, 70 ), - score = 0, -} -local playerRight = { - pos = Vec2:new( 0, 0 ), - size = Vec2:new( 10, 70 ), - score = 0, -} -local ball = { - pos = Vec2:new( 0, 0 ), - radius = 8.0, - vel = Vec2:new( 0, 0 ), -} - -local function reset() - -- Initialize player positions. - playerLeft.pos.x = playerLeft.size.x - playerLeft.pos.y = winSize.y / 2 - playerLeft.size.y / 2 - - playerRight.pos.x = winSize.x - playerRight.size.x * 2 - playerRight.pos.y = winSize.y / 2 - playerRight.size.y / 2 - - -- Set ball to center. - ball.pos:set( winSize.x / 2, winSize.y / 2 ) - -- Short for if math random result 1, set BALL_SPEED otherwise set -BALL_SPEED. - -- Could be replaced by normal if statement for easier readability. - ball.vel.x = math.random( 0, 1 ) == 1 and BALL_SPEED or -BALL_SPEED - -- Start slow. - ball.vel.y = 0 -end - -local function ballHit( padPos, padSize ) - ball.vel.x = -ball.vel.x - - local padCenter = padPos.y + padSize.y / 2 - local relHitPos = ball.pos.y - padCenter - ball.vel.y = BALL_SPEED * relHitPos / padSize.y * 2 -end - -function RL.init() - -- Set window to center of monitor. - local mPos = Vec2:new( RL.GetMonitorPosition( monitor ) ) - local mSize = Vec2:new( RL.GetMonitorSize( monitor ) ) - - RL.SetConfigFlags( RL.FLAG_VSYNC_HINT ) - RL.SetWindowSize( winSize ) - RL.SetWindowPosition( { mPos.x + mSize.x / 2 - winSize.x / 2, mPos.y + mSize.y / 2 - winSize.y / 2 } ) - RL.SetWindowTitle( "Pong" ) - - -- Initialize ball pos. - math.randomseed( os.time() ) - reset() -end - -function RL.process( delta ) - -- Left player controls. - if RL.IsKeyDown( RL.KEY_W ) and 0 < playerLeft.pos.y then - playerLeft.pos.y = playerLeft.pos.y - PLAYER_SPEED * delta - elseif RL.IsKeyDown( RL.KEY_S ) and playerLeft.pos.y + playerLeft.size.y < winSize.y then - playerLeft.pos.y = playerLeft.pos.y + PLAYER_SPEED * delta - end - - -- Right player controls. - if RL.IsKeyDown( RL.KEY_UP ) and 0 < playerRight.pos.y then - playerRight.pos.y = playerRight.pos.y - PLAYER_SPEED * delta - elseif RL.IsKeyDown( RL.KEY_DOWN ) and playerRight.pos.y + playerRight.size.y < winSize.y then - playerRight.pos.y = playerRight.pos.y + PLAYER_SPEED * delta - end - - -- Move ball. - ball.pos = ball.pos + ball.vel:scale( delta ) - - -- Bounce from window edge. - if ( ball.pos.y < ball.radius and ball.vel.y < 0 ) - or ( winSize.y < ball.pos.y + ball.radius and 0 < ball.vel.y ) then - ball.vel.y = -ball.vel.y - end - - -- Bounce from players. - local playerLeftRect = { playerLeft.pos.x, playerLeft.pos.y, - playerLeft.size.x, playerLeft.size.y } - local playerRightRect = { playerRight.pos.x, playerRight.pos.y, - playerRight.size.x, playerRight.size.y } - - if RL.CheckCollisionCircleRec( ball.pos, ball.radius, playerLeftRect ) and ball.vel.x < 0 then - ballHit( playerLeft.pos, playerLeft.size ) - elseif RL.CheckCollisionCircleRec( ball.pos, ball.radius, playerRightRect ) and 0 < ball.vel.x then - ballHit( playerRight.pos, playerRight.size ) - end - - -- Score. - if ball.pos.x < 0 then - playerRight.score = playerRight.score + 1 - reset() - elseif winSize.x < ball.pos.x then - playerLeft.score = playerLeft.score + 1 - reset() - end -end - -function RL.draw() - RL.ClearBackground( RL.BLACK ) - - -- Draw players. - RL.DrawRectangle( { playerLeft.pos.x, playerLeft.pos.y, playerLeft.size.x, playerLeft.size.y }, RL.WHITE ) - RL.DrawRectangle( { playerRight.pos.x, playerRight.pos.y, playerRight.size.x, playerRight.size.y }, RL.WHITE ) - - -- Draw ball. Ball position will be the center in drawCircle. - RL.DrawCircle( ball.pos, ball.radius, RL.WHITE ) - - -- Draw score. - RL.DrawText( RL.defaultFont, tostring( playerLeft.score ), { 50, 10 }, 40, 2, RL.WHITE ) - local rightTextSize = Vec2:new( RL.MeasureText( RL.defaultFont, tostring( playerRight.score ), 40, 2 ) ) - RL.DrawText( RL.defaultFont, tostring( playerRight.score ), { winSize.x - 50 - rightTextSize.x, 10 }, 40, 2, RL.WHITE ) -end diff --git a/examples/ray/main.lua b/examples/ray/main.lua index 6bee146..52924df 100644 --- a/examples/ray/main.lua +++ b/examples/ray/main.lua @@ -53,7 +53,7 @@ function RL.draw() RL.DrawGrid( 8, 1 ) RL.DrawRay( ray, { 255, 100, 100 } ) - RL.DrawMesh( sphereMesh, RL.defaultMaterial, RL.MatrixIdentity() ) + RL.DrawMesh( sphereMesh, RL.GetMaterialDefault(), RL.MatrixIdentity() ) RL.DrawSphereWires( rayCol.point, 0.05, 4, 8, RL.BLUE ) RL.DrawLine3D( rayCol.point, RL.Vector3Add( rayCol.point, rayCol.normal ), RL.GREEN ) RL.EndMode3D() diff --git a/examples/resources/lib/gui.lua b/examples/resources/lib/gui.lua index bca87bd..996001c 100644 --- a/examples/resources/lib/gui.lua +++ b/examples/resources/lib/gui.lua @@ -40,7 +40,7 @@ Gui = { }, mouseButton = RL.MOUSE_BUTTON_LEFT, - font = RL.defaultFont, + font = RL.GetFontDefault(), fontSize = 20, padding = 2, spacing = 4, diff --git a/examples/snake/main.lua b/examples/snake/main.lua index e90c732..5aa22b3 100644 --- a/examples/snake/main.lua +++ b/examples/snake/main.lua @@ -213,7 +213,7 @@ function RL.draw() drawApple() if gameState == STATE.OVER then - RL.DrawText( RL.defaultFont, "Press Enter to\nrestart", { 10, 10 }, 10, 2, RL.WHITE ) + RL.DrawText( RL.GetFontDefault(), "Press Enter to\nrestart", { 10, 10 }, 10, 2, RL.WHITE ) end RL.EndTextureMode() diff --git a/examples/window/main.lua b/examples/window/main.lua index 4be48f6..c6161e9 100644 --- a/examples/window/main.lua +++ b/examples/window/main.lua @@ -24,5 +24,5 @@ end function RL.draw() RL.ClearBackground( RL.RAYWHITE ) - RL.DrawText( RL.defaultFont, text, textPos, 20, 2, textColor ) + RL.DrawText( RL.GetFontDefault(), text, textPos, 20, 2, textColor ) end diff --git a/include/audio.h b/include/audio.h index 756f16f..edc47ee 100644 --- a/include/audio.h +++ b/include/audio.h @@ -5,7 +5,11 @@ int laudioSetMasterVolume( lua_State *L ); /* Wave/Sound Loading. */ int laudioLoadSound( lua_State *L ); int laudioLoadWave( lua_State *L ); +int laudioIsWaveReady( lua_State *L ); int laudioLoadSoundFromWave( lua_State *L ); +int laudioIsSoundReady( lua_State *L ); +int laudioUnloadWave( lua_State *L ); +int laudioUnloadSound( lua_State *L ); int laudioExportWave( lua_State *L ); int laudioExportWaveAsCode( lua_State *L ); /* Wave/Sound management. */ @@ -22,6 +26,8 @@ int laudioWaveCopy( lua_State *L ); int laudioWaveCrop( lua_State *L ); /* Music management. */ int laudioLoadMusicStream( lua_State *L ); +int laudioIsMusicReady( lua_State *L ); +int laudioUnloadMusicStream( lua_State *L ); int laudioPlayMusicStream( lua_State *L ); int laudioIsMusicStreamPlaying( lua_State *L ); int laudioUpdateMusicStream( lua_State *L ); diff --git a/include/core.h b/include/core.h index 2afc4fe..f9b26bd 100644 --- a/include/core.h +++ b/include/core.h @@ -44,6 +44,8 @@ int lcoreSetLogLevelInvalid( lua_State *L ); int lcoreGetLogLevelInvalid( lua_State *L ); int lcoreOpenURL( lua_State *L ); int lcoreLoadBuffer( lua_State *L ); +int lcoreUnloadBuffer( lua_State *L ); +int lcoreIsGCUnloadEnabled( lua_State *L ); /* Cursor. */ int lcoreShowCursor( lua_State *L ); int lcoreHideCursor( lua_State *L ); @@ -62,6 +64,7 @@ int lcoreEndScissorMode( lua_State *L ); /* Shader. */ int lcoreLoadShader( lua_State *L ); int lcoreLoadShaderFromMemory( lua_State *L ); +int lcoreIsShaderReady( lua_State *L ); int lcoreBeginShaderMode( lua_State *L ); int lcoreEndShaderMode( lua_State *L ); int lcoreGetShaderLocation( lua_State *L ); @@ -72,6 +75,7 @@ int lcoreSetShaderValueMatrix( lua_State *L ); int lcoreSetShaderValueTexture( lua_State *L ); int lcoreSetShaderValue( lua_State *L ); int lcoreSetShaderValueV( lua_State *L ); +int lcoreUnloadShader( lua_State *L ); /* File. */ int lcoreGetBasePath( lua_State *L ); int lcoreFileExists( lua_State *L ); diff --git a/include/lua_core.h b/include/lua_core.h index f8c94ac..5fe539f 100644 --- a/include/lua_core.h +++ b/include/lua_core.h @@ -57,6 +57,7 @@ Ray uluaGetRay( lua_State *L ); Ray uluaGetRayIndex( lua_State *L, int index ); NPatchInfo uluaGetNPatchInfo( lua_State *L ); NPatchInfo uluaGetNPatchInfoIndex( lua_State *L, int index ); +Buffer* uluaGetBuffer( lua_State *L, int index ); Image* uluaGetImage( lua_State *L, int index ); Texture* uluaGetTexture( lua_State *L, int index ); RenderTexture* uluaGetRenderTexture( lua_State *L, int index ); @@ -83,6 +84,7 @@ void uluaPushMatrix( lua_State *L, Matrix matrix ); void uluaPushRay( lua_State *L, Ray ray ); void uluaPushRayCollision( lua_State *L, RayCollision rayCol ); void uluaPushBoundingBox( lua_State *L, BoundingBox box ); +void uluaPushBuffer( lua_State *L, Buffer buffer ); void uluaPushImage( lua_State *L, Image image ); void uluaPushTexture( lua_State *L, Texture texture ); void uluaPushRenderTexture( lua_State *L, RenderTexture renderTexture ); diff --git a/include/models.h b/include/models.h index ba92732..f97e4a4 100644 --- a/include/models.h +++ b/include/models.h @@ -38,6 +38,7 @@ 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 ); int lmodelsSetMeshColor( lua_State *L ); @@ -45,8 +46,11 @@ int lmodelsExportMesh( lua_State *L ); int lmodelsGetMeshBoundingBox( lua_State *L ); int lmodelsGenMeshTangents( lua_State *L ); /* Material. */ +int lmodelsGetMaterialDefault( lua_State *L ); int lmodelsLoadMaterialDefault( lua_State *L ); int lmodelsCreateMaterial( lua_State *L ); +int lmodelsIsMaterialReady( lua_State *L ); +int lmodelsUnloadMaterial( lua_State *L ); int lmodelsSetMaterialTexture( lua_State *L ); int lmodelsSetMaterialColor( lua_State *L ); int lmodelsSetMaterialValue( lua_State *L ); @@ -60,6 +64,8 @@ int lmodelsGetMaterialParams( lua_State *L ); /* Model. */ int lmodelsLoadModel( lua_State *L ); int lmodelsLoadModelFromMesh( lua_State *L ); +int lmodelsIsModelReady( lua_State *L ); +int lmodelsUnloadModel( lua_State *L ); int lmodelsDrawModel( lua_State *L ); int lmodelsDrawModelEx( lua_State *L ); int lmodelsSetModelMaterial( lua_State *L ); diff --git a/include/state.h b/include/state.h index 4b023aa..d7e1052 100644 --- a/include/state.h +++ b/include/state.h @@ -6,9 +6,12 @@ typedef struct { char *exePath; bool hasWindow; bool run; + bool gcUnload; lua_State *luaState; Vector2 resolution; int logLevelInvalid; + Font defaultFont; + Material defaultMaterial; /* Raylib GLFW input callback events. */ /* Window events. */ GLFWwindowsizefun raylibWindowSizeCallback; diff --git a/include/text.h b/include/text.h index 1c3ef40..1cfe4e8 100644 --- a/include/text.h +++ b/include/text.h @@ -5,6 +5,8 @@ int ltextGetFontDefault( lua_State *L ); int ltextLoadFont( lua_State *L ); int ltextLoadFontEx( lua_State *L ); int ltextLoadFontFromImage( lua_State *L ); +int ltextIsFontReady( lua_State *L ); +int ltextUnloadFont( lua_State *L ); /* Drawing. */ int ltextDrawFPS( lua_State *L ); int ltextDrawText( lua_State *L ); diff --git a/include/textures.h b/include/textures.h index 931058a..353026e 100644 --- a/include/textures.h +++ b/include/textures.h @@ -4,6 +4,8 @@ int ltexturesLoadImage( lua_State *L ); int ltexturesLoadImageFromTexture( lua_State *L ); int ltexturesLoadImageFromScreen( lua_State *L ); +int ltextureIsImageReady( lua_State *L ); +int ltextureUnloadImage( lua_State *L ); int ltexturesExportImage( lua_State *L ); int ltexturesExportImageAsCode( lua_State *L ); /* Image Generation. */ @@ -69,6 +71,9 @@ int ltexturesLoadTextureFromData( lua_State *L ); int ltexturesLoadRenderTexture( lua_State *L ); int ltexturesLoadRenderTextureFromData( lua_State *L ); int ltexturesIsTextureReady( lua_State *L ); +int ltextureUnloadTexture( lua_State *L ); +int ltexturesIsRenderTextureReady( lua_State *L ); +int ltextureUnloadRenderTexture( lua_State *L ); int ltexturesUpdateTexture( lua_State *L ); int ltexturesUpdateTextureRec( lua_State *L ); /* Texture Drawing. */ diff --git a/src/audio.c b/src/audio.c index 6a2164d..f1ef460 100644 --- a/src/audio.c +++ b/src/audio.c @@ -65,6 +65,21 @@ int laudioLoadWave( lua_State *L ) { } /* +> isReady = RL.IsWaveReady( Wave wave ) + +Checks if wave data is ready + +- Success return bool +*/ +int laudioIsWaveReady( lua_State *L ) { + Wave *wave = uluaGetWave( L, 1 ); + + lua_pushboolean( L, IsWaveReady( *wave ) ); + + return 1; +} + +/* > sound = RL.LoadSoundFromWave( Wave wave ) Load sound from wave data @@ -80,6 +95,47 @@ int laudioLoadSoundFromWave( lua_State *L ) { } /* +> isReady = RL.IsSoundReady( Sound sound ) + +Checks if a sound is ready + +- Success return bool +*/ +int laudioIsSoundReady( lua_State *L ) { + Sound *sound = uluaGetSound( L, 1 ); + + lua_pushboolean( L, IsSoundReady( *sound ) ); + + return 1; +} + +/* +> RL.UnloadWave( Wave wave ) + +Unload wave data +*/ +int laudioUnloadWave( lua_State *L ) { + Wave *wave = uluaGetWave( L, 1 ); + + UnloadWave( *wave ); + + return 0; +} + +/* +> RL.UnloadSound( Sound sound ) + +Unload sound +*/ +int laudioUnloadSound( lua_State *L ) { + Sound *sound = uluaGetSound( L, 1 ); + + UnloadSound( *sound ); + + return 0; +} + +/* > success = RL.ExportWave( Wave wave, string fileName ) Export wave data to file, returns true on success @@ -292,6 +348,34 @@ int laudioLoadMusicStream( lua_State *L ) { } /* +> isReady = RL.IsMusicReady( Music music ) + +Checks if a music stream is ready + +- Success return bool +*/ +int laudioIsMusicReady( lua_State *L ) { + Music *music = uluaGetMusic( L, 1 ); + + lua_pushboolean( L, IsMusicReady( *music ) ); + + return 1; +} + +/* +> RL.UnloadMusicStream( Music music ) + +Unload music stream +*/ +int laudioUnloadMusicStream( lua_State *L ) { + Music *music = uluaGetMusic( L, 1 ); + + UnloadMusicStream( *music ); + + return 0; +} + +/* > RL.PlayMusicStream( Music music ) Start music playing @@ -552,33 +552,34 @@ int lcoreLoadBuffer( lua_State *L ) { luaL_checktype( L, 1, LUA_TTABLE ); int type = luaL_checkinteger( L, 2 ); - Buffer *buffer = lua_newuserdata( L, sizeof( Buffer ) ); + Buffer buffer = { 0 }; + // Buffer *buffer = lua_newuserdata( L, sizeof( Buffer ) ); int len = uluaGetTableLenIndex( L, 1 ); switch ( type ) { case BUFFER_UNSIGNED_CHAR: - buffer->size = len * sizeof( unsigned char ); + buffer.size = len * sizeof( unsigned char ); break; case BUFFER_UNSIGNED_SHORT: - buffer->size = len * sizeof( unsigned short ); + buffer.size = len * sizeof( unsigned short ); break; case BUFFER_UNSIGNED_INT: - buffer->size = len * sizeof( unsigned int ); + buffer.size = len * sizeof( unsigned int ); break; case BUFFER_FLOAT: - buffer->size = len * sizeof( float ); + buffer.size = len * sizeof( float ); break; default: break; } - buffer->data = malloc( buffer->size ); + 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; + unsigned char *up = buffer.data; + unsigned short *sp = buffer.data; + unsigned int *ip = buffer.data; + float *fp = buffer.data; lua_pushnil( L ); @@ -606,7 +607,33 @@ int lcoreLoadBuffer( lua_State *L ) { lua_pop( L, 1 ); i++; } - luaL_setmetatable( L, "Buffer" ); + uluaPushBuffer( L, buffer ); + + return 1; +} + +/* +> RL.UnloadBuffer( Buffer buffer ) + +Unload buffer data +*/ +int lcoreUnloadBuffer( lua_State *L ) { + Buffer *buffer = uluaGetBuffer( L, 1 ); + + free( buffer->data ); + + return 0; +} + +/* +> enabled = RL.IsGCUnloadEnabled() + +Check if Lua garbage collection is set to unload object data + +- Success return bool +*/ +int lcoreIsGCUnloadEnabled( lua_State *L ) { + lua_pushboolean( L, state->gcUnload ); return 1; } @@ -862,6 +889,21 @@ int lcoreLoadShaderFromMemory( lua_State *L ) { } /* +> isReady = RL.IsShaderReady( Shader shader ) + +Check if a shader is ready + +- Success return bool +*/ +int lcoreIsShaderReady( lua_State *L ) { + Shader *shader = uluaGetShader( L, 1 ); + + lua_pushboolean( L, IsShaderReady( *shader ) ); + + return 1; +} + +/* > RL.BeginShaderMode( Shader shader ) Begin custom shader drawing @@ -1062,6 +1104,19 @@ int lcoreSetShaderValueV( lua_State *L ) { } /* +> RL.UnloadShader( Shader shader ) + +Unload shader from GPU memory (VRAM) +*/ +int lcoreUnloadShader( lua_State *L ) { + Shader *shader = uluaGetShader( L, 1 ); + + UnloadShader( *shader ); + + return 0; +} + +/* ## Core - Input-related Keyboard */ diff --git a/src/lua_core.c b/src/lua_core.c index a2b3303..10f48b8 100644 --- a/src/lua_core.c +++ b/src/lua_core.c @@ -18,7 +18,8 @@ /* Buffer. */ static int gcBuffer( lua_State *L ) { - Buffer *buffer = luaL_checkudata ( L, 1, "Buffer" ); + Buffer *buffer = luaL_checkudata( L, 1, "Buffer" ); + free( buffer->data ); } @@ -28,13 +29,15 @@ static void defineBuffer() { luaL_newmetatable( L, "Buffer" ); lua_pushvalue( L, -1 ); lua_setfield( L, -2, "__index" ); +#ifdef GC_UNLOAD lua_pushcfunction( L, gcBuffer ); lua_setfield( L, -2, "__gc" ); +#endif } /* Image */ static int gcImage( lua_State *L ) { - Image *image = luaL_checkudata ( L, 1, "Image" ); + Image *image = luaL_checkudata( L, 1, "Image" ); UnloadImage( *image ); } @@ -45,13 +48,15 @@ static void defineImage() { luaL_newmetatable( L, "Image" ); lua_pushvalue( L, -1 ); lua_setfield( L, -2, "__index" ); +#ifdef GC_UNLOAD lua_pushcfunction( L, gcImage ); lua_setfield( L, -2, "__gc" ); +#endif } /* Texture */ static int gcTexture( lua_State *L ) { - Texture *texture = luaL_checkudata ( L, 1, "Texture" ); + Texture *texture = luaL_checkudata( L, 1, "Texture" ); UnloadTexture( *texture ); } @@ -62,13 +67,15 @@ static void defineTexture() { luaL_newmetatable( L, "Texture" ); lua_pushvalue( L, -1 ); lua_setfield( L, -2, "__index" ); +#ifdef GC_UNLOAD lua_pushcfunction( L, gcTexture ); lua_setfield( L, -2, "__gc" ); +#endif } /* RenderRexture. */ static int gcRenderTexture( lua_State *L ) { - RenderTexture *renderTexture = luaL_checkudata ( L, 1, "RenderTexture" ); + RenderTexture *renderTexture = luaL_checkudata( L, 1, "RenderTexture" ); UnloadRenderTexture( *renderTexture ); } @@ -79,8 +86,10 @@ static void defineRenderTexture() { luaL_newmetatable( L, "RenderTexture" ); lua_pushvalue( L, -1 ); lua_setfield( L, -2, "__index" ); +#ifdef GC_UNLOAD lua_pushcfunction( L, gcRenderTexture ); lua_setfield( L, -2, "__gc" ); +#endif } /* Camera2D. */ @@ -103,7 +112,7 @@ static void defineCamera3D() { /* Shader. */ static int gcShader( lua_State *L ) { - Shader *shader = luaL_checkudata ( L, 1, "Shader" ); + Shader *shader = luaL_checkudata( L, 1, "Shader" ); UnloadShader( *shader ); } @@ -114,13 +123,15 @@ static void defineShader() { luaL_newmetatable( L, "Shader" ); lua_pushvalue( L, -1 ); lua_setfield( L, -2, "__index" ); +#ifdef GC_UNLOAD lua_pushcfunction( L, gcShader ); lua_setfield( L, -2, "__gc" ); +#endif } /* Font. */ static int gcFont( lua_State *L ) { - Font *font = luaL_checkudata ( L, 1, "Font" ); + Font *font = luaL_checkudata( L, 1, "Font" ); UnloadFont( *font ); } @@ -131,13 +142,15 @@ static void defineFont() { luaL_newmetatable( L, "Font" ); lua_pushvalue( L, -1 ); lua_setfield( L, -2, "__index" ); +#ifdef GC_UNLOAD lua_pushcfunction( L, gcFont ); lua_setfield( L, -2, "__gc" ); +#endif } /* Wave. */ static int gcWave( lua_State *L ) { - Wave *wave = luaL_checkudata ( L, 1, "Wave" ); + Wave *wave = luaL_checkudata( L, 1, "Wave" ); UnloadWave( *wave ); } @@ -148,13 +161,15 @@ static void defineWave() { luaL_newmetatable( L, "Wave" ); lua_pushvalue( L, -1 ); lua_setfield( L, -2, "__index" ); +#ifdef GC_UNLOAD lua_pushcfunction( L, gcWave ); lua_setfield( L, -2, "__gc" ); +#endif } /* Sound. */ static int gcSound( lua_State *L ) { - Sound *sound = luaL_checkudata ( L, 1, "Sound" ); + Sound *sound = luaL_checkudata( L, 1, "Sound" ); UnloadSound( *sound ); } @@ -165,13 +180,15 @@ static void defineSound() { luaL_newmetatable( L, "Sound" ); lua_pushvalue( L, -1 ); lua_setfield( L, -2, "__index" ); +#ifdef GC_UNLOAD lua_pushcfunction( L, gcSound ); lua_setfield( L, -2, "__gc" ); +#endif } /* Music. */ static int gcMusic( lua_State *L ) { - Music *music = luaL_checkudata ( L, 1, "Music" ); + Music *music = luaL_checkudata( L, 1, "Music" ); UnloadMusicStream( *music ); } @@ -182,8 +199,10 @@ static void defineMusic() { luaL_newmetatable( L, "Music" ); lua_pushvalue( L, -1 ); lua_setfield( L, -2, "__index" ); +#ifdef GC_UNLOAD lua_pushcfunction( L, gcMusic ); lua_setfield( L, -2, "__gc" ); +#endif } /* Light. */ @@ -197,22 +216,12 @@ static void defineLight() { /* Material. */ static int gcMaterial( lua_State *L ) { - Material *material = luaL_checkudata ( L, 1, "Material" ); - - // int MAX_MATERIAL_MAPS = 12; - - // Unload loaded texture maps (avoid unloading default texture, managed by raylib) - // if ( material->maps != NULL ) { - // for ( int i = 0; i < MAX_MATERIAL_MAPS; i++ ) { - // if ( material->maps[i].texture.id != rlGetTextureIdDefault() ) { - // printf( "gcMaterial material->maps[i].texture.id = %d\n", material->maps[i].texture.id ); - // rlUnloadTexture( material->maps[i].texture.id ); - // } - // } - // } + Material *material = luaL_checkudata( L, 1, "Material" ); /* Custom UnloadMaterial since we don't want to free Shaders or Textures. */ - RL_FREE( material->maps ); + RL_FREE( material->maps ); + + // UnloadMaterial( *material ); } static void defineMaterial() { @@ -221,13 +230,15 @@ static void defineMaterial() { luaL_newmetatable( L, "Material" ); lua_pushvalue( L, -1 ); lua_setfield( L, -2, "__index" ); +#ifdef GC_UNLOAD lua_pushcfunction( L, gcMaterial ); lua_setfield( L, -2, "__gc" ); +#endif } /* Mesh. */ static int gcMesh( lua_State *L ) { - Mesh *mesh = luaL_checkudata ( L, 1, "Mesh" ); + Mesh *mesh = luaL_checkudata( L, 1, "Mesh" ); UnloadMesh( *mesh ); } @@ -238,13 +249,15 @@ static void defineMesh() { luaL_newmetatable( L, "Mesh" ); lua_pushvalue( L, -1 ); lua_setfield( L, -2, "__index" ); +#ifdef GC_UNLOAD lua_pushcfunction( L, gcMesh ); lua_setfield( L, -2, "__gc" ); +#endif } /* Model. */ static int gcModel( lua_State *L ) { - Model *model = luaL_checkudata ( L, 1, "Model" ); + Model *model = luaL_checkudata( L, 1, "Model" ); UnloadModel( *model ); // UnloadModelKeepMeshes( *model ); @@ -256,13 +269,15 @@ static void defineModel() { luaL_newmetatable( L, "Model" ); lua_pushvalue( L, -1 ); lua_setfield( L, -2, "__index" ); +#ifdef GC_UNLOAD lua_pushcfunction( L, gcModel ); lua_setfield( L, -2, "__gc" ); +#endif } /* ModelAnimation. */ static int gcModelAnimation( lua_State *L ) { - ModelAnimation *modelAnimation = luaL_checkudata ( L, 1, "ModelAnimation" ); + ModelAnimation *modelAnimation = luaL_checkudata( L, 1, "ModelAnimation" ); UnloadModelAnimation( *modelAnimation ); } @@ -273,8 +288,10 @@ static void defineModelAnimation() { luaL_newmetatable( L, "ModelAnimation" ); lua_pushvalue( L, -1 ); lua_setfield( L, -2, "__index" ); +#ifdef GC_UNLOAD lua_pushcfunction( L, gcModelAnimation ); lua_setfield( L, -2, "__gc" ); +#endif } /* Assing globals. */ @@ -316,12 +333,6 @@ static void defineGlobals() { lua_setglobal( L, "RL" ); lua_getglobal( L, "RL" ); - uluaPushFont( L, GetFontDefault() ); - lua_setfield( L, -2, "defaultFont" ); - - uluaPushMaterial( L, LoadMaterialDefault() ); - lua_setfield( L, -2, "defaultMaterial" ); - /*DOC_START*/ /* ConfigFlags */ assignGlobalInt( FLAG_VSYNC_HINT, "FLAG_VSYNC_HINT" ); @@ -1527,6 +1538,8 @@ void luaRegister() { assingGlobalFunction( "GetLogLevelInvalid", lcoreGetLogLevelInvalid ); assingGlobalFunction( "OpenURL", lcoreOpenURL ); assingGlobalFunction( "LoadBuffer", lcoreLoadBuffer ); + assingGlobalFunction( "UnloadBuffer", lcoreUnloadBuffer ); + assingGlobalFunction( "IsGCUnloadEnabled", lcoreIsGCUnloadEnabled ); /* Cursor. */ assingGlobalFunction( "ShowCursor", lcoreShowCursor ); assingGlobalFunction( "HideCursor", lcoreHideCursor ); @@ -1545,6 +1558,7 @@ void luaRegister() { /* Shader. */ assingGlobalFunction( "LoadShader", lcoreLoadShader ); assingGlobalFunction( "LoadShaderFromMemory", lcoreLoadShaderFromMemory ); + assingGlobalFunction( "IsShaderReady", lcoreIsShaderReady ); assingGlobalFunction( "BeginShaderMode", lcoreBeginShaderMode ); assingGlobalFunction( "EndShaderMode", lcoreEndShaderMode ); assingGlobalFunction( "GetShaderLocation", lcoreGetShaderLocation ); @@ -1555,6 +1569,7 @@ void luaRegister() { assingGlobalFunction( "SetShaderValueTexture", lcoreSetShaderValueTexture ); assingGlobalFunction( "SetShaderValue", lcoreSetShaderValue ); assingGlobalFunction( "SetShaderValueV", lcoreSetShaderValueV ); + assingGlobalFunction( "UnloadShader", lcoreUnloadShader ); /* File. */ assingGlobalFunction( "GetBasePath", lcoreGetBasePath ); assingGlobalFunction( "FileExists", lcoreFileExists ); @@ -1717,6 +1732,8 @@ void luaRegister() { assingGlobalFunction( "LoadImage", ltexturesLoadImage ); assingGlobalFunction( "LoadImageFromTexture", ltexturesLoadImageFromTexture ); assingGlobalFunction( "LoadImageFromScreen", ltexturesLoadImageFromScreen ); + assingGlobalFunction( "IsImageReady", ltextureIsImageReady ); + assingGlobalFunction( "UnloadImage", ltextureUnloadImage ); assingGlobalFunction( "ExportImage", ltexturesExportImage ); assingGlobalFunction( "ExportImageAsCode", ltexturesExportImageAsCode ); /* Image Generation. */ @@ -1782,6 +1799,9 @@ void luaRegister() { assingGlobalFunction( "LoadRenderTexture", ltexturesLoadRenderTexture ); assingGlobalFunction( "LoadRenderTextureFromData", ltexturesLoadRenderTextureFromData ); assingGlobalFunction( "IsTextureReady", ltexturesIsTextureReady ); + assingGlobalFunction( "UnloadTexture", ltextureUnloadTexture ); + assingGlobalFunction( "IsRenderTextureReady", ltexturesIsRenderTextureReady ); + assingGlobalFunction( "UnloadRenderTexture", ltextureUnloadRenderTexture ); assingGlobalFunction( "UpdateTexture", ltexturesUpdateTexture ); assingGlobalFunction( "UpdateTextureRec", ltexturesUpdateTextureRec ); /* Texture Drawing. */ @@ -1852,6 +1872,7 @@ void luaRegister() { assingGlobalFunction( "GenMeshHeightmap", lmodelsGenMeshHeightmap ); assingGlobalFunction( "GenMeshCustom", lmodelsGenMeshCustom ); assingGlobalFunction( "UpdateMesh", lmodelsUpdateMesh ); + assingGlobalFunction( "UnloadMesh", lmodelsUnloadMesh ); assingGlobalFunction( "DrawMesh", lmodelsDrawMesh ); assingGlobalFunction( "DrawMeshInstanced", lmodelsDrawMeshInstanced ); assingGlobalFunction( "SetMeshColor", lmodelsSetMeshColor ); @@ -1859,8 +1880,11 @@ void luaRegister() { assingGlobalFunction( "GetMeshBoundingBox", lmodelsGetMeshBoundingBox ); assingGlobalFunction( "GenMeshTangents", lmodelsGenMeshTangents ); /* Material. */ + assingGlobalFunction( "GetMaterialDefault", lmodelsGetMaterialDefault ); assingGlobalFunction( "LoadMaterialDefault", lmodelsLoadMaterialDefault ); assingGlobalFunction( "CreateMaterial", lmodelsCreateMaterial ); + assingGlobalFunction( "IsMaterialReady", lmodelsIsMaterialReady ); + assingGlobalFunction( "UnloadMaterial", lmodelsUnloadMaterial ); assingGlobalFunction( "SetMaterialTexture", lmodelsSetMaterialTexture ); assingGlobalFunction( "SetMaterialColor", lmodelsSetMaterialColor ); assingGlobalFunction( "SetMaterialValue", lmodelsSetMaterialValue ); @@ -1874,6 +1898,8 @@ void luaRegister() { /* Model. */ assingGlobalFunction( "LoadModel", lmodelsLoadModel ); assingGlobalFunction( "LoadModelFromMesh", lmodelsLoadModelFromMesh ); + assingGlobalFunction( "IsModelReady", lmodelsIsModelReady ); + assingGlobalFunction( "UnloadModel", lmodelsUnloadModel ); assingGlobalFunction( "DrawModel", lmodelsDrawModel ); assingGlobalFunction( "DrawModelEx", lmodelsDrawModelEx ); assingGlobalFunction( "SetModelMaterial", lmodelsSetModelMaterial ); @@ -1905,6 +1931,8 @@ void luaRegister() { assingGlobalFunction( "LoadFont", ltextLoadFont ); assingGlobalFunction( "LoadFontEx", ltextLoadFontEx ); assingGlobalFunction( "LoadFontFromImage", ltextLoadFontFromImage ); + assingGlobalFunction( "IsFontReady", ltextIsFontReady ); + assingGlobalFunction( "UnloadFont", ltextUnloadFont ); /* Drawing. */ assingGlobalFunction( "DrawFPS", ltextDrawFPS ); assingGlobalFunction( "DrawText", ltextDrawText ); @@ -1922,7 +1950,11 @@ void luaRegister() { /* Wave/Sound Loading. */ assingGlobalFunction( "LoadSound", laudioLoadSound ); assingGlobalFunction( "LoadWave", laudioLoadWave ); + assingGlobalFunction( "IsWaveReady", laudioIsWaveReady ); assingGlobalFunction( "LoadSoundFromWave", laudioLoadSoundFromWave ); + assingGlobalFunction( "IsSoundReady", laudioIsSoundReady ); + assingGlobalFunction( "UnloadWave", laudioUnloadWave ); + assingGlobalFunction( "UnloadSound", laudioUnloadSound ); assingGlobalFunction( "ExportWave", laudioExportWave ); assingGlobalFunction( "ExportWaveAsCode", laudioExportWaveAsCode ); /* Wave/Sound management */ @@ -1939,6 +1971,8 @@ void luaRegister() { assingGlobalFunction( "WaveCrop", laudioWaveCrop ); /* Music management. */ assingGlobalFunction( "LoadMusicStream", laudioLoadMusicStream ); + assingGlobalFunction( "IsMusicReady", laudioIsMusicReady ); + assingGlobalFunction( "UnloadMusicStream", laudioUnloadMusicStream ); assingGlobalFunction( "PlayMusicStream", laudioPlayMusicStream ); assingGlobalFunction( "IsMusicStreamPlaying", laudioIsMusicStreamPlaying ); assingGlobalFunction( "UpdateMusicStream", laudioUpdateMusicStream ); @@ -2788,6 +2822,13 @@ NPatchInfo uluaGetNPatchInfoIndex( lua_State *L, int index ) { return npatch; } +Buffer* uluaGetBuffer( lua_State *L, int index ) { + if ( lua_islightuserdata( L, index ) ) { + return (Buffer*)lua_touserdata( L, index ); + } + return luaL_checkudata( L, index, "Buffer" ); +} + Image* uluaGetImage( lua_State *L, int index ) { if ( lua_islightuserdata( L, index ) ) { return (Image*)lua_touserdata( L, index ); @@ -3065,6 +3106,12 @@ void uluaPushBoundingBox( lua_State *L, BoundingBox box ) { lua_rawseti( L, -2, 2 ); } +void uluaPushBuffer( lua_State *L, Buffer buffer ) { + Buffer *bufferP = lua_newuserdata( L, sizeof( Buffer ) ); + *bufferP = buffer; + luaL_setmetatable( L, "Buffer" ); +} + void uluaPushImage( lua_State *L, Image image ) { Image *imageP = lua_newuserdata( L, sizeof( Image ) ); *imageP = image; diff --git a/src/models.c b/src/models.c index 75f07fd..330346f 100644 --- a/src/models.c +++ b/src/models.c @@ -924,6 +924,19 @@ int lmodelsUpdateMesh( lua_State *L ) { } /* +> RL.UnloadMesh( Mesh mesh ) + +Unload mesh data from CPU and GPU +*/ +int lmodelsUnloadMesh( lua_State *L ) { + Mesh *mesh = uluaGetMesh( L, 1 ); + + UnloadMesh( *mesh ); + + return 0; +} + +/* > RL.DrawMesh( Mesh mesh, Material material, Matrix transform ) Draw a 3d mesh with material and transform @@ -1047,9 +1060,22 @@ int lmodelsGenMeshTangents( lua_State *L ) { */ /* +> material = RL.GetMaterialDefault() + +Default material for reference. Return as lightuserdata + +- Success return Material +*/ +int lmodelsGetMaterialDefault( lua_State *L ) { + lua_pushlightuserdata( L, &state->defaultMaterial ); + + return 1; +} + +/* > material = RL.LoadMaterialDefault() -Load default material +Load default material as new object - Success return Material */ @@ -1145,6 +1171,37 @@ int lmodelsCreateMaterial( lua_State *L ) { } /* +> isReady = RL.IsMaterialReady( Material material ) + +Check if a material is ready + +- Success return bool +*/ +int lmodelsIsMaterialReady( lua_State *L ) { + Material *material = uluaGetMaterial( L, 1 ); + + lua_pushboolean( L, IsMaterialReady( *material ) ); + + return 1; +} + +/* +> RL.UnloadMaterial( Material material ) + +Unload material from GPU memory (VRAM) +*/ +int lmodelsUnloadMaterial( lua_State *L ) { + Material *material = uluaGetMaterial( L, 1 ); + + /* Custom UnloadMaterial since we don't want to free Shaders or Textures. */ + RL_FREE( material->maps ); + + // UnloadMaterial( *material ); + + return 0; +} + +/* > RL.SetMaterialTexture( Material material, int mapType, Texture texture ) Set texture for a material map type (MATERIAL_MAP_ALBEDO, MATERIAL_MAP_METALNESS...) @@ -1286,7 +1343,7 @@ int lmodelsGetMaterialValue( lua_State *L ) { Get material shader -- Success return Shader. Returns as lightuserdata +- Success return Shader. Return as lightuserdata */ int lmodelsGetMaterialShader( lua_State *L ) { Material *material = uluaGetMaterial( L, 1 ); @@ -1357,6 +1414,34 @@ int lmodelsLoadModelFromMesh( lua_State *L ) { } /* +> isReady = RL.IsModelReady( Model model ) + +Check if a model is ready + +- Success return bool +*/ +int lmodelsIsModelReady( lua_State *L ) { + Model *model = uluaGetModel( L, 1 ); + + lua_pushboolean( L, IsModelReady( *model ) ); + + return 1; +} + +/* +> RL.UnloadModel( Model model ) + +Unload model (including meshes) from memory (RAM and/or VRAM) +*/ +int lmodelsUnloadModel( lua_State *L ) { + Model *model = uluaGetModel( L, 1 ); + + UnloadModel( *model ); + + return 0; +} + +/* > RL.DrawModel( Model model, Vector3 position, float scale, Color tint ) Draw a model (With texture if set) @@ -1400,6 +1485,8 @@ int lmodelsSetModelMaterial( lua_State *L ) { int modelMaterialId = luaL_checkinteger( L, 2 ); Material *material = uluaGetMaterial( L, 3 ); + //TODO Could maybe return old shader and textures for storage or get garbage collected? + /* Copy material data instead of using pointer. Pointer would result in double free error. */ model->materials[ modelMaterialId ].shader = material->shader; model->materials[ modelMaterialId ].maps[ MATERIAL_MAP_ALBEDO ] = material->maps[ MATERIAL_MAP_ALBEDO ]; diff --git a/src/state.c b/src/state.c index 6102a2d..b96b557 100644 --- a/src/state.c +++ b/src/state.c @@ -18,6 +18,12 @@ bool stateInit( int argn, const char **argc, const char *exePath ) { state->luaState = NULL; state->logLevelInvalid = LOG_ERROR; +#ifdef GC_UNLOAD + state->gcUnload = true; +#else + state->gcUnload = false; +#endif + InitWindow( state->resolution.x, state->resolution.y, "ReiLua" ); if ( !IsWindowReady() ) { @@ -28,6 +34,8 @@ bool stateInit( int argn, const char **argc, const char *exePath ) { InitAudioDevice(); state->run = luaInit( argn, argc ); } + state->defaultFont = GetFontDefault(); + state->defaultMaterial = LoadMaterialDefault(); return state->run; } @@ -11,10 +11,10 @@ /* > RL.GetFontDefault() -Get the default Font +Get the default Font. Return as lightuserdata */ int ltextGetFontDefault( lua_State *L ) { - uluaPushFont( L, GetFontDefault() ); + lua_pushlightuserdata( L, &state->defaultFont ); return 1; } @@ -97,6 +97,34 @@ int ltextLoadFontFromImage( lua_State *L ) { } /* +> isReady = RL.IsFontReady( Font font ) + +Check if a font is ready + +- Success return bool +*/ +int ltextIsFontReady( lua_State *L ) { + Font *font = uluaGetFont( L, 1 ); + + lua_pushboolean( L, IsFontReady( *font ) ); + + return 1; +} + +/* +> RL.UnloadFont( Font font ) + +Unload font from GPU memory (VRAM) +*/ +int ltextUnloadFont( lua_State *L ) { + Font *font = uluaGetFont( L, 1 ); + + UnloadFont( *font ); + + return 0; +} + +/* ## Text - Draw */ @@ -218,14 +246,15 @@ int ltextGetFontGlyphPadding( lua_State *L ) { /* > texture = RL.GetFontTexture( Font font ) -Get font texture atlas containing the glyphs. +Get font texture atlas containing the glyphs. Returns as lightuserdata - Success return Texture */ int ltextGetFontTexture( lua_State *L ) { Font *font = uluaGetFont( L, 1 ); - uluaPushTexture( L, font->texture ); + // uluaPushTexture( L, font->texture ); + lua_pushlightuserdata( L, &font->texture ); return 1; } diff --git a/src/textures.c b/src/textures.c index abfdf01..9f65ab5 100644 --- a/src/textures.c +++ b/src/textures.c @@ -55,6 +55,34 @@ int ltexturesLoadImageFromScreen( lua_State *L ) { } /* +> isReady = RL.IsImageReady( Image image ) + +Check if an image is ready + +- Success return bool +*/ +int ltextureIsImageReady( lua_State *L ) { + Image *image = uluaGetImage( L, 1 ); + + lua_pushboolean( L, IsImageReady( *image ) ); + + return 1; +} + +/* +> RL.UnloadImage( Image image ) + +Unload image from CPU memory (RAM) +*/ +int ltextureUnloadImage( lua_State *L ) { + Image *image = uluaGetImage( L, 1 ); + + UnloadImage( *image ); + + return 0; +} + +/* > success = RL.ExportImage( Image image, string fileName ) Export image data to file, returns true on success @@ -1042,6 +1070,47 @@ int ltexturesIsTextureReady( lua_State *L ) { } /* +> RL.UnloadTexture( Texture texture ) + +Unload texture from GPU memory (VRAM) +*/ +int ltextureUnloadTexture( lua_State *L ) { + Texture *texture = uluaGetTexture( L, 1 ); + + UnloadTexture( *texture ); + + return 0; +} + +/* +> isReady = RL.IsRenderTextureReady( RenderTexture target ) + +Check if a render texture is ready + +- Success return bool +*/ +int ltexturesIsRenderTextureReady( lua_State *L ) { + RenderTexture *target = uluaGetRenderTexture( L, 1 ); + + lua_pushboolean( L, IsRenderTextureReady( *target ) ); + + return 1; +} + +/* +> RL.UnloadRenderTexture( RenderTexture target ) + +Unload render texture from GPU memory (VRAM) +*/ +int ltextureUnloadRenderTexture( lua_State *L ) { + RenderTexture *target = uluaGetRenderTexture( L, 1 ); + + UnloadRenderTexture( *target ); + + return 0; +} + +/* > RL.UpdateTexture( Texture texture, int{} pixels ) Update GPU texture with new data |
