Esempio n. 1
0
    def view_draw(self, context, depsgraph):
        profiler = cProfile.Profile()
        global PROFILE
        if PROFILE:
            profiler.enable()
            if self.request_new_frame:
                self.profiling_data = io.StringIO()

        # Get viewport resolution
        resolution = context.region.width, context.region.height

        def bind_display_shader():
            self.bind_display_space_shader(depsgraph.scene_eval)

        if self.display_draw is None or self.display_draw.resolution != resolution:
            self.display_draw = DisplayDraw(bind_display_shader, resolution)

        #Save FBO for later use
        fbo = GL.gl_buffer(GL.GL_INT, 1)
        GL.glGetIntegerv(GL.GL_FRAMEBUFFER_BINDING, fbo)

        # Generating a VAO before loading/rendering fixes an error where the viewport
        # freezes in edit mode. Why ??? I have no idea. ¯\_(ツ)_/¯
        # TODO: try to load meshes the normal way, without lazy VAO generation.
        # (Would need a Pipeline refactor)
        VAO = GL.gl_buffer(GL.GL_INT, 1)
        GL.glGenVertexArrays(1, VAO)

        #render
        scene = self.load_scene(context, depsgraph)
        render_texture = self.get_pipeline().render(
            resolution, scene, False, self.request_new_frame)['COLOR']
        self.request_new_frame = False
        if MaltMaterial.INITIALIZED == False:  #First viewport render can happen before initialization
            self.request_new_frame = True

        #Render to viewport
        self.display_draw.draw(bind_display_shader, fbo, render_texture)

        if self.get_pipeline().needs_more_samples():
            self.tag_redraw()

        GL.glDeleteVertexArrays(1, VAO)

        if PROFILE:
            profiler.disable()
            stats = pstats.Stats(profiler, stream=self.profiling_data)
            stats.strip_dirs()
            stats.sort_stats(pstats.SortKey.CUMULATIVE)
            stats.print_stats()

            if self.get_pipeline().needs_more_samples() == False:
                PROFILE = False
                with open(REPORT_PATH, 'w') as file:
                    file.write(self.profiling_data.getvalue())
Esempio n. 2
0
    def render(self, depsgraph):
        scene = depsgraph.scene_eval
        scale = scene.render.resolution_percentage / 100.0

        self.size_x = int(scene.render.resolution_x * scale)
        self.size_y = int(scene.render.resolution_y * scale)
        resolution = (self.size_x, self.size_y)

        scene = self.load_scene(None, depsgraph)
        render_textures = None
        while True:
            render_textures = self.get_pipeline().render(
                resolution, scene, True, False)
            if self.get_pipeline().needs_more_samples() == False:
                break
        render_textures['COLOR'].bind()

        result = self.begin_result(0, 0, self.size_x, self.size_y)

        render_textures['COLOR'].bind()
        gl_pixels = GL.gl_buffer(GL.GL_FLOAT,
                                 resolution[0] * resolution[1] * 4)
        GL.glGetTexImage(GL.GL_TEXTURE_2D, 0, GL.GL_RGBA, GL.GL_FLOAT,
                         gl_pixels)
        it = iter(gl_pixels)
        pixels = list(zip(it, it, it,
                          it))  #convert from 1D list to list of tuples

        layer = result.layers[0].passes["Combined"]
        layer.rect = pixels

        render_textures['DEPTH'].bind()
        gl_pixels = GL.gl_buffer(GL.GL_FLOAT, resolution[0] * resolution[1])
        GL.glGetTexImage(GL.GL_TEXTURE_2D, 0, GL.GL_RED, GL.GL_FLOAT,
                         gl_pixels)

        layer = result.layers[0].passes["Depth"]
        layer.rect.foreach_set(list(gl_pixels))

        self.end_result(result)

        #Delete the pipeline while we are in the correct OpenGL context
        del self.pipeline
Esempio n. 3
0
    def __init__(self, bind_display_shader, resolution):
        # Generate dummy float image buffer
        self.resolution = resolution
        width, height = resolution

        bind_display_shader()
        shader_program = GL.gl_buffer(GL.GL_INT, 1)
        GL.glGetIntegerv(GL.GL_CURRENT_PROGRAM, shader_program)

        self.vertex_array = GL.gl_buffer(GL.GL_INT, 1)
        GL.glGenVertexArrays(1, self.vertex_array)
        GL.glBindVertexArray(self.vertex_array[0])

        texturecoord_location = GL.glGetAttribLocation(shader_program[0],
                                                       "texCoord")
        position_location = GL.glGetAttribLocation(shader_program[0], "pos")

        GL.glEnableVertexAttribArray(texturecoord_location)
        GL.glEnableVertexAttribArray(position_location)

        position = [0.0, 0.0, width, 0.0, width, height, 0.0, height]
        position = GL.gl_buffer(GL.GL_FLOAT, len(position), position)
        texcoord = [0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0]
        texcoord = GL.gl_buffer(GL.GL_FLOAT, len(texcoord), texcoord)

        self.vertex_buffer = GL.gl_buffer(GL.GL_INT, 2)

        GL.glGenBuffers(2, self.vertex_buffer)
        GL.glBindBuffer(GL.GL_ARRAY_BUFFER, self.vertex_buffer[0])
        GL.glBufferData(GL.GL_ARRAY_BUFFER, 32, position, GL.GL_STATIC_DRAW)
        GL.glVertexAttribPointer(position_location, 2, GL.GL_FLOAT,
                                 GL.GL_FALSE, 0, None)

        GL.glBindBuffer(GL.GL_ARRAY_BUFFER, self.vertex_buffer[1])
        GL.glBufferData(GL.GL_ARRAY_BUFFER, 32, texcoord, GL.GL_STATIC_DRAW)
        GL.glVertexAttribPointer(texturecoord_location, 2, GL.GL_FLOAT,
                                 GL.GL_FALSE, 0, None)

        GL.glBindBuffer(GL.GL_ARRAY_BUFFER, 0)
        GL.glBindVertexArray(0)
