Skip to content

Commit a3d83f1

Browse files
make lighting example EVEN MORE OO
1 parent 968d095 commit a3d83f1

File tree

1 file changed

+89
-69
lines changed

1 file changed

+89
-69
lines changed

examples/shaders/shaders_basic_lighting.py

Lines changed: 89 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -109,40 +109,71 @@ def MatrixMultiply(left, right):
109109
#// Types and Structures Definition
110110
#//----------------------------------------------------------------------------------
111111

112-
MAX_LIGHTS = 4 #// Max dynamic lights supported by shader
113-
lightsCount = 0
112+
class LightSystem:
113+
MAX_LIGHTS = 4 #// Max dynamic lights supported by shader
114+
lightsCount = 0
115+
lights = []
116+
117+
def __init__(self, ambient = [ 0.2, 0.2, 0.2, 1.0 ], *ls):
118+
self.shader = LoadShader(b"resources/shaders/glsl330/basic_lighting.vs",
119+
b"resources/shaders/glsl330/basic_lighting.fs");
120+
121+
#// Get some shader loactions
122+
self.shader.locs[LOC_MATRIX_MODEL] = GetShaderLocation(self.shader, b"matModel");
123+
self.shader.locs[LOC_VECTOR_VIEW] = GetShaderLocation(self.shader, b"viewPos");
124+
125+
#// ambient light level
126+
self.ambientLoc = GetShaderLocation(self.shader, b"ambient");
127+
v = ffi.new("struct Vector4 *", ambient)
128+
SetShaderValue(self.shader, self.ambientLoc, v, UNIFORM_VEC4);
129+
130+
for light in ls:
131+
self.add(light)
132+
133+
def add(self, light):
134+
light.configure(len(self.lights), self.shader)
135+
self.lights.append(light)
136+
if len(self.lights) > self.MAX_LIGHTS:
137+
raise Exception("Too many lights")
138+
139+
def update(self, cameraPos):
140+
SetShaderValue(self.shader, self.shader.locs[LOC_VECTOR_VIEW], ffi.new("struct Vector3 *",cameraPos), UNIFORM_VEC3)
141+
for light in self.lights:
142+
light.UpdateLightValues()
143+
144+
def draw(self):
145+
for light in self.lights:
146+
if light.enabled:
147+
DrawSphereEx(light.position[0], 0.2, 8, 8, light.color)
148+
149+
114150

115-
#// Light type
116151

117152
LIGHT_DIRECTIONAL=0
118153
LIGHT_POINT=1
119154

120155

121156
class Light:
122-
def __init__(self, type, position, target, color, shader):
123-
global lightsCount
124-
if lightsCount >= MAX_LIGHTS:
125-
raise Exception("Too many lights")
157+
def __init__(self, type, position, target, color):
126158
self.enabled = True
127159
self.type = type
128-
self.position = position
160+
self.position = ffi.new("struct Vector3 *",position)
129161
self.target = target
130162
self.color = color
131-
self.shader = shader
132163

164+
165+
166+
167+
def configure(self, id, shader):
168+
self.shader = shader
133169
#// TODO: Below code doesn't look good to me,
134170
# // it assumes a specific shader naming and structure
135171
# // Probably this implementation could be improved
136-
self.enabledName = f"lights[{lightsCount}].enabled"
137-
self.typeName = f"lights[{lightsCount}].type"
138-
self.posName = f"lights[{lightsCount}].position"
139-
self.targetName = f"lights[{lightsCount}].target"
140-
self.colorName = f"lights[{lightsCount}].color"
141-
# enabledName = '0' + str(lightsCount)
142-
# typeName = '0' + str(lightsCount)
143-
# posName = '0' + str(lightsCount)
144-
# targetName = '0' + str(lightsCount)
145-
# colorName = '0' + str(lightsCount)
172+
self.enabledName = f"lights[{id}].enabled"
173+
self.typeName = f"lights[{id}].type"
174+
self.posName = f"lights[{id}].position"
175+
self.targetName = f"lights[{id}].target"
176+
self.colorName = f"lights[{id}].color"
146177

147178
self.enabledLoc = GetShaderLocation(shader, self.enabledName.encode('utf-8'))
148179
self.typeLoc = GetShaderLocation(shader, self.typeName.encode('utf-8'))
@@ -152,26 +183,25 @@ def __init__(self, type, position, target, color, shader):
152183

153184
self.UpdateLightValues()
154185

155-
lightsCount += 1
156186

157-
#// Send light properties to shader
158-
# // NOTE: Light shader locations should be available
187+
#// Send light properties to shader
188+
#// NOTE: Light shader locations should be available
159189
def UpdateLightValues(self):
160190
#// Send to shader light enabled state and type
161-
SetShaderValue(shader, self.enabledLoc, ffi.new("int *",self.enabled), UNIFORM_INT)
162-
SetShaderValue(shader, self.typeLoc, ffi.new("int *",self.type), UNIFORM_INT)
191+
SetShaderValue(self.shader, self.enabledLoc, ffi.new("int *",self.enabled), UNIFORM_INT)
192+
SetShaderValue(self.shader, self.typeLoc, ffi.new("int *",self.type), UNIFORM_INT)
163193

164194
#// Send to shader light position values
165195
position = [ self.position.x, self.position.y, self.position.z]
166-
SetShaderValue(shader, self.posLoc, ffi.new("struct Vector3 *",position), UNIFORM_VEC3)
196+
SetShaderValue(self.shader, self.posLoc, ffi.new("struct Vector3 *",position), UNIFORM_VEC3)
167197

168198
#// Send to shader light target position values
169199
target =[ self.target.x, self.target.y, self.target.z ]
170-
SetShaderValue(shader, self.targetLoc, ffi.new("struct Vector3 *",target), UNIFORM_VEC3)
200+
SetShaderValue(self.shader, self.targetLoc, ffi.new("struct Vector3 *",target), UNIFORM_VEC3)
171201

172202
#// Send to shader light color values
173203
color = [self.color[0]/255.0, self.color[1]/255.0, self.color[2]/255.0, self.color[3]/255.0]
174-
SetShaderValue(shader, self.colorLoc, ffi.new("struct Vector4 *",color), UNIFORM_VEC4)
204+
SetShaderValue(self.shader, self.colorLoc, ffi.new("struct Vector4 *",color), UNIFORM_VEC4)
175205

176206

177207

@@ -208,34 +238,28 @@ def Vector3Zero():
208238
modelB.materials[0].maps[MAP_DIFFUSE].texture = texture
209239
modelC.materials[0].maps[MAP_DIFFUSE].texture = texture
210240

211-
shader = LoadShader(b"resources/shaders/glsl330/basic_lighting.vs",
212-
b"resources/shaders/glsl330/basic_lighting.fs");
213-
214-
#// Get some shader loactions
215-
shader.locs[LOC_MATRIX_MODEL] = GetShaderLocation(shader, b"matModel");
216-
shader.locs[LOC_VECTOR_VIEW] = GetShaderLocation(shader, b"viewPos");
217241

218-
#// ambient light level
219-
ambientLoc = GetShaderLocation(shader, b"ambient");
220-
v = ffi.new("struct Vector4 *", [ 0.2, 0.2, 0.2, 1.0 ])
221-
SetShaderValue(shader, ambientLoc, v, UNIFORM_VEC4);
222242

223243

224244

225245
angle = 6.282;
226246

227-
#// All models use the same shader
228-
modelA.materials[0].shader = shader
229-
modelB.materials[0].shader = shader
230-
modelC.materials[0].shader = shader
231247

232248
#// Using 4 point lights, white, red, green and blue
233-
lights = [0] * 4
249+
234250
#lights[0] = Light(LIGHT_POINT, ffi.new("struct Vector3 *",[ 400, 400, 400 ]), Vector3Zero(), WHITE, shader)
235-
lights[0] = Light(LIGHT_POINT, ffi.new("struct Vector3 *",[ 4, 2, 4 ]), Vector3Zero(), WHITE, shader)
236-
lights[1] = Light(LIGHT_POINT, ffi.new("struct Vector3 *",[4, 2, 4 ]), Vector3Zero(), RED, shader)
237-
lights[2] = Light(LIGHT_POINT, ffi.new("struct Vector3 *",[ 0, 4, 2 ]), Vector3Zero(), GREEN, shader)
238-
lights[3] = Light(LIGHT_POINT, ffi.new("struct Vector3 *",[ 0, 4, 2 ]), Vector3Zero(), BLUE, shader)
251+
lights0 = Light(LIGHT_POINT, [ 4, 2, 4 ], Vector3Zero(), WHITE)
252+
lights1 = Light(LIGHT_POINT, [4, 2, 4 ], Vector3Zero(), RED)
253+
lights2 = Light(LIGHT_POINT, [ 0, 4, 2 ], Vector3Zero(), GREEN)
254+
lights3 = Light(LIGHT_POINT, [ 0, 4, 2 ], Vector3Zero(), BLUE)
255+
256+
lightSystem = LightSystem([ 0.2, 0.2, 0.2, 1.0 ], lights0, lights1, lights2, lights3)
257+
258+
#// All models use the same shader
259+
modelA.materials[0].shader = lightSystem.shader
260+
modelB.materials[0].shader = lightSystem.shader
261+
modelC.materials[0].shader = lightSystem.shader
262+
239263

240264
SetCameraMode(camera, CAMERA_ORBITAL) #// Set an orbital camera mode
241265

@@ -246,28 +270,28 @@ def Vector3Zero():
246270
while not WindowShouldClose(): #// Detect window close button or ESC key
247271
#// Update
248272
#//----------------------------------------------------------------------------------
249-
if IsKeyPressed(KEY_W): lights[0].enabled = not lights[0].enabled
250-
if IsKeyPressed(KEY_R): lights[1].enabled = not lights[1].enabled
251-
if IsKeyPressed(KEY_G): lights[2].enabled = not lights[2].enabled
252-
if IsKeyPressed(KEY_B): lights[3].enabled = not lights[3].enabled
273+
if IsKeyPressed(KEY_W): lights0.enabled = not lights0.enabled
274+
if IsKeyPressed(KEY_R): lights1.enabled = not lights1.enabled
275+
if IsKeyPressed(KEY_G): lights2.enabled = not lights2.enabled
276+
if IsKeyPressed(KEY_B): lights3.enabled = not lights3.enabled
253277

254278
UpdateCamera(cameraPtr); #// Update camera
255279

256280
#// Make the lights do differing orbits
257281
angle -= 0.02
258-
lights[0].position.x = math.cos(angle)*4.0
259-
lights[0].position.z = math.sin(angle)*4.0
260-
lights[1].position.x = math.cos(-angle*0.6)*4.0
261-
lights[1].position.z = math.sin(-angle*0.6)*4.0
262-
lights[2].position.y = math.cos(angle*0.2)*4.0
263-
lights[2].position.z = math.sin(angle*0.2)*4.0
264-
lights[3].position.y = math.cos(-angle*0.35)*4.0
265-
lights[3].position.z = math.sin(-angle*0.35)*4.0
282+
lights0.position.x = math.cos(angle)*4.0
283+
lights0.position.z = math.sin(angle)*4.0
284+
lights1.position.x = math.cos(-angle*0.6)*4.0
285+
lights1.position.z = math.sin(-angle*0.6)*4.0
286+
lights2.position.y = math.cos(angle*0.2)*4.0
287+
lights2.position.z = math.sin(angle*0.2)*4.0
288+
lights3.position.y = math.cos(-angle*0.35)*4.0
289+
lights3.position.z = math.sin(-angle*0.35)*4.0
290+
291+
#// Update the light shader with the camera view position
292+
293+
lightSystem.update(camera.position)
266294

267-
lights[0].UpdateLightValues()
268-
lights[1].UpdateLightValues()
269-
lights[2].UpdateLightValues()
270-
lights[3].UpdateLightValues()
271295

272296

273297
#// Rotate the torus
@@ -277,9 +301,7 @@ def Vector3Zero():
277301

278302

279303

280-
#// Update the light shader with the camera view position
281-
cameraPos = [ camera.position.x, camera.position.y, camera.position.z ]
282-
SetShaderValue(shader, shader.locs[LOC_VECTOR_VIEW], ffi.new("struct Vector3 *",cameraPos), UNIFORM_VEC3)
304+
283305
#//----------------------------------------------------------------------------------
284306

285307
#// Draw
@@ -296,10 +318,8 @@ def Vector3Zero():
296318
DrawModel(modelC, [ 1.6,0,0], 1.0, WHITE)
297319

298320
#// Draw markers to show where the lights are
299-
if lights[0].enabled: DrawSphereEx(lights[0].position[0], 0.2, 8, 8, WHITE)
300-
if lights[1].enabled: DrawSphereEx(lights[1].position[0], 0.2, 8, 8, RED)
301-
if lights[2].enabled: DrawSphereEx(lights[2].position[0], 0.2, 8, 8, GREEN)
302-
if lights[3].enabled: DrawSphereEx(lights[3].position[0], 0.2, 8, 8, BLUE)
321+
lightSystem.draw()
322+
303323

304324
DrawGrid(10, 1.0)
305325

0 commit comments

Comments
 (0)