def __init__(self, ctx, queue, z_bounds, init_chunk_array_kernel):
     '''
     
     '''
     num_layers = z_bounds[1] - z_bounds[0]
     self.array_buffer = RenderBuffer(ctx, queue, self.dtype_array.itemsize, 0) # may not grow
     self.layer_buffer = RenderBuffer(ctx, queue, 2**14, 2**12)
     self.chunk_buffer = RenderBuffer(ctx, queue, 2**14, 2**12) # The chunks
     
     self.data, offset = self.array_buffer.allocate_data(self.dtype_array)
     self.layers = [ ChunkLayer(*self.layer_buffer.allocate_data(self.dtype_layer)) for i in range(num_layers) ]
     self.z_bounds = z_bounds
     self.x_bounds = (2**30, -2**30)
     self.y_bounds = (2**30, -2**30)
     self.chunk_layers_ptr = self.layer_buffer._d_buffer.int_ptr
     
     self.voxel_data = VoxelData(ctx, queue)
     self.init_chunk_array_kernel = init_chunk_array_kernel
     
     self.ctx = ctx
     self.queue = queue
Exemple #2
0
 def __init__(self, clctx, queue):
     '''
     Constructor
     '''
     self.clctx = clctx
     self.queue = queue
     
     # stores the objects of the scene. (data and ref)
     self.objects = set() 
     self.lights = set()
     
     # stores the (byte)data of the objects
     self._obj_buffer     = RenderBuffer(clctx, queue, 2**16, 2**15)
     
     # stores the references on the (byte)data. 
     # these will be raytraced in the render process.
     self._obj_references = RenderBuffer(clctx, queue, 2**15, 2**14)
     
     # couldn't help myself but put this in a buffer... maybe sometimes we need multiple cameras.
     self._cam_buffer     = RenderBuffer(clctx, queue, Camera.dtype.itemsize, Camera.dtype.itemsize)
     
     # The lights in the scene. These are referenced by _light_references
     self._light_buffer     = RenderBuffer(clctx, queue, 2**9, 2**7)
     self._light_references = RenderBuffer(clctx, queue, 2**8, 2**6)
     
     # This camera will be passed to the render process
     self.camera = self.create_camera(position=(-2,-2,30), orientation=(1,0,0,0), bounds=(-2,2,1.5,-1.5), warp=4)
     
     self.raytrace_pgrm = build_program(clctx, "raytrace")
     self.raytrace = self.raytrace_pgrm.raytrace
     self.raytrace.set_scalar_arg_dtypes([None, None, None, numpy.uint32, None, None, None, None])
     self._chunk_array = ChunkArray(self.clctx, self.queue, (0, 1) , self.raytrace_pgrm.init_chunk_array)
     
     """self._chunk_array.allocate_layer(0, x_bounds=(0, 2), y_bounds=(0, 2))
     self._chunk_array.allocate_layer(1, x_bounds=(0, 2), y_bounds=(0, 2))
     self._chunk_array.allocate_chunk(0, 0, 0, level=0)
     self._chunk_array.allocate_chunk(1, 0, 0, level=1)
     self._chunk_array.allocate_chunk(0, 0, 1, level=0)
     self._chunk_array.allocate_chunk(1, 0, 1, level=0)
     self._chunk_array.allocate_chunk(0, 1, 0, level=0)
     self._chunk_array.allocate_chunk(1, 1, 0, level=0)
     self._chunk_array.allocate_chunk(0, 1, 1, level=0)
     self._chunk_array.allocate_chunk(1, 1, 1, level=0)
     
     self._chunk_array.get_layer(0).chunk_offset = 0
     chunk = self._chunk_array.get_chunk(0, 0, 0)
     chunk.voxel_data[:] = numpy.array([(random.randint(0,2), (0,0,0), (-1,-1,-1)) for i in range(32**3)], dtype=VoxelData.test_dtype)
     
     chunk = self._chunk_array.get_chunk(1, 0, 0)
     chunk.voxel_data[:] = numpy.array([(i % 2, (0,0,0), (-1,-1,-1)) for i in range(16**3)], dtype=VoxelData.test_dtype)
     
     chunk = self._chunk_array.get_chunk(0, 0, 1)
     chunk.voxel_data[:] = numpy.array([(random.randint(0,2), (0,0,0), (-1,-1,-1)) for i in range(32**3)], dtype=VoxelData.test_dtype)
     
     self._chunk_array.get_chunk(1, 0, 1).voxel_data[:] = chunk.voxel_data
     
     
     self._chunk_array.get_chunk(0, 1, 0).voxel_data[:] = chunk.voxel_data
     self._chunk_array.get_chunk(1, 1, 0).voxel_data[:] = chunk.voxel_data
     self._chunk_array.get_chunk(0, 1, 1).voxel_data[:] = chunk.voxel_data
     self._chunk_array.get_chunk(1, 1, 1).voxel_data[:] = chunk.voxel_data"""
     
     self.h_test_buffer = numpy.zeros((32,32,32), dtype=numpy.uint32)
     self.d_test_buffer = pyopencl.Buffer(clctx, pyopencl.mem_flags.READ_WRITE | pyopencl.mem_flags.COPY_HOST_PTR, hostbuf=self.h_test_buffer)