Esempio n. 4
0
def load_mesh(object):
    m = object.to_mesh()
    if m is None:
        return None

    m.calc_loop_triangles()
    m.calc_normals_split()

    #TODO: Blender indexes vertex positions and normals, but not uvs and colors,
    #we might need to do our own indexing or don't do indexing at all
    fast_path = False
    if fast_path:
        positions = (ctypes.c_float*(len(m.vertices)*3))()
        m.vertices.foreach_get("co", positions)
        normals = (ctypes.c_float*(len(m.vertices)*3))()
        m.vertices.foreach_get("normal", normals)
        indices = (ctypes.c_uint32*(len(m.loop_triangles)*3))()
        m.loop_triangles.foreach_get("vertices", indices)

        return Mesh(positions, indices, normals)
    else:    
        count = len(m.loops)

        indices = GL.gl_buffer(GL.GL_UNSIGNED_INT, len(m.loop_triangles)*3)
        m.loop_triangles.foreach_get("loops",indices)

        normals = GL.gl_buffer(GL.GL_FLOAT, count*3)
        m.loops.foreach_get("normal",normals)

        uvs = []
        tangents = []

        if len(m.uv_layers) == 0:
            m.uv_layers.new() #At least 1 UV layer is needed for tangents calculation

        for i, uv_layer in enumerate(m.uv_layers):
            uvs.append(GL.gl_buffer(GL.GL_FLOAT, count*2))
            uv_layer.data.foreach_get("uv", uvs[i])

            try:
                m.calc_tangents(uvmap=uv_layer.name)
            except Exception as ex:
                # TODO:
                log('DEBUG', "Object :", object.name)
                log('DEBUG', ex)
            packed_tangents = [e for l in m.loops for e in (*l.tangent, l.bitangent_sign)]
            tangents.append(GL.gl_buffer(GL.GL_FLOAT, count*4, packed_tangents))

        colors = []
        for i, vertex_color in enumerate(m.vertex_colors):
            colors.append(GL.gl_buffer(GL.GL_FLOAT, count*4))
            vertex_color.data.foreach_get("color", colors[i])

        pos = [axis for l in m.loops for axis in m.vertices[l.vertex_index].co]
        positions = GL.gl_buffer(GL.GL_FLOAT, count*3, pos)

        return Mesh(positions, indices, normals, tangents, uvs, colors)
Esempio n. 5
0
    def view_draw(self, context, depsgraph):
        # Get viewport resolution
        resolution = context.region.width, context.region.height

        def bind_display_shader():
            self.bind_display_space_shader(depsgraph.scene_eval)

        if self.display_draw is None or self.display_draw.resolution != resolution:
            self.display_draw = DisplayDraw(bind_display_shader, resolution)

        #Save FBO for later use
        fbo = GL.gl_buffer(GL.GL_INT, 1)
        GL.glGetIntegerv(GL.GL_FRAMEBUFFER_BINDING, fbo)

        # Generating a VAO before loading/rendering fixes an error where the viewport
        # freezes in edit mode. Why ??? I have no idea. ¯\_(ツ)_/¯
        # TODO: try to load meshes the normal way, without lazy VAO generation.
        # (Would need a Pipeline refactor)
        VAO = GL.gl_buffer(GL.GL_INT, 1)
        GL.glGenVertexArrays(1, VAO)

        #render
        scene = self.load_scene(context, depsgraph)
        render_texture = self.get_pipeline().render(
            resolution, scene, False, self.request_new_frame)['COLOR']
        self.request_new_frame = False
        if MaltMaterial.INITIALIZED == False:  #First viewport render can happen before initialization
            self.request_new_frame = True

        #Render to viewport
        self.display_draw.draw(bind_display_shader, fbo, render_texture)

        if self.get_pipeline().needs_more_samples():
            self.tag_redraw()

        GL.glDeleteVertexArrays(1, VAO)