diff options
| -rw-r--r-- | API.md | 90 | ||||
| -rw-r--r-- | ReiLua_API.lua | 75 | ||||
| -rw-r--r-- | changelog | 1 | ||||
| -rw-r--r-- | devnotes | 4 | ||||
| -rw-r--r-- | examples/basic_lighting/main.lua | 140 | ||||
| -rw-r--r-- | examples/free_camera3d/main.lua | 1 | ||||
| -rw-r--r-- | examples/resources/lib/raygui.lua | 5 | ||||
| -rw-r--r-- | examples/resources/shaders/glsl330/base.fs | 25 | ||||
| -rw-r--r-- | examples/resources/shaders/glsl330/base.vs | 26 | ||||
| -rw-r--r-- | examples/resources/shaders/glsl330/lighting.vs | 32 | ||||
| -rw-r--r-- | include/lights.h | 10 | ||||
| -rw-r--r-- | src/lights.c | 260 | ||||
| -rw-r--r-- | src/lua_core.c | 10 |
13 files changed, 674 insertions, 5 deletions
@@ -6520,6 +6520,96 @@ Send light properties to shader --- +> success = RL.SetLightType( Light light, int type ) + +Set light type + +- Failure return false +- Success return true + +--- + +> success = RL.SetLightPosition( Light light, Vector3 position ) + +Set light position + +- Failure return false +- Success return true + +--- + +> success = RL.SetLightTarget( Light light, Vector3 target ) + +Set light target + +- Failure return false +- Success return true + +--- + +> success = RL.SetLightColor( Light light, Color color ) + +Set light color + +- Failure return false +- Success return true + +--- + +> success = RL.SetLightEnabled( Light light, bool enabled ) + +Set light enabled + +- Failure return false +- Success return true + +--- + +> type = RL.GetLightType( Light light ) + +Get light type + +- Failure return false +- Success return int + +--- + +> position = RL.GetLightPosition( Light light ) + +Get light position + +- Failure return false +- Success return Vector3 + +--- + +> target = RL.GetLightTarget( Light light ) + +Get light target + +- Failure return false +- Success return Vector3 + +--- + +> color = RL.GetLightColor( Light light ) + +Get light color + +- Failure return false +- Success return Color + +--- + +> enabled = RL.IsLightEnabled( Light light ) + +Get light enabled + +- Failure return nil +- Success return boolean + +--- + ## RLGL - General render state --- diff --git a/ReiLua_API.lua b/ReiLua_API.lua index 0ace7f4..54ab8ba 100644 --- a/ReiLua_API.lua +++ b/ReiLua_API.lua @@ -5335,6 +5335,81 @@ function RL.CreateLight( type, position, target, color, shader ) end ---@return any success function RL.UpdateLightValues( shader, light ) end +---Set light type +---- Failure return false +---- Success return true +---@param light any +---@param type integer +---@return any success +function RL.SetLightType( light, type ) end + +---Set light position +---- Failure return false +---- Success return true +---@param light any +---@param position table +---@return any success +function RL.SetLightPosition( light, position ) end + +---Set light target +---- Failure return false +---- Success return true +---@param light any +---@param target table +---@return any success +function RL.SetLightTarget( light, target ) end + +---Set light color +---- Failure return false +---- Success return true +---@param light any +---@param color table +---@return any success +function RL.SetLightColor( light, color ) end + +---Set light enabled +---- Failure return false +---- Success return true +---@param light any +---@param enabled boolean +---@return any success +function RL.SetLightEnabled( light, enabled ) end + +---Get light type +---- Failure return false +---- Success return int +---@param light any +---@return any type +function RL.GetLightType( light ) end + +---Get light position +---- Failure return false +---- Success return Vector3 +---@param light any +---@return any position +function RL.GetLightPosition( light ) end + +---Get light target +---- Failure return false +---- Success return Vector3 +---@param light any +---@return any target +function RL.GetLightTarget( light ) end + +---Get light color +---- Failure return false +---- Success return Color +---@param light any +---@return any color +function RL.GetLightColor( light ) end + +---Get light enabled +---- Failure return nil +---- Success return boolean +---@param light any +---@return any enabled +function RL.IsLightEnabled( light ) end + -- RLGL - General render state ---Enable color blending @@ -13,6 +13,7 @@ KEY CHANGES: - CHANGED: Can now have multiple Music objects like other Raylib objects instead of just one. - CHANGED: Texture now can be either Texture or RenderTexture. No need to change texture source anymore. - ADDED: Material getter functions. + - ADDED: Light property functions. Detailed changes: - FIXED: uluaGetRay was looking for integers instead of tables. @@ -1,11 +1,9 @@ Current { - * Review GenMeshCustom indices. } Backlog { * Platformer example physics process for true framerate independence. * Extend color lib functionality. - * Tilemap clib. Fast tilemap draw and clib example. * IsWaveReady and other Is* ready functions. * Text @@ -23,7 +21,7 @@ Backlog { * ImageBlurGaussian * Models * LoadMaterials - * DrawBillboardPro + * Needs Testing * UpdateTexture * UpdateTextureRec diff --git a/examples/basic_lighting/main.lua b/examples/basic_lighting/main.lua new file mode 100644 index 0000000..5db21b3 --- /dev/null +++ b/examples/basic_lighting/main.lua @@ -0,0 +1,140 @@ +-- Based on raylib [shaders] example - basic lighting by Chris Camacho (@codifies) +-- https://github.com/TSnake41/raylib-lua/blob/master/examples/textures_bunnymark.lua + +package.path = package.path..";"..RL.GetBasePath().."../resources/lib/?.lua" + +Util = require( "utillib" ) +Vec2 = require( "vector2" ) +Vec3 = require( "vector3" ) +Cam3D = require( "camera3d" ) + +local monitor = 0 +local camera = {} + +local plane = -1 +local cube = -1 +local material = -1 +local shader = -1 +local lights = {} + +function RL.init() + local mPos = Vec2:new( RL.GetMonitorPosition( monitor ) ) + local mSize = Vec2:new( RL.GetMonitorSize( monitor ) ) + local winSize = Vec2:new( 1028, 720 ) + + RL.SetWindowTitle( "Simple Lighting" ) + RL.SetWindowState( RL.FLAG_WINDOW_RESIZABLE ) + RL.SetWindowState( 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 } ) + + -- Define the camera to look into our 3d world. + camera = Cam3D:new() + + camera:setPosition( { 0, 4, 12 } ) + camera:setTarget( { 0, 0, 0 } ) + camera:setUp( { 0, 1, 0 } ) + -- camera.mode = camera.MODES.ORBITAL + camera.mode = camera.MODES.FIRST_PERSON + + RL.HideCursor() + + -- Generate meshes. + plane = RL.GenMeshPlane( 10, 10, 3, 3 ) + cube = RL.GenMeshCube( { 2, 4, 2 } ) + + -- Load basic lighting shader. + -- NOTE: Shaders used in this example are #version 330 (OpenGL 3.3). + + -- Shader folders. + local glslDir = { + -- [ RL.RL_OPENGL_11 ] = "glsl100", + -- [ RL.RL_OPENGL_21 ] = "glsl120", + [ RL.RL_OPENGL_33 ] = "glsl330", + [ RL.RL_OPENGL_43 ] = "glsl330", + -- [ RL.RL_OPENGL_ES_20 ] = "glsl120", + } + local prefix = RL.GetBasePath().."../resources/shaders/"..glslDir[ RL.rlGetVersion() ].."/" + + shader = RL.LoadShader( prefix.."lighting.vs", prefix.."lighting.fs" ) + + -- Get some required shader locations. + local viewPosLoc = RL.GetShaderLocation( shader, "viewPos" ) + RL.SetShaderLocationIndex( shader, RL.SHADER_LOC_VECTOR_VIEW, viewPosLoc ) + --[[ + NOTE: "matModel" location name is automatically assigned on shader loading, + no need to get the location again if using that uniform name. + ]]-- + + -- Ambient light level (some basic lighting). + local ambientLoc = RL.GetShaderLocation( shader, "ambient" ) + RL.SetShaderValue( shader, ambientLoc, { 0.1, 0.1, 0.1, 1.0 }, RL.SHADER_UNIFORM_VEC4 ) + + -- Create material. + local materialData = { + shader = shader, + maps = { + { + RL.MATERIAL_MAP_ALBEDO, + { + color = RL.WHITE, + }, + }, + }, + } + material = RL.CreateMaterial( materialData ) + + -- Create lights. + table.insert( lights, RL.CreateLight( RL.LIGHT_POINT, { -2, 1, -2 }, RL.Vector3Zero(), RL.YELLOW, shader ) ) + table.insert( lights, RL.CreateLight( RL.LIGHT_POINT, { 2, 1, 2 }, RL.Vector3Zero(), RL.RED, shader ) ) + table.insert( lights, RL.CreateLight( RL.LIGHT_POINT, { -2, 1, 2 }, RL.Vector3Zero(), RL.GREEN, shader ) ) + table.insert( lights, RL.CreateLight( RL.LIGHT_POINT, { 2, 1, -2 }, RL.Vector3Zero(), RL.BLUE, shader ) ) +end + +function RL.process( delta ) + camera:process( delta ) + + -- Check key inputs to enable/disable lights. + if RL.IsKeyPressed( RL.KEY_Y ) then + RL.SetLightEnabled( lights[1], not RL.IsLightEnabled( lights[1] ) ) + end + if RL.IsKeyPressed( RL.KEY_R ) then + RL.SetLightEnabled( lights[2], not RL.IsLightEnabled( lights[2] ) ) + end + if RL.IsKeyPressed( RL.KEY_G ) then + RL.SetLightEnabled( lights[3], not RL.IsLightEnabled( lights[3] ) ) + end + if RL.IsKeyPressed( RL.KEY_B ) then + RL.SetLightEnabled( lights[4], not RL.IsLightEnabled( lights[4] ) ) + end + + -- Update light values (actually, only enable/disable them). + for _, light in ipairs( lights ) do + RL.UpdateLightValues( shader, light ) + end +end + +function RL.draw() + RL.ClearBackground( { 100, 150, 100 } ) + + -- Update the shader with the camera view vector (points towards { 0.0f, 0.0f, 0.0f }). + local loc = RL.GetShaderLocationIndex( shader, RL.SHADER_LOC_VECTOR_VIEW ) + RL.SetShaderValue( shader, loc, camera:getPosition():arr(), RL.SHADER_UNIFORM_VEC3 ) + + camera:beginMode3D() + RL.DrawMesh( plane, material, RL.MatrixIdentity() ) + RL.DrawMesh( cube, material, RL.MatrixIdentity() ) + + -- Draw spheres to show where the lights are. + for _, light in ipairs( lights ) do + if RL.IsLightEnabled( light ) then + RL.DrawSphereEx( RL.GetLightPosition( light ), 0.2, 8, 8, RL.GetLightColor( light ) ) + else + RL.DrawSphereWires( RL.GetLightPosition( light ), 0.2, 8, 8, RL.ColorAlpha( RL.GetLightColor( light ), 0.3 ) ) + end + end + + camera:endMode3D() + + RL.DrawText( 0, "Use keys [Y][R][G][B] to toggle lights", { 10, 10 }, 20, 4, RL.DARKGRAY ) +end diff --git a/examples/free_camera3d/main.lua b/examples/free_camera3d/main.lua index 0945daf..be3195c 100644 --- a/examples/free_camera3d/main.lua +++ b/examples/free_camera3d/main.lua @@ -27,7 +27,6 @@ function RL.init() camera:setUp( { 0, 1, 0 } ) -- camera.mode = camera.MODES.ORBITAL camera.mode = camera.MODES.FREE - -- camera.mode = camera.MODES.FIRST_PERSON end function RL.process( delta ) diff --git a/examples/resources/lib/raygui.lua b/examples/resources/lib/raygui.lua index 1ebb3f0..69f5694 100644 --- a/examples/resources/lib/raygui.lua +++ b/examples/resources/lib/raygui.lua @@ -47,7 +47,7 @@ end -- Raygui. -Raygui = { +local Raygui = { RAYGUI_WINDOWBOX_STATUSBAR_HEIGHT = 24, elements = {}, @@ -64,6 +64,9 @@ function Raygui.process() return end + -- Focused is 0 if not over any element. + Raygui.focused = 0 + for i = #Raygui.elements, 1, -1 do local element = Raygui.elements[i] diff --git a/examples/resources/shaders/glsl330/base.fs b/examples/resources/shaders/glsl330/base.fs new file mode 100644 index 0000000..6b50062 --- /dev/null +++ b/examples/resources/shaders/glsl330/base.fs @@ -0,0 +1,25 @@ +#version 330 + +// Input vertex attributes (from vertex shader) +in vec2 fragTexCoord; +in vec4 fragColor; + +// Input uniform values +uniform sampler2D texture0; +uniform vec4 colDiffuse; + +// Output fragment color +out vec4 finalColor; + +// NOTE: Add here your custom variables + +void main() +{ + // Texel color fetching from texture sampler + vec4 texelColor = texture(texture0, fragTexCoord); + + // NOTE: Implement here your fragment shader code + + finalColor = texelColor*colDiffuse; +} + diff --git a/examples/resources/shaders/glsl330/base.vs b/examples/resources/shaders/glsl330/base.vs new file mode 100644 index 0000000..8cc2abb --- /dev/null +++ b/examples/resources/shaders/glsl330/base.vs @@ -0,0 +1,26 @@ +#version 330 + +// Input vertex attributes +in vec3 vertexPosition; +in vec2 vertexTexCoord; +in vec3 vertexNormal; +in vec4 vertexColor; + +// Input uniform values +uniform mat4 mvp; + +// Output vertex attributes (to fragment shader) +out vec2 fragTexCoord; +out vec4 fragColor; + +// NOTE: Add here your custom variables + +void main() +{ + // Send vertex attributes to fragment shader + fragTexCoord = vertexTexCoord; + fragColor = vertexColor; + + // Calculate final vertex position + gl_Position = mvp*vec4(vertexPosition, 1.0); +}
\ No newline at end of file diff --git a/examples/resources/shaders/glsl330/lighting.vs b/examples/resources/shaders/glsl330/lighting.vs new file mode 100644 index 0000000..f8ec45f --- /dev/null +++ b/examples/resources/shaders/glsl330/lighting.vs @@ -0,0 +1,32 @@ +#version 330 + +// Input vertex attributes +in vec3 vertexPosition; +in vec2 vertexTexCoord; +in vec3 vertexNormal; +in vec4 vertexColor; + +// Input uniform values +uniform mat4 mvp; +uniform mat4 matModel; +uniform mat4 matNormal; + +// Output vertex attributes (to fragment shader) +out vec3 fragPosition; +out vec2 fragTexCoord; +out vec4 fragColor; +out vec3 fragNormal; + +// NOTE: Add here your custom variables + +void main() +{ + // Send vertex attributes to fragment shader + fragPosition = vec3(matModel*vec4(vertexPosition, 1.0)); + fragTexCoord = vertexTexCoord; + fragColor = vertexColor; + fragNormal = normalize(vec3(matNormal*vec4(vertexNormal, 1.0))); + + // Calculate final vertex position + gl_Position = mvp*vec4(vertexPosition, 1.0); +} diff --git a/include/lights.h b/include/lights.h index 2b483b3..1268d86 100644 --- a/include/lights.h +++ b/include/lights.h @@ -5,3 +5,13 @@ bool validLight( size_t id ); /* Basics. */ int llightsCreateLight( lua_State *L ); int llightsUpdateLightValues( lua_State *L ); +int llightsSetLightType( lua_State *L ); +int llightsSetLightPosition( lua_State *L ); +int llightsSetLightTarget( lua_State *L ); +int llightsSetLightColor( lua_State *L ); +int llightsSetLightEnabled( lua_State *L ); +int llightsGetLightType( lua_State *L ); +int llightsGetLightPosition( lua_State *L ); +int llightsGetLightTarget( lua_State *L ); +int llightsGetLightColor( lua_State *L ); +int llightsIsLightEnabled( lua_State *L ); diff --git a/src/lights.c b/src/lights.c index 180cbd1..70ac011 100644 --- a/src/lights.c +++ b/src/lights.c @@ -108,3 +108,263 @@ int llightsUpdateLightValues( lua_State *L ) { return 1; } + +/* +> success = RL.SetLightType( Light light, int type ) + +Set light type + +- Failure return false +- Success return true +*/ +int llightsSetLightType( lua_State *L ) { + if ( !lua_isnumber( L, 1 ) || !lua_isnumber( L, 2 ) ) { + TraceLog( LOG_WARNING, "%s", "Bad call of function. RL.SetLightType( Light light, int type )" ); + lua_pushboolean( L, false ); + return 1; + } + size_t lightId = lua_tointeger( L, 1 ); + int type = lua_tointeger( L, 2 ); + + if ( !validLight( lightId ) ) { + lua_pushboolean( L, false ); + return 1; + } + state->lights[ lightId ]->type = type; + lua_pushboolean( L, true ); + + return 1; +} + +/* +> success = RL.SetLightPosition( Light light, Vector3 position ) + +Set light position + +- Failure return false +- Success return true +*/ +int llightsSetLightPosition( lua_State *L ) { + if ( !lua_isnumber( L, 1 ) || !lua_istable( L, 2 ) ) { + TraceLog( LOG_WARNING, "%s", "Bad call of function. RL.SetLightPosition( Light light, Vecto3 position )" ); + lua_pushboolean( L, false ); + return 1; + } + size_t lightId = lua_tointeger( L, 1 ); + Vector3 position = uluaGetVector3Index( L, 2 ); + + if ( !validLight( lightId ) ) { + lua_pushboolean( L, false ); + return 1; + } + state->lights[ lightId ]->position = position; + lua_pushboolean( L, true ); + + return 1; +} + +/* +> success = RL.SetLightTarget( Light light, Vector3 target ) + +Set light target + +- Failure return false +- Success return true +*/ +int llightsSetLightTarget( lua_State *L ) { + if ( !lua_isnumber( L, 1 ) || !lua_istable( L, 2 ) ) { + TraceLog( LOG_WARNING, "%s", "Bad call of function. RL.SetLightTarget( Light light, Vecto3 target )" ); + lua_pushboolean( L, false ); + return 1; + } + size_t lightId = lua_tointeger( L, 1 ); + Vector3 target = uluaGetVector3Index( L, 2 ); + + if ( !validLight( lightId ) ) { + lua_pushboolean( L, false ); + return 1; + } + state->lights[ lightId ]->target = target; + lua_pushboolean( L, true ); + + return 1; +} + +/* +> success = RL.SetLightColor( Light light, Color color ) + +Set light color + +- Failure return false +- Success return true +*/ +int llightsSetLightColor( lua_State *L ) { + if ( !lua_isnumber( L, 1 ) || !lua_istable( L, 2 ) ) { + TraceLog( LOG_WARNING, "%s", "Bad call of function. RL.SetLightColor( Light light, Color color )" ); + lua_pushboolean( L, false ); + return 1; + } + size_t lightId = lua_tointeger( L, 1 ); + Color color = uluaGetColorIndex( L, 2 ); + + if ( !validLight( lightId ) ) { + lua_pushboolean( L, false ); + return 1; + } + state->lights[ lightId ]->color = color; + lua_pushboolean( L, true ); + + return 1; +} + +/* +> success = RL.SetLightEnabled( Light light, bool enabled ) + +Set light enabled + +- Failure return false +- Success return true +*/ +int llightsSetLightEnabled( lua_State *L ) { + if ( !lua_isnumber( L, 1 ) || !lua_isboolean( L, 2 ) ) { + TraceLog( LOG_WARNING, "%s", "Bad call of function. RL.SetLightEnabled( Light light, bool enabled )" ); + lua_pushboolean( L, false ); + return 1; + } + size_t lightId = lua_tointeger( L, 1 ); + bool enabled = lua_toboolean( L, 2 ); + + if ( !validLight( lightId ) ) { + lua_pushboolean( L, false ); + return 1; + } + state->lights[ lightId ]->enabled = enabled; + lua_pushboolean( L, true ); + + return 1; +} + +/* +> type = RL.GetLightType( Light light ) + +Get light type + +- Failure return false +- Success return int +*/ +int llightsGetLightType( lua_State *L ) { + if ( !lua_isnumber( L, 1 ) ) { + TraceLog( LOG_WARNING, "%s", "Bad call of function. RL.GetLightType( Light light )" ); + lua_pushboolean( L, false ); + return 1; + } + size_t lightId = lua_tointeger( L, 1 ); + + if ( !validLight( lightId ) ) { + lua_pushboolean( L, false ); + return 1; + } + lua_pushinteger( L, state->lights[ lightId ]->type ); + + return 1; +} + +/* +> position = RL.GetLightPosition( Light light ) + +Get light position + +- Failure return false +- Success return Vector3 +*/ +int llightsGetLightPosition( lua_State *L ) { + if ( !lua_isnumber( L, 1 ) ) { + TraceLog( LOG_WARNING, "%s", "Bad call of function. RL.GetLightPosition( Light light )" ); + lua_pushboolean( L, false ); + return 1; + } + size_t lightId = lua_tointeger( L, 1 ); + + if ( !validLight( lightId ) ) { + lua_pushboolean( L, false ); + return 1; + } + uluaPushVector3( L, state->lights[ lightId ]->position ); + + return 1; +} + +/* +> target = RL.GetLightTarget( Light light ) + +Get light target + +- Failure return false +- Success return Vector3 +*/ +int llightsGetLightTarget( lua_State *L ) { + if ( !lua_isnumber( L, 1 ) ) { + TraceLog( LOG_WARNING, "%s", "Bad call of function. RL.GetLightTarget( Light light )" ); + lua_pushboolean( L, false ); + return 1; + } + size_t lightId = lua_tointeger( L, 1 ); + + if ( !validLight( lightId ) ) { + lua_pushboolean( L, false ); + return 1; + } + uluaPushVector3( L, state->lights[ lightId ]->target ); + + return 1; +} + +/* +> color = RL.GetLightColor( Light light ) + +Get light color + +- Failure return false +- Success return Color +*/ +int llightsGetLightColor( lua_State *L ) { + if ( !lua_isnumber( L, 1 ) ) { + TraceLog( LOG_WARNING, "%s", "Bad call of function. RL.GetLightColor( Light light )" ); + lua_pushboolean( L, false ); + return 1; + } + size_t lightId = lua_tointeger( L, 1 ); + + if ( !validLight( lightId ) ) { + lua_pushboolean( L, false ); + return 1; + } + uluaPushColor( L, state->lights[ lightId ]->color ); + + return 1; +} + +/* +> enabled = RL.IsLightEnabled( Light light ) + +Get light enabled + +- Failure return nil +- Success return boolean +*/ +int llightsIsLightEnabled( lua_State *L ) { + if ( !lua_isnumber( L, 1 ) ) { + TraceLog( LOG_WARNING, "%s", "Bad call of function. RL.IsLightEnabled( Light light )" ); + lua_pushnil( L ); + return 1; + } + size_t lightId = lua_tointeger( L, 1 ); + + if ( !validLight( lightId ) ) { + lua_pushnil( L ); + return 1; + } + lua_pushboolean( L, state->lights[ lightId ]->enabled ); + + return 1; +} diff --git a/src/lua_core.c b/src/lua_core.c index a65c95a..e14395c 100644 --- a/src/lua_core.c +++ b/src/lua_core.c @@ -1358,6 +1358,16 @@ void luaRegister() { /* Basics. */ assingGlobalFunction( "CreateLight", llightsCreateLight ); assingGlobalFunction( "UpdateLightValues", llightsUpdateLightValues ); + assingGlobalFunction( "SetLightType", llightsSetLightType ); + assingGlobalFunction( "SetLightPosition", llightsSetLightPosition ); + assingGlobalFunction( "SetLightTarget", llightsSetLightTarget ); + assingGlobalFunction( "SetLightColor", llightsSetLightColor ); + assingGlobalFunction( "SetLightEnabled", llightsSetLightEnabled ); + assingGlobalFunction( "GetLightType", llightsGetLightType ); + assingGlobalFunction( "GetLightPosition", llightsGetLightPosition ); + assingGlobalFunction( "GetLightTarget", llightsGetLightTarget ); + assingGlobalFunction( "GetLightColor", llightsGetLightColor ); + assingGlobalFunction( "IsLightEnabled", llightsIsLightEnabled ); /* RLGL */ /* General render state. */ |