Exemple #3
0
class Scene(object):
    '''
    Stores a list of render objects and allocates them. 
    '''

    reference_t = numpy.dtype([ ('obj_type', numpy.short), ('obj_offset', numpy.uint32) ])
    
    def __init__(self, clctx, queue):
        '''
        Constructor
        '''
        self.clctx = clctx
        self.queue = queue
        
        # stores the objects of the scene. (data and ref)
        self.objects = set() 
        self.lights = set()
        
        # stores the (byte)data of the objects
        self._obj_buffer     = RenderBuffer(clctx, queue, 2**16, 2**15)
        
        # stores the references on the (byte)data. 
        # these will be raytraced in the render process.
        self._obj_references = RenderBuffer(clctx, queue, 2**15, 2**14)
        
        # couldn't help myself but put this in a buffer... maybe sometimes we need multiple cameras.
        self._cam_buffer     = RenderBuffer(clctx, queue, Camera.dtype.itemsize, Camera.dtype.itemsize)
        
        # The lights in the scene. These are referenced by _light_references
        self._light_buffer     = RenderBuffer(clctx, queue, 2**9, 2**7)
        self._light_references = RenderBuffer(clctx, queue, 2**8, 2**6)
        
        # This camera will be passed to the render process
        self.camera = self.create_camera(position=(-2,-2,30), orientation=(1,0,0,0), bounds=(-2,2,1.5,-1.5), warp=4)
        
        self.raytrace_pgrm = build_program(clctx, "raytrace")
        self.raytrace = self.raytrace_pgrm.raytrace
        self.raytrace.set_scalar_arg_dtypes([None, None, None, numpy.uint32, None, None, None, None])
        self._chunk_array = ChunkArray(self.clctx, self.queue, (0, 1) , self.raytrace_pgrm.init_chunk_array)
        
        """self._chunk_array.allocate_layer(0, x_bounds=(0, 2), y_bounds=(0, 2))
        self._chunk_array.allocate_layer(1, x_bounds=(0, 2), y_bounds=(0, 2))
        self._chunk_array.allocate_chunk(0, 0, 0, level=0)
        self._chunk_array.allocate_chunk(1, 0, 0, level=1)
        self._chunk_array.allocate_chunk(0, 0, 1, level=0)
        self._chunk_array.allocate_chunk(1, 0, 1, level=0)
        self._chunk_array.allocate_chunk(0, 1, 0, level=0)
        self._chunk_array.allocate_chunk(1, 1, 0, level=0)
        self._chunk_array.allocate_chunk(0, 1, 1, level=0)
        self._chunk_array.allocate_chunk(1, 1, 1, level=0)
        
        self._chunk_array.get_layer(0).chunk_offset = 0
        chunk = self._chunk_array.get_chunk(0, 0, 0)
        chunk.voxel_data[:] = numpy.array([(random.randint(0,2), (0,0,0), (-1,-1,-1)) for i in range(32**3)], dtype=VoxelData.test_dtype)
        
        chunk = self._chunk_array.get_chunk(1, 0, 0)
        chunk.voxel_data[:] = numpy.array([(i % 2, (0,0,0), (-1,-1,-1)) for i in range(16**3)], dtype=VoxelData.test_dtype)
        
        chunk = self._chunk_array.get_chunk(0, 0, 1)
        chunk.voxel_data[:] = numpy.array([(random.randint(0,2), (0,0,0), (-1,-1,-1)) for i in range(32**3)], dtype=VoxelData.test_dtype)
        
        self._chunk_array.get_chunk(1, 0, 1).voxel_data[:] = chunk.voxel_data
        
        
        self._chunk_array.get_chunk(0, 1, 0).voxel_data[:] = chunk.voxel_data
        self._chunk_array.get_chunk(1, 1, 0).voxel_data[:] = chunk.voxel_data
        self._chunk_array.get_chunk(0, 1, 1).voxel_data[:] = chunk.voxel_data
        self._chunk_array.get_chunk(1, 1, 1).voxel_data[:] = chunk.voxel_data"""
        
        self.h_test_buffer = numpy.zeros((32,32,32), dtype=numpy.uint32)
        self.d_test_buffer = pyopencl.Buffer(clctx, pyopencl.mem_flags.READ_WRITE | pyopencl.mem_flags.COPY_HOST_PTR, hostbuf=self.h_test_buffer)
        
    def _create_buffer_object(self, buff, cls, **kwargs):
        dtype = cls.dtype
        data = None
        
        if dtype is not None:
            data, offset = buff.allocate_data(dtype)
            
        obj = cls(data)
        for k,v in kwargs.items():
            obj.__setattr__(k, v)
        return obj, offset
        
    def create_reference(self, ref_buffer, obj_type, obj_offset):
        ref, offset = ref_buffer.allocate_data(self.reference_t)
        ref['obj_type']   = obj_type
        ref['obj_offset'] = obj_offset
        return ref
        
    def create_object(self, name, **kwargs):
        cls = RenderObject._render_object_classes[name]
        obj, offset = self._create_buffer_object(self._obj_buffer, cls, **kwargs)
        
        ref = self.create_reference(self._obj_references, cls.type_id, offset)
        obj.data_ref = ref
        
        self.objects.add(obj)
        return obj
    
    def create_camera(self, **kwargs):
        cam, offset = self._create_buffer_object(self._cam_buffer, Camera, **kwargs)
        return cam
    
    def create_light(self, name, **kwargs):
        cls = RenderObject._light_classes[name]
        light, offset = self._create_buffer_object(self._light_buffer, cls, **kwargs)
        
        ref = self.create_reference(self._light_references, cls.type_id, offset)
        light.data_ref = ref
        return light
    
    def call_test(self):
        self.raytrace_pgrm.test_kernel(self.queue, (1,), None, self.d_test_buffer)
        pyopencl.enqueue_copy(self.queue, self.h_test_buffer, self.d_test_buffer)
    
    def render(self, img, size):
        self._obj_buffer.upload_buffer()
        self._obj_references.upload_buffer()
        self._cam_buffer.upload_buffer()
        self._light_buffer.upload_buffer()
        self._light_references.upload_buffer()
        
        """self.raytrace(self.queue, size, None,
                        img, self._cam_buffer._d_buffer, 
                             self._obj_references.n_elements,
                             self._obj_references._d_buffer,
                             self._obj_buffer._d_buffer,
                             self._light_references.n_elements,
                             self._light_references._d_buffer,
                             self._light_buffer._d_buffer,
                             self.d_test_buffer)"""
                             
        self.raytrace(self.queue, size, (16,8), img, self._cam_buffer._d_buffer, 
                             self._chunk_array.array_buffer._d_buffer,
                             self._light_references.n_elements,
                             self._light_references._d_buffer,
                             self._light_buffer._d_buffer,
                             self.d_test_buffer,
                             self._chunk_array.voxel_data.level_buffers[0]._d_buffer)
        pyopencl.enqueue_copy(self.queue, self.h_test_buffer, self.d_test_buffer)
        #pyopencl.enqueue_copy(self.queue, self._chunk_array.array_buffer._h_buffer, self._chunk_array.array_buffer._d_buffer)
        
