This repository has been archived on 2025-06-21. You can view files and clone it, but you cannot make any changes to it's state, such as pushing and creating new issues, pull requests or comments.
raylib-python-cffi/examples/shaders/light_system.py
2024-11-16 20:11:08 +00:00

99 lines
3.8 KiB
Python

import raylib as rl
class LightSystem:
MAX_LIGHTS = 4 #// Max dynamic lights supported by shader
lightsCount = 0
lights: list['Light'] = []
def __init__(self, ambient = [ 0.2, 0.2, 0.2, 1.0 ], *ls):
self.shader = rl.LoadShader(b"resources/shaders/fogLight.vs",
b"resources/shaders/fogLight.fs");
#// Get some shader loactions
self.shader.locs[rl.SHADER_LOC_MATRIX_MODEL] = rl.GetShaderLocation(self.shader, b"matModel")
self.shader.locs[rl.SHADER_LOC_VECTOR_VIEW] = rl.GetShaderLocation(self.shader, b"viewPos")
#// ambient light level
self.ambientLoc = rl.GetShaderLocation(self.shader, b"ambient")
v = rl.ffi.new("struct Vector4 *", ambient)
rl.SetShaderValue(self.shader, self.ambientLoc, v, rl.SHADER_UNIFORM_VEC4)
for light in ls:
self.add(light)
def add(self, light):
light.configure(len(self.lights), self.shader)
self.lights.append(light)
if len(self.lights) > self.MAX_LIGHTS:
raise Exception("Too many lights")
def update(self, cameraPos):
rl.SetShaderValue(self.shader, self.shader.locs[rl.SHADER_LOC_VECTOR_VIEW], rl.ffi.new("struct Vector3 *",cameraPos), rl.SHADER_UNIFORM_VEC3)
for light in self.lights:
light.UpdateLightValues()
def draw(self):
for light in self.lights:
if light.enabled:
rl.DrawSphereEx(light.position[0], 0.2, 8, 8, light.color)
LIGHT_DIRECTIONAL=0
LIGHT_POINT=1
class Light:
def __init__(self, type, position, target, color):
self.enabled = True
self.type = type
self.position = rl.ffi.new("struct Vector3 *",position)
self.target = target
self.color = color
def configure(self, id, shader):
self.shader = shader
#// TODO: Below code doesn't look good to me,
#// it assumes a specific shader naming and structure
#// Probably this implementation could be improved
self.enabledName = f"lights[{id}].enabled"
self.typeName = f"lights[{id}].type"
self.posName = f"lights[{id}].position"
self.targetName = f"lights[{id}].target"
self.colorName = f"lights[{id}].color"
self.enabledLoc = rl.GetShaderLocation(shader, self.enabledName.encode('utf-8'))
self.typeLoc = rl.GetShaderLocation(shader, self.typeName.encode('utf-8'))
self.posLoc = rl.GetShaderLocation(shader, self.posName.encode('utf-8'))
self.targetLoc = rl.GetShaderLocation(shader, self.targetName.encode('utf-8'))
self.colorLoc = rl.GetShaderLocation(shader, self.colorName.encode('utf-8'))
self.UpdateLightValues()
#// Send light properties to shader
#// NOTE: Light shader locations should be available
def UpdateLightValues(self):
#// Send to shader light enabled state and type
rl.SetShaderValue(self.shader, self.enabledLoc, rl.ffi.new("int *",self.enabled), rl.SHADER_UNIFORM_INT)
rl.SetShaderValue(self.shader, self.typeLoc, rl.ffi.new("int *",self.type), rl.SHADER_UNIFORM_INT)
#// Send to shader light position values
position = [ self.position.x, self.position.y, self.position.z]
rl.SetShaderValue(self.shader, self.posLoc, rl.ffi.new("struct Vector3 *",position), rl.SHADER_UNIFORM_VEC3)
#// Send to shader light target position values
target =[ self.target.x, self.target.y, self.target.z ]
rl.SetShaderValue(self.shader, self.targetLoc, rl.ffi.new("struct Vector3 *",target), rl.SHADER_UNIFORM_VEC3)
#// Send to shader light color values
color = [self.color[0]/255.0, self.color[1]/255.0, self.color[2]/255.0, self.color[3]/255.0]
rl.SetShaderValue(self.shader, self.colorLoc, rl.ffi.new("struct Vector4 *",color), rl.SHADER_UNIFORM_VEC4)