def __init__(self, resolution): self.resolution = resolution width, height = resolution 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)
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 #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.get_scene(context, depsgraph, self.request_scene_update) self.request_scene_update = False 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.bind_display_space_shader(depsgraph.scene_eval) if self.display_draw is None or self.display_draw.resolution != resolution: self.display_draw = DisplayDraw(resolution) self.display_draw.draw(fbo, render_texture) self.unbind_display_space_shader() if self.get_pipeline().needs_more_samples(): self.tag_redraw() reset_GL_state() 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())
def view_draw(self, context, depsgraph): if self.bridge is not MaltPipeline.get_bridge(): #The Bridge has been reset self.bridge = MaltPipeline.get_bridge() self.bridge_id = self.bridge.get_viewport_id() self.request_new_frame = True self.request_scene_update = True global CAPTURE if CAPTURE: self.request_new_frame = True overrides = [] if context.space_data.shading.type == 'MATERIAL': overrides.append('Preview') scene = self.get_scene(context, depsgraph, self.request_scene_update, overrides) viewport_resolution = context.region.width, context.region.height resolution = viewport_resolution resolution_scale = scene.world_parameters['Viewport.Resolution Scale'] mag_filter = GL.GL_LINEAR if resolution_scale != 1.0: w, h = resolution resolution = round(w * resolution_scale), round(h * resolution_scale) smooth_interpolation = scene.world_parameters[ 'Viewport.Smooth Interpolation'] mag_filter = GL.GL_LINEAR if smooth_interpolation else GL.GL_NEAREST if self.request_new_frame: self.bridge.render(self.bridge_id, resolution, scene, self.request_scene_update, CAPTURE) CAPTURE = False self.request_new_frame = False self.request_scene_update = False target_fps = context.preferences.addons[ 'BlenderMalt'].preferences.render_fps_cap if target_fps > 0: delta_time = time.perf_counter() - self.last_frame_time target_delta = 1.0 / target_fps if delta_time < target_delta: high_res_sleep(target_delta - delta_time) self.last_frame_time = time.perf_counter() buffers, finished, read_resolution = self.bridge.render_result( self.bridge_id) pixels = buffers['COLOR'] if not finished: self.tag_redraw() if pixels is None or resolution != read_resolution: # Only render if resolution is the same as read_resolution. # This avoids visual glitches when the viewport is resizing. # The alternative would be locking when writing/reading the pixel buffer. return for region in context.area.regions: if region.type == 'UI': region.tag_redraw() fbo = GL.gl_buffer(GL.GL_INT, 1) GL.glGetIntegerv(GL.GL_FRAMEBUFFER_BINDING, fbo) data_format = GL.GL_FLOAT texture_format = GL.GL_RGBA32F if self.bridge.viewport_bit_depth == 8: data_format = GL.GL_UNSIGNED_BYTE texture_format = GL.GL_RGBA8 if GL.glGetInternalformativ(GL.GL_TEXTURE_2D, texture_format, GL.GL_READ_PIXELS, 1) != GL.GL_ZERO: data_format = GL.glGetInternalformativ( GL.GL_TEXTURE_2D, texture_format, GL.GL_TEXTURE_IMAGE_TYPE, 1) render_texture = Texture(resolution, texture_format, data_format, pixels.buffer(), mag_filter=mag_filter) self.bind_display_space_shader(depsgraph.scene_eval) if self.display_draw is None or self.display_draw.resolution != viewport_resolution: if self.display_draw: self.display_draw.gl_delete() self.display_draw = DisplayDraw(viewport_resolution) self.display_draw.draw(fbo, render_texture) self.unbind_display_space_shader()
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() if self.bridge is not MaltPipeline.get_bridge(): #The Bridge has been reset self.bridge.free_viewport_id(self.bridge_id) self.bridge = MaltPipeline.get_bridge() self.bridge_id = self.bridge.get_viewport_id() self.request_new_frame = True self.request_scene_update = True overrides = [] if context.space_data.shading.type == 'MATERIAL': overrides.append('Preview') scene = self.get_scene(context, depsgraph, self.request_scene_update, overrides) resolution = context.region.width, context.region.height if self.request_new_frame: self.bridge.render(self.bridge_id, resolution, scene, self.request_scene_update) self.request_new_frame = False self.request_scene_update = False buffers, finished, read_resolution = self.bridge.render_result(self.bridge_id) pixels = buffers['COLOR'] if not finished: self.tag_redraw() if pixels is None or resolution != read_resolution: # Only render if resolution is the same as read_resolution. # This avoids visual glitches when the viewport is resizing. # The alternative would be locking when writing/reading the pixel buffer. return fbo = GL.gl_buffer(GL.GL_INT, 1) GL.glGetIntegerv(GL.GL_FRAMEBUFFER_BINDING, fbo) render_texture = Texture(resolution, GL.GL_RGBA32F, GL.GL_FLOAT, pixels) self.bind_display_space_shader(depsgraph.scene_eval) if self.display_draw is None or self.display_draw.resolution != resolution: if self.display_draw: self.display_draw.gl_delete() self.display_draw = DisplayDraw(resolution) self.display_draw.draw(fbo, render_texture) self.unbind_display_space_shader() if PROFILE: profiler.disable() stats = pstats.Stats(profiler, stream=self.profiling_data) stats.strip_dirs() stats.sort_stats(pstats.SortKey.CUMULATIVE) stats.print_stats() print('PROFILE BEGIN--------------------------------------') print(self.profiling_data.getvalue()) print('PROFILE END--------------------------------------')