Exemple #4
0
 def test_renderbuffer(self):
     buffer = RenderBuffer(self.ctx, self.queue, 256, 64)
     b1 = buffer.allocate_array(256, numpy.dtype([("p", numpy.byte)]))
     b2 = buffer.allocate_array(16, numpy.dtype([("p", numpy.byte)]))
class ChunkArray(object):
    '''
    Stores chunk layers in a array structure.
    '''
    
    dtype_array = numpy.dtype( [ ('x_bounds', numpy.int32, 2), ('y_bounds', numpy.int32, 2), ('z_bounds', numpy.int32, 2),
                                 ('chunk_layers_ptr', numpy.uintp), ('chunks_ptr', numpy.uintp), ('voxel_levels_ptr', numpy.uintp, 6) ] )
    
    dtype_layer = numpy.dtype( [ ('x_bounds', numpy.int32, 2), ('y_bounds', numpy.int32, 2), ('chunk_offset', numpy.uint32) ] )
    
    dtype_chunk = numpy.dtype( [ ('level', numpy.int), ('voxel_offset', numpy.uint32) ] )
    
    def __init__(self, ctx, queue, z_bounds, init_chunk_array_kernel):
        '''
        
        '''
        num_layers = z_bounds[1] - z_bounds[0]
        self.array_buffer = RenderBuffer(ctx, queue, self.dtype_array.itemsize, 0) # may not grow
        self.layer_buffer = RenderBuffer(ctx, queue, 2**14, 2**12)
        self.chunk_buffer = RenderBuffer(ctx, queue, 2**14, 2**12) # The chunks
        
        self.data, offset = self.array_buffer.allocate_data(self.dtype_array)
        self.layers = [ ChunkLayer(*self.layer_buffer.allocate_data(self.dtype_layer)) for i in range(num_layers) ]
        self.z_bounds = z_bounds
        self.x_bounds = (2**30, -2**30)
        self.y_bounds = (2**30, -2**30)
        self.chunk_layers_ptr = self.layer_buffer._d_buffer.int_ptr
        
        self.voxel_data = VoxelData(ctx, queue)
        self.init_chunk_array_kernel = init_chunk_array_kernel
        
        self.ctx = ctx
        self.queue = queue
        
    def get_layer(self, z):
        if z < self.z_bounds[0] or z >= self.z_bounds[1]:
            raise IndexError("%d index is out of bounds (layer not found)" % z)
        return self.layers[z - self.z_bounds[0]]
        
    def get_chunk(self, x, y, z):
        layer = self.get_layer(z)
        if (x < layer.x_bounds[0] or x >= layer.x_bounds[1] or
            y < layer.y_bounds[0] or y >= layer.y_bounds[1]):
            raise IndexError("Layer %d found, but not chunk (%d, %d) in it. " % (z, x, y))
        x_offset = x - layer.x_bounds[0]
        y_offset = y - layer.y_bounds[0]
        return layer.chunks[x_offset + y_offset*(layer.y_bounds[1]-layer.y_bounds[0])]
        
    def get_voxel(self, x, y, z):
        chunk_x, voxel_x = divmod(x, 32)
        chunk_y, voxel_y = divmod(y, 32)
        chunk_z, voxel_z = divmod(z, 32)
        chunk = self.get_chunk(chunk_x, chunk_y, chunk_z)
        return chunk.get_voxel((voxel_x, voxel_y, voxel_z))
        
    def allocate_layer(self, z, x_bounds, y_bounds):
        layer = self.get_layer(z)
        
        x_size = x_bounds[1] - x_bounds[0]
        y_size = y_bounds[1] - y_bounds[0]
        if x_bounds[0] < self.x_bounds[0]:
            self.x_bounds[0] = x_bounds[0]
        if x_bounds[1] > self.x_bounds[1]:
            self.x_bounds[1] = x_bounds[1]
        if y_bounds[0] < self.y_bounds[0]:
            self.y_bounds[0] = y_bounds[0]
        if y_bounds[1] > self.y_bounds[1]:
            self.y_bounds[1] = y_bounds[1]
            
        layer.x_bounds = x_bounds
        layer.y_bounds = y_bounds
        layer.chunks = [ Chunk(*self.chunk_buffer.allocate_data(self.dtype_chunk)) for i in range(x_size*y_size) ]
        
        layer.chunk_offset = layer.chunks[0].offset / self.dtype_chunk.itemsize
        
    def allocate_chunk(self, x, y, z, level):
        chunk = self.get_chunk(x, y, z)
        chunk.level = level
        data, offset = self.voxel_data.allocate_buffer(level)
        chunk.voxel_offset = offset / self.voxel_data.test_dtype.itemsize
        chunk.voxel_data = data
        
    def upload_buffers(self):
        self.array_buffer.upload_buffer()
        self.layer_buffer.upload_buffer()
        self.chunk_buffer.upload_buffer()
        self.voxel_data.upload_buffers()
        self.init_chunk_array_kernel(self.queue, (1,), None, 
                                     self.array_buffer._d_buffer, 
                                     self.layer_buffer._d_buffer,
                                     self.chunk_buffer._d_buffer,
                                      *[ self.voxel_data.level_buffers[i]._d_buffer for i in range(self.voxel_data.num_levels) ])
        self.array_buffer.download_buffer()
        
    @render_property("x_bounds")
    def x_bounds(self):
        "x_min, x_max"
        
    @render_property("y_bounds")
    def y_bounds(self):
        "y_min, y_max"
    
    @render_property("z_bounds")
    def z_bounds(self):
        "z_min, z_max"

    @render_property("chunk_layers_ptr", None)
    def chunk_layers_ptr(self):
        "chunk_layer_t*"
    
    @render_property("chunks_ptr", None)
    def chunks_ptr(self):
        "chunk_t*"
        
    @render_property("voxel_levels_ptr")
    def voxel_levels_ptr(self):
        "voxel_t* [6]"