currently this is what I am doing:
class ManyLightsManager():
def __init__(self, render, max_lights = 100):
self.MAX_LIGHTS = max_lights
width = self.MAX_LIGHTS
self.render = render
self.spotlight_data = np.zeros((self.MAX_LIGHTS * 4, 4), dtype=np.float32)
self.spotlight_buffer = glGenBuffers(1)
glBindBuffer(GL_UNIFORM_BUFFER, self.spotlight_buffer)
glBufferData(GL_UNIFORM_BUFFER, self.spotlight_data.nbytes, self.spotlight_data, GL_DYNAMIC_DRAW)
glBindBufferBase(GL_UNIFORM_BUFFER, 0, self.spotlight_buffer)
glBindBuffer(GL_UNIFORM_BUFFER, 0)
self.spotlights = []
self.spotlight_index_count = 0
self.spotlight_task_sequence = []
def re_input(self):
pass
def update_lights_transforms(self):
glBindBuffer(GL_UNIFORM_BUFFER, self.spotlight_buffer)
for i, light in enumerate(self.spotlights):
index = i * 4
pos = light._lightnp.getPos(self.render)
self.spotlight_data[index, :3] = [pos[0], pos[1], pos[2]]
#self.spotlight_data[index+1] = [light._light_color[0], light._light_color[1], light._light_color[2], 0.0]
dir = light._lightnp.getQuat(self.render).getForward()
self.spotlight_data[index+2, :3] = [dir[0], dir[1], dir[2]]
#self.spotlight_data [index+3] = [light._light.attenuation[0], light._light.attenuation[1], light._light.attenuation[2], 1.0]
glBufferSubData(GL_UNIFORM_BUFFER, (index + 0) * 4 * 4, self.spotlight_data[index].nbytes, self.spotlight_data[index])
#glBufferSubData(GL_UNIFORM_BUFFER, (index + 1) * 4 * 4, self.spotlight_data[index+1].nbytes, self.spotlight_data[index+1])
glBufferSubData(GL_UNIFORM_BUFFER, (index + 2) * 4 * 4, self.spotlight_data[index+2].nbytes, self.spotlight_data[index+2])
#glBufferSubData(GL_UNIFORM_BUFFER, (index + 3) * 4 * 4, self.spotlight_data[index+3].nbytes, self.spotlight_data[index+3])
glBindBuffer(GL_UNIFORM_BUFFER, 0)
self.render.setShaderInput('SpotLightCount', len(self.spotlights))
def add_spotlight(self, light):
self.spotlights.append(light)
def remove_spotlight(self, light):
self.spotlights.remove(light)
def change_spotlight_fov(self, light):
glBindBuffer(GL_UNIFORM_BUFFER, self.spotlight_buffer)
cos = math.cos(math.radians(light._light.getLens().get_fov()[0] * 0.5))
index = self.spotlights.index(light) * 4
self.spotlight_data[index+2, 3] = cos
glBindBuffer(GL_UNIFORM_BUFFER, 0)
#print('CHANGING FOV!', cos)
def change_spotlight_color(self, light):
glBindBuffer(GL_UNIFORM_BUFFER, self.spotlight_buffer)
index = self.spotlights.index(light) * 4
self.spotlight_data[index+1, :3] = [light._light_color[0], light._light_color[1], light._light_color[2]]
glBufferSubData(GL_UNIFORM_BUFFER, (index + 1) * 4 * 4, self.spotlight_data[index + 1].nbytes,self.spotlight_data[index + 1])
glBindBuffer(GL_UNIFORM_BUFFER, 0)
#print('CHANGING COLOR!')
def change_spotlight_exponent(self, light):
glBindBuffer(GL_UNIFORM_BUFFER, self.spotlight_buffer)
#print('CHANGING EXPONENT!')
index = self.spotlights.index(light) * 4
self.spotlight_data[index + 1, 3] = light._light.getExponent()
glBufferSubData(GL_UNIFORM_BUFFER, (index + 1) * 4 * 4, self.spotlight_data[index + 1].nbytes,self.spotlight_data[index + 1])
glBindBuffer(GL_UNIFORM_BUFFER, 0)
def change_spotlight_attenuation(self, light):
glBindBuffer(GL_UNIFORM_BUFFER, self.spotlight_buffer)
#print('CHANGING ATTENUATION!')
index = self.spotlights.index(light) * 4
self.spotlight_data[index+3, :3] = [light._light.attenuation[0], light._light.attenuation[1], light._light.attenuation[2]]
glBufferSubData(GL_UNIFORM_BUFFER, (index + 3) * 4 * 4, self.spotlight_data[index + 3].nbytes,self.spotlight_data[index + 3])
glBindBuffer(GL_UNIFORM_BUFFER, 0)
def change_spotlight_on(self, light):
glBindBuffer(GL_UNIFORM_BUFFER, self.spotlight_buffer)
#print('CHANGING LIGHT ON / OFF!')
index = self.spotlights.index(light) * 4
self.spotlight_data[index, 3] = float(light._on)
glBindBuffer(GL_UNIFORM_BUFFER, 0)
glsl shader code:
uniform sampler2DArray SpotLightShadows;
struct PointLightParameters {
vec4 position_on;
vec4 color_exponent;
vec4 direction_cutoff;
vec4 attenuation;
};
layout(std140) uniform SpotLightBuffer {
PointLightParameters pointlights[64];
};
uniform int SpotLightCount;
when I use panda3ds ShaderBuffer Object, it no longer works. I don’t change anything in my shader code. Just the python side.
#Cutt down version
def update_lights_transforms():
ubo = ShaderBuffer("buffer", data, ShaderBuffer.UHDynamic)
#then
render.setShaderInput("SpotLightBuffer", ubo)
There aren’t any errors, but my glsl shader doesn’t seem to be retrieving any values.
SSBOs work perfectly but when I switch to a UBO, it all fails when using panda3ds system.