def __init__(self, location=(0, 0, 0), rotation=(0, 0, 0), scale=(1, 1, 1)): self._location = Vec3(location) self._rotation = Vec3(rotation) self._scale = Vec3(scale) self.model = 0 self.transformation = Mat4(*create_transformation_matrix( *location, *rotation, *scale).flatten())
def on_draw(): glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) # Load lights. for light_struct, light in zip(point_light_structs, point_lights): light_struct.position[:] = world.location[light] for light_struct, light in zip(spot_light_structs, spot_lights): light_struct.position[:] = world.location[light] # light_struct.direction[:] = cos(time), 0, -sin(time) for light_struct, light in zip(sun_light_structs, sun_lights): light_struct.direction = cos(pi / 2), -sin(pi / 2), 0 with object_shader: # Upload uniforms. object_shader.load_uniform_matrix(create_transformation_matrix( *camera_location, 0, 0, 0, 1, 1, 1), name='view') for index, light_struct in enumerate(point_light_structs): object_shader.load_uniform_struct(light_struct, name='light[{}]'.format(index)) for index, light_struct in enumerate(spot_light_structs): object_shader.load_uniform_struct(light_struct, name='spotlight') for index, light_struct in enumerate(sun_light_structs): object_shader.load_uniform_struct(light_struct, name='sunlight') object_shader.load_uniform_struct(material_struct, name='material') object_shader.load_uniform_floats(time, name='time') # Render. world.draw(object_shader, models, textures) with lamp_shader: # Just renders the lamp object, does not handle different objects interaction with the lights. # Upload uniforms. lamp_shader.load_uniform_matrix(create_transformation_matrix( *camera_location, 0, 0, 0, 1, 1, 1), name='view') for light_struct in point_light_structs: lamp_shader.load_uniform_floats(*light_struct.diffuse, name='color') # Render. world.draw_light(lamp_shader, models)
def create_object(self, mask, location=(0, 0, 0), rotation=(0, 0, 0), scale=(1, 1, 1), model=0, diffuse=0, specular=0, emission=0): entity = self.create_entity() self.mask[entity] = mask self.location[entity] = location self.rotation[entity] = rotation self.scale[entity] = scale self.transformation[entity] = create_transformation_matrix( *location, *rotation, *scale) self.model[entity] = model self.diffuse[entity] = diffuse self.specular[entity] = specular self.emission[entity] = emission return entity
def update(self, *args, **kwargs): self.transformation = create_transformation_matrix( *self._location, *self._rotation, *self._scale)
def draw_light(self, shader, models): """ Dependencies are location, rotation, scale, and model (optionally texture). Args: shader: models: Returns: """ attribute_location = shader.attribute_location location_location = attribute_location['position'] for entity in numpy.where(self.mask == World.COMPONENT_LIGHT)[0]: shader.load_uniform_matrix(create_transformation_matrix( *self.location[entity], *self.rotation[entity], *self.scale[entity]), name='transform') model = models[self.model[entity]] glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, model.indexed_vbo) glBindBuffer(GL_ARRAY_BUFFER, model.vbo_array['location']) glEnableVertexAttribArray(location_location) glVertexAttribPointer(location_location, 3, GL_FLOAT, GL_FALSE, 0, 0) glDrawElements(GL_TRIANGLES, model.indexed_vbo.count, GL_UNSIGNED_INT, 0) glDisableVertexAttribArray(location_location) glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0) glBindBuffer(GL_ARRAY_BUFFER, 0) # # # # # class World: # # Must be of same data type as 'mask' array. # COMPONENT_VOID = numpy.uint(0) # COMPONENT_DISPLACEMENT = numpy.uint(1 << 0) # COMPONENT_MODEL = numpy.uint(1 << 1) # COMPONENT_TEXTURE = numpy.uint(1 << 2) # # COMPONENT_LIGHT = COMPONENT_DISPLACEMENT | COMPONENT_MODEL # COMPONENT_SPRITE = COMPONENT_DISPLACEMENT | COMPONENT_MODEL | COMPONENT_TEXTURE # # def __init__(self, max_entities): # self.max_entities = max_entities # self.entity_count = 0 # # self.mask = numpy.zeros(shape=max_entities, dtype=numpy.uint, order='C') # # # Displacement. # self.location = numpy.zeros(shape=(max_entities, 3), dtype=numpy.float32, order='C') # self.rotation = numpy.zeros(shape=(max_entities, 3), dtype=numpy.float32, order='C') # self.scale = numpy.zeros(shape=(max_entities, 3), dtype=numpy.float32, order='C') # self.transformation = numpy.zeros(shape=(max_entities, 4, 4), dtype=numpy.float32, order='C') # # # Model. # self.model = numpy.zeros(shape=max_entities, dtype=numpy.uint, order='C') # # # Texture. # self.diffuse = numpy.zeros(shape=max_entities, dtype=numpy.uint, order='C') # self.specular = numpy.zeros(shape=max_entities, dtype=numpy.uint, order='C') # self.emission = numpy.zeros(shape=max_entities, dtype=numpy.uint, order='C') # # # def create_entity(world, **attributes) -> int: # """ # Generates a handle for an entity. # # Returns: # int # """ # handle = world.entity_count # world.entity_count += 1 # # if world.entity_count > world.max_entities: # raise ValueError('Maximum entity count of %i reached!' % world.max_entities) # # for key, value in attributes.items(): # attribute_array = getattr(world, key) # attribute_array[handle][:] = value # # return handle # # # def remove_entity(world, entity): # world.mask[entity] = World.COMPONENT_VOID # # # def draw(world, mask, shader, models, textures): # """ # # # Dependencies are location, rotation, scale, and model (optionally texture). # # Args: # world: # mask: # shader: # models: # textures: # # Returns: # # """ # attribute_location = shader.attribute_location # location_location = attribute_location['location'] # texture_location = attribute_location['texture_coordinate'] # normal_location = attribute_location['normal'] # # for entity in numpy.where((world.mask & mask) == mask)[0]: # model = models[world.model[entity]] # # shader.load_uniform_matrix(world.transformation[entity], name='transform') # # glActiveTexture(GL_TEXTURE0) # texture = textures[world.diffuse[entity]] # glBindTexture(GL_TEXTURE_2D, texture.id) # glActiveTexture(GL_TEXTURE0 + 1) # texture = textures[world.specular[entity]] # glBindTexture(GL_TEXTURE_2D, texture.id) # glActiveTexture(GL_TEXTURE0 + 2) # texture = textures[world.emission[entity]] # glBindTexture(GL_TEXTURE_2D, texture.id) # # glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, model.indexed_vbo) # # glBindBuffer(GL_ARRAY_BUFFER, model.vbo_array['location']) # glEnableVertexAttribArray(location_location) # glVertexAttribPointer(location_location, 3, GL_FLOAT, GL_FALSE, 0, 0) # # glBindBuffer(GL_ARRAY_BUFFER, model.vbo_array['texture_coordinate']) # glEnableVertexAttribArray(texture_location) # glVertexAttribPointer(texture_location, 2, GL_FLOAT, GL_FALSE, 0, 0) # # glBindBuffer(GL_ARRAY_BUFFER, model.vbo_array['normal']) # glEnableVertexAttribArray(normal_location) # glVertexAttribPointer(normal_location, 3, GL_FLOAT, GL_FALSE, 0, 0) # # glDrawElements(GL_TRIANGLES, model.indexed_vbo.count, GL_UNSIGNED_INT, 0) # # glDisableVertexAttribArray(location_location) # glDisableVertexAttribArray(texture_location) # glDisableVertexAttribArray(normal_location) # glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0) # glBindBuffer(GL_ARRAY_BUFFER, 0) # # # def draw_light(world, shader, models): # """ # # # Dependencies are location, rotation, scale, and model (optionally texture). # # Args: # world: # shader: # models: # # Returns: # # """ # attribute_location = shader.attribute_location # location_location = attribute_location['location'] # # for entity in numpy.where(world.mask == World.COMPONENT_LIGHT)[0]: # shader.load_uniform_matrix(world.transformation[entity], name='transform') # # model = models[world.model[entity]] # # glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, model.indexed_vbo) # # glBindBuffer(GL_ARRAY_BUFFER, model.vbo_array['location']) # glEnableVertexAttribArray(location_location) # glVertexAttribPointer(location_location, 3, GL_FLOAT, GL_FALSE, 0, 0) # # glDrawElements(GL_TRIANGLES, model.indexed_vbo.count, GL_UNSIGNED_INT, 0) # # glDisableVertexAttribArray(location_location) # glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0) # glBindBuffer(GL_ARRAY_BUFFER, 0)
def scale(self, entity, dx, dy, dz): self.scale[entity] += dx, dy, dz self.transformation[entity] = create_transformation_matrix( *self.location[entity], *self.rotation[entity], *self.scale[entity])