def init_opengl(cls): # OpenGL was already initialized, nothing to do here. if cls.shader is not None: return cls.shader = Shader( load_shader('3D_vert.glsl'), None, load_shader('primitive_id_frag.glsl'), ) cls.unif_use_clip_planes = bgl.glGetUniformLocation( cls.shader.program, 'use_clip_planes') cls.unif_clip_plane = bgl.glGetUniformLocation(cls.shader.program, 'clip_plane') cls.unif_MVP = bgl.glGetUniformLocation(cls.shader.program, 'MVP') cls.unif_MV = bgl.glGetUniformLocation(cls.shader.program, 'MV') cls.unif_offset = bgl.glGetUniformLocation(cls.shader.program, 'offset') cls.attr_pos = bgl.glGetAttribLocation(cls.shader.program, 'pos') cls.attr_primitive_id = bgl.glGetAttribLocation( cls.shader.program, 'primitive_id') cls.P = bgl.Buffer(bgl.GL_FLOAT, (4, 4)) cls.MV = bgl.Buffer(bgl.GL_FLOAT, (4, 4)) # returns of public API # cls.vert_index = bgl.Buffer(bgl.GL_INT, 1) cls.tri_co = bgl.Buffer(bgl.GL_FLOAT, (3, 3)) cls.edge_co = bgl.Buffer(bgl.GL_FLOAT, (2, 3)) cls.vert_co = bgl.Buffer(bgl.GL_FLOAT, 3)
def init_opengl(cls): # OpenGL was already initialized, nothing to do here. if cls.shader is not None: return import atexit # Make sure we only registered the callback once. atexit.unregister(cls.end_opengl) atexit.register(cls.end_opengl) cls.shader = Shader( load_shader('3D_vert.glsl'), None, load_shader('primitive_id_frag.glsl'), ) cls.unif_use_clip_planes = bgl.glGetUniformLocation( cls.shader.program, 'use_clip_planes') cls.unif_clip_plane = bgl.glGetUniformLocation(cls.shader.program, 'clip_plane') cls._NULL = gl_buffer_void_as_long(0) cls.unif_MVP = bgl.glGetUniformLocation(cls.shader.program, 'MVP') cls.unif_MV = bgl.glGetUniformLocation(cls.shader.program, 'MV') cls.unif_offset = bgl.glGetUniformLocation(cls.shader.program, 'offset') cls.attr_pos = bgl.glGetAttribLocation(cls.shader.program, 'pos') cls.attr_primitive_id = bgl.glGetAttribLocation( cls.shader.program, 'primitive_id') cls.P = bgl.Buffer(bgl.GL_FLOAT, (4, 4)) cls.MV = bgl.Buffer(bgl.GL_FLOAT, (4, 4)) cls.MVP = bgl.Buffer(bgl.GL_FLOAT, (4, 4)) # returns of public API # cls.vert_index = bgl.Buffer(bgl.GL_INT, 1) cls.tri_co = bgl.Buffer(bgl.GL_FLOAT, (3, 3)) cls.edge_co = bgl.Buffer(bgl.GL_FLOAT, (2, 3)) cls.vert_co = bgl.Buffer(bgl.GL_FLOAT, 3)
def init_opengl(cls): # OpenGL was already initialized, nothing to do here. if cls.shader is not None: return import atexit # Make sure we only registered the callback once. atexit.unregister(cls.end_opengl) atexit.register(cls.end_opengl) cls.shader = Shader( load_shader('3D_vert.glsl'), None, load_shader('primitive_id_frag.glsl'), ) cls.unif_use_clip_planes = bgl.glGetUniformLocation(cls.shader.program, 'use_clip_planes') cls.unif_clip_plane = bgl.glGetUniformLocation(cls.shader.program, 'clip_plane') cls._NULL = gl_buffer_void_as_long(0) cls.unif_MVP = bgl.glGetUniformLocation(cls.shader.program, 'MVP') cls.unif_MV = bgl.glGetUniformLocation(cls.shader.program, 'MV') cls.unif_offset = bgl.glGetUniformLocation(cls.shader.program, 'offset') cls.attr_pos = bgl.glGetAttribLocation(cls.shader.program, 'pos') cls.attr_primitive_id = bgl.glGetAttribLocation(cls.shader.program, 'primitive_id') cls.P = bgl.Buffer(bgl.GL_FLOAT, (4, 4)) cls.MV = bgl.Buffer(bgl.GL_FLOAT, (4, 4)) cls.MVP = bgl.Buffer(bgl.GL_FLOAT, (4, 4)) # returns of public API # cls.vert_index = bgl.Buffer(bgl.GL_INT, 1) cls.tri_co = bgl.Buffer(bgl.GL_FLOAT, (3, 3)) cls.edge_co = bgl.Buffer(bgl.GL_FLOAT, (2, 3)) cls.vert_co = bgl.Buffer(bgl.GL_FLOAT, 3)
def draw_vertex_array(key, mode, dimensions, color): if key in VAO and VAO[key] and program: vao = VAO[key] bgl.glUseProgram(program) bgl.glUniform4f(bgl.glGetUniformLocation(program, "color"), *color) bgl.glEnableClientState(bgl.GL_VERTEX_ARRAY) bgl.glVertexPointer(dimensions, bgl.GL_FLOAT, 0, vao) bgl.glDrawArrays(mode, 0, int(len(vao) / dimensions)) bgl.glDisableClientState(bgl.GL_VERTEX_ARRAY) bgl.glUseProgram(0)
def preExecute(self, refholder): # pass self.rdData[self.name] = {} D = bpy.data textureName = self.nodeTree.name + " - " + self.identifier resolution = self.nodeTree.properties.TextureResolution if textureName in D.images: D.images.remove(D.images[textureName]) image = bpy.data.images.new(textureName, width=resolution, height=resolution) self.rdData[self.name]["image"] = image npImage = np.asarray(image.pixels, dtype="float") self.rdData[self.name]["npArray"] = npImage.reshape( resolution, resolution, image.channels) vertex_shader = bgl_helper.createShader(bgl.GL_VERTEX_SHADER, self.vertex_source) fragment_shader = bgl_helper.createShader(bgl.GL_FRAGMENT_SHADER, self.fragment_source) self.rdData[self.name]["program"] = bgl_helper.createProgram( vertex_shader, fragment_shader) self.rdData[self.name]["prev_program"] = bgl.Buffer(bgl.GL_INT, [1]) self.rdData[self.name]["buffer"] = bgl.Buffer(bgl.GL_FLOAT, (resolution**2) * 4) program = self.rdData[self.name]["program"] self.rdData[self.name]["dt_loc"] = bgl.glGetUniformLocation( program, "timestep") self.rdData[self.name]["step_loc"] = bgl.glGetUniformLocation( program, "step") self.rdData[self.name]["da_loc"] = bgl.glGetUniformLocation( program, "du") self.rdData[self.name]["db_loc"] = bgl.glGetUniformLocation( program, "dv") self.rdData[self.name]["kill_loc"] = bgl.glGetUniformLocation( program, "k") self.rdData[self.name]["feed_loc"] = bgl.glGetUniformLocation( program, "f")
class GPU_Indices_Mesh(): shader = Shader( load_shader('3D_vert.glsl'), None, load_shader('primitive_id_frag.glsl'), ) unif_use_clip_planes = bgl.glGetUniformLocation(shader.program, 'use_clip_planes') unif_clip_plane = bgl.glGetUniformLocation(shader.program, 'clip_plane') unif_MVP = bgl.glGetUniformLocation(shader.program, 'MVP') unif_MV = bgl.glGetUniformLocation(shader.program, 'MV') unif_offset = bgl.glGetUniformLocation(shader.program, 'offset') attr_pos = bgl.glGetAttribLocation(shader.program, 'pos') attr_primitive_id = bgl.glGetAttribLocation(shader.program, 'primitive_id') P = bgl.Buffer(bgl.GL_FLOAT, (4, 4)) MV = bgl.Buffer(bgl.GL_FLOAT, (4, 4)) # returns of public API # vert_index = bgl.Buffer(bgl.GL_INT, 1) tri_co = bgl.Buffer(bgl.GL_FLOAT, (3, 3)) edge_co = bgl.Buffer(bgl.GL_FLOAT, (2, 3)) vert_co = bgl.Buffer(bgl.GL_FLOAT, 3) def __init__(self, obj, draw_tris, draw_edges, draw_verts): self._NULL = VoidBufValue(0) self.MVP = bgl.Buffer(bgl.GL_FLOAT, (4, 4)) self.obj = obj self.draw_tris = draw_tris self.draw_edges = draw_edges self.draw_verts = draw_verts self.vbo = None self.vbo_tris = None self.vbo_edges = None self.vbo_verts = None ## Create VAO ## self.vao = bgl.Buffer(bgl.GL_INT, 1) bgl.glGenVertexArrays(1, self.vao) bgl.glBindVertexArray(self.vao[0]) ## Init Array ## mesh_arrays = _Mesh_Arrays(obj, draw_tris, draw_edges, draw_verts) ## Create VBO for vertices ## if mesh_arrays.verts_co is None: self.draw_tris = False self.draw_edges = False self.draw_verts = False return if False: # Blender 2.8 self.vbo_len = len(mesh_arrays.verts_co) self.vbo = bgl.Buffer(bgl.GL_INT, 1) bgl.glGenBuffers(1, self.vbo) bgl.glBindBuffer(bgl.GL_ARRAY_BUFFER, self.vbo[0]) bgl.glBufferData(bgl.GL_ARRAY_BUFFER, self.vbo_len * 12, np_array_as_bgl_Buffer(mesh_arrays.verts_co), bgl.GL_STATIC_DRAW) ## Create VBO for Tris ## if mesh_arrays.tri_verts is not None: self.tri_verts = mesh_arrays.tri_verts self.num_tris = len(self.tri_verts) np_tris_co = mesh_arrays.verts_co[mesh_arrays.tri_verts] self.vbo_tris = bgl.Buffer(bgl.GL_INT, 1) bgl.glGenBuffers(1, self.vbo_tris) bgl.glBindBuffer(bgl.GL_ARRAY_BUFFER, self.vbo_tris[0]) bgl.glBufferData(bgl.GL_ARRAY_BUFFER, self.num_tris * 36, np_array_as_bgl_Buffer(np_tris_co), bgl.GL_STATIC_DRAW) del np_tris_co tri_indices = np.repeat(np.arange(self.num_tris, dtype='f4'), 3) self.vbo_tri_indices = bgl.Buffer(bgl.GL_INT, 1) bgl.glGenBuffers(1, self.vbo_tri_indices) bgl.glBindBuffer(bgl.GL_ARRAY_BUFFER, self.vbo_tri_indices[0]) bgl.glBufferData(bgl.GL_ARRAY_BUFFER, self.num_tris * 12, np_array_as_bgl_Buffer(tri_indices), bgl.GL_STATIC_DRAW) del tri_indices else: self.num_tris = 0 self.draw_tris = False ## Create VBO for Edges ## if mesh_arrays.edge_verts is not None: self.edge_verts = mesh_arrays.edge_verts self.num_edges = len(self.edge_verts) np_edges_co = mesh_arrays.verts_co[mesh_arrays.edge_verts] self.vbo_edges = bgl.Buffer(bgl.GL_INT, 1) bgl.glGenBuffers(1, self.vbo_edges) bgl.glBindBuffer(bgl.GL_ARRAY_BUFFER, self.vbo_edges[0]) bgl.glBufferData(bgl.GL_ARRAY_BUFFER, self.num_edges * 24, np_array_as_bgl_Buffer(np_edges_co), bgl.GL_STATIC_DRAW) del np_edges_co edge_indices = np.repeat(np.arange(self.num_edges, dtype='f4'), 2) self.vbo_edge_indices = bgl.Buffer(bgl.GL_INT, 1) bgl.glGenBuffers(1, self.vbo_edge_indices) bgl.glBindBuffer(bgl.GL_ARRAY_BUFFER, self.vbo_edge_indices[0]) bgl.glBufferData(bgl.GL_ARRAY_BUFFER, self.num_edges * 8, np_array_as_bgl_Buffer(edge_indices), bgl.GL_STATIC_DRAW) del edge_indices else: self.num_edges = 0 self.draw_edges = False ## Create EBO for Loose Verts ## if mesh_arrays.looseverts is not None: self.looseverts = mesh_arrays.looseverts self.num_verts = len(mesh_arrays.looseverts) np_lverts_co = mesh_arrays.verts_co[mesh_arrays.looseverts] self.vbo_verts = bgl.Buffer(bgl.GL_INT, 1) bgl.glGenBuffers(1, self.vbo_verts) bgl.glBindBuffer(bgl.GL_ARRAY_BUFFER, self.vbo_verts[0]) bgl.glBufferData(bgl.GL_ARRAY_BUFFER, self.num_verts * 12, np_array_as_bgl_Buffer(np_lverts_co), bgl.GL_STATIC_DRAW) del np_lverts_co looseverts_indices = np.arange(self.num_verts, dtype='f4') self.vbo_looseverts_indices = bgl.Buffer(bgl.GL_INT, 1) bgl.glGenBuffers(1, self.vbo_looseverts_indices) bgl.glBindBuffer(bgl.GL_ARRAY_BUFFER, self.vbo_looseverts_indices[0]) bgl.glBufferData(bgl.GL_ARRAY_BUFFER, self.num_verts * 4, np_array_as_bgl_Buffer(looseverts_indices), bgl.GL_STATIC_DRAW) del looseverts_indices else: self.num_verts = 0 self.draw_verts = False del mesh_arrays bgl.glBindVertexArray(0) def get_tot_elems(self): tot = 0 if self.draw_tris: tot += self.num_tris if self.draw_edges: tot += self.num_edges if self.draw_verts: tot += self.num_verts return tot def set_draw_mode(self, draw_tris, draw_edges, draw_verts): self.draw_tris = draw_tris and self.vbo_tris self.draw_edges = draw_edges and self.vbo_edges self.draw_verts = draw_verts and self.vbo_verts def set_ModelViewMatrix(self, MV): self.MV[:] = MV[:] self.MVP[:] = Matrix(self.P) * MV def Draw(self, index_offset): self.first_index = index_offset bgl.glUseProgram(self.shader.program) bgl.glBindVertexArray(self.vao[0]) bgl.glUniformMatrix4fv(self.unif_MV, 1, bgl.GL_TRUE, self.MV) bgl.glUniformMatrix4fv(self.unif_MVP, 1, bgl.GL_TRUE, self.MVP) if self.draw_tris: bgl.glUniform1f(self.unif_offset, float(index_offset)) # bgl has no glUniform1ui :\ bgl.glBindBuffer(bgl.GL_ARRAY_BUFFER, self.vbo_tris[0]) bgl.glEnableVertexAttribArray(self.attr_pos) bgl.glVertexAttribPointer(self.attr_pos, 3, bgl.GL_FLOAT, bgl.GL_FALSE, 0, self._NULL.buf) bgl.glBindBuffer(bgl.GL_ARRAY_BUFFER, self.vbo_tri_indices[0]) bgl.glEnableVertexAttribArray(self.attr_primitive_id) bgl.glVertexAttribPointer(self.attr_primitive_id, 1, bgl.GL_FLOAT, bgl.GL_FALSE, 0, self._NULL.buf) bgl.glDrawArrays(bgl.GL_TRIANGLES, 0, self.num_tris * 3) index_offset += self.num_tris bgl.glDepthRange(-0.00005, 0.99995) if self.draw_edges: bgl.glUniform1f(self.unif_offset, float(index_offset)) #TODO: use glUniform1ui bgl.glBindBuffer(bgl.GL_ARRAY_BUFFER, self.vbo_edges[0]) bgl.glVertexAttribPointer(self.attr_pos, 3, bgl.GL_FLOAT, bgl.GL_FALSE, 0, self._NULL.buf) bgl.glEnableVertexAttribArray(self.attr_pos) bgl.glBindBuffer(bgl.GL_ARRAY_BUFFER, self.vbo_edge_indices[0]) bgl.glVertexAttribPointer(self.attr_primitive_id, 1, bgl.GL_FLOAT, bgl.GL_FALSE, 0, self._NULL.buf) bgl.glEnableVertexAttribArray(self.attr_primitive_id) bgl.glDrawArrays(bgl.GL_LINES, 0, self.num_edges * 2) index_offset += self.num_edges if self.draw_verts: bgl.glUniform1f(self.unif_offset, float(index_offset)) #TODO: use glUniform1ui bgl.glBindBuffer(bgl.GL_ARRAY_BUFFER, self.vbo_verts[0]) bgl.glVertexAttribPointer(self.attr_pos, 3, bgl.GL_FLOAT, bgl.GL_FALSE, 0, self._NULL.buf) bgl.glEnableVertexAttribArray(self.attr_pos) bgl.glBindBuffer(bgl.GL_ARRAY_BUFFER, self.vbo_looseverts_indices[0]) bgl.glVertexAttribPointer(self.attr_primitive_id, 1, bgl.GL_FLOAT, bgl.GL_FALSE, 0, self._NULL.buf) bgl.glEnableVertexAttribArray(self.attr_primitive_id) bgl.glDrawArrays(bgl.GL_POINTS, 0, self.num_verts) bgl.glDepthRange(0.0, 1.0) def get_tri_co(self, index): bgl.glBindVertexArray(self.vao[0]) bgl.glBindBuffer(bgl.GL_ARRAY_BUFFER, self.vbo_tris[0]) bgl.glGetBufferSubData(bgl.GL_ARRAY_BUFFER, index * 36, 36, self.tri_co) bgl.glBindVertexArray(0) return self.tri_co def get_edge_co(self, index): bgl.glBindVertexArray(self.vao[0]) bgl.glBindBuffer(bgl.GL_ARRAY_BUFFER, self.vbo_edges[0]) bgl.glGetBufferSubData(bgl.GL_ARRAY_BUFFER, index * 24, 24, self.edge_co) bgl.glBindVertexArray(0) return self.edge_co def get_loosevert_co(self, index): bgl.glBindVertexArray(self.vao[0]) bgl.glBindBuffer(bgl.GL_ARRAY_BUFFER, self.vbo_verts[0]) bgl.glGetBufferSubData(bgl.GL_ARRAY_BUFFER, index * 12, 12, self.vert_co) bgl.glBindVertexArray(0) return self.vert_co def get_tri_verts(self, index): return self.tri_verts[index] def get_edge_verts(self, index): return self.edge_verts[index] def get_loosevert_index(self, index): return self.looseverts[index] def __del__(self): del self._NULL if self.vbo_tris: bgl.glDeleteBuffers(1, self.vbo_tris) bgl.glDeleteBuffers(1, self.vbo_tri_indices) del self.tri_verts if self.vbo_edges: bgl.glDeleteBuffers(1, self.vbo_edges) bgl.glDeleteBuffers(1, self.vbo_edge_indices) del self.edge_verts if self.vbo_verts: bgl.glDeleteBuffers(1, self.vbo_verts) bgl.glDeleteBuffers(1, self.vbo_looseverts_indices) del self.looseverts bgl.glDeleteVertexArrays(1, self.vao)
def image_to_KK(image, lut_name): width = image.size[0] height = image.size[1] # Some Sauce vertex_default = ''' in vec2 a_position; in vec2 a_texcoord; void main() { gl_Position = vec4(a_position, 0.0, 1.0); } ''' # The Secret Sauce current_code = ''' uniform sampler2D tex0; uniform sampler2D lut; uniform vec2 u_resolution; vec3 to_srgb(vec3 c){ c.rgb = max( 1.055 * pow( c.rgb, vec3(0.416666667,0.416666667,0.416666667) ) - 0.055, 0 ); return c; } vec3 apply_lut(vec3 color) { const vec3 coord_scale = vec3(0.0302734375, 0.96875, 31.0); const vec3 coord_offset = vec3( 0.5/1024, 0.5/32, 0.0); const vec2 texel_height_X0 = vec2( 0.03125, 0.0 ); vec3 coord = color * coord_scale + coord_offset; vec3 coord_frac = fract( coord ); vec3 coord_floor = coord - coord_frac; vec2 coord_bot = coord.xy + coord_floor.zz * texel_height_X0; vec2 coord_top = coord_bot + texel_height_X0; vec3 lutcol_bot = texture2D( lut, coord_bot ).rgb; vec3 lutcol_top = texture2D( lut, coord_top ).rgb; vec3 lutColor = mix(lutcol_bot, lutcol_top, coord_frac.z); return lutColor; } void main() { vec4 texRGBA = texture2D(tex0, gl_FragCoord.xy / u_resolution); vec3 texColor = to_srgb(texRGBA.rgb); vec3 newColor = apply_lut(texColor); newColor = to_srgb(newColor); gl_FragColor = vec4(newColor.rgb, texRGBA.a); } ''' # This object gives access to off screen buffers. offscreen = gpu.types.GPUOffScreen(width, height) # Context manager to ensure balanced bind calls, even in the case of an error. # Only run if valid with offscreen.bind(): # Clear buffers to preset values bgl.glClear(bgl.GL_COLOR_BUFFER_BIT) # Initialize the shader # GPUShader combines multiple GLSL shaders into a program used for drawing. # It must contain a vertex and fragment shaders, with an optional geometry shader. shader = gpu.types.GPUShader(vertex_default, current_code) # Initialize the shader batch # It makes sure that all the vertex attributes necessary for a specific shader are provided. batch = batch_for_shader( shader, 'TRI_FAN', {'a_position': ((-1, -1), (1, -1), (1, 1), (-1, 1))}, ) # Bind the shader object. Required to be able to change uniforms of this shader. shader.bind() bgl.glUniform1i(bgl.glGetUniformLocation(shader.program, "tex0"), 0) bgl.glUniform1i(bgl.glGetUniformLocation(shader.program, "lut"), 1) try: # Make sure image has a bindcode if image.bindcode == 0: for i in range(0, 20): image.gl_load() if image.bindcode != 0: break # https://docs.blender.org/api/current/bgl.html bgl.glActiveTexture(bgl.GL_TEXTURE0) bgl.glBindTexture(bgl.GL_TEXTURE_2D, image.bindcode) bgl.glTexParameteri(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_WRAP_S, bgl.GL_CLAMP_TO_EDGE) bgl.glTexParameteri(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_WRAP_T, bgl.GL_CLAMP_TO_EDGE) bgl.glTexParameterf(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_MIN_FILTER, bgl.GL_LINEAR) bgl.glTexParameterf(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_MAG_FILTER, bgl.GL_LINEAR) # Specify the value of a uniform variable for the current program object. # In this case, an image. shader.uniform_int("tex0", 0) except ValueError: pass try: lut_image = bpy.data.images[lut_name] # Make sure image has a bindcode if lut_image.bindcode == 0: for i in range(0, 20): lut_image.gl_load() if lut_image.bindcode != 0: break # https://docs.blender.org/api/current/bgl.html bgl.glActiveTexture(bgl.GL_TEXTURE1) bgl.glBindTexture(bgl.GL_TEXTURE_2D, lut_image.bindcode) bgl.glTexParameteri(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_WRAP_S, bgl.GL_CLAMP_TO_EDGE) bgl.glTexParameteri(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_WRAP_T, bgl.GL_CLAMP_TO_EDGE) bgl.glTexParameterf(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_MIN_FILTER, bgl.GL_LINEAR) bgl.glTexParameterf(bgl.GL_TEXTURE_2D, bgl.GL_TEXTURE_MAG_FILTER, bgl.GL_LINEAR) # Specify the value of a uniform variable for the current program object. # In this case, an image. shader.uniform_int("lut", 1) except ValueError: pass try: shader.uniform_float('u_resolution', (width, height)) except ValueError: pass # Run the drawing program with the parameters assigned to the batch. batch.draw(shader) # The Buffer object is simply a block of memory that is delineated and initialized by the user. buffer = bgl.Buffer(bgl.GL_BYTE, width * height * 4) # Select a color buffer source for pixels. bgl.glReadBuffer(bgl.GL_BACK) # Read a block of pixels from the frame buffer. bgl.glReadPixels(0, 0, width, height, bgl.GL_RGBA, bgl.GL_UNSIGNED_BYTE, buffer) # Free the offscreen object. The framebuffer, texture and render objects will no longer be accessible. offscreen.free() # Return the final buffer-pixels pixels = [v / 255 for v in buffer] return pixels, width, height
def execute(self, context): namespace['projection_matrix'] = bgl.Buffer(bgl.GL_FLOAT, (4, 4)) namespace['points'] = (-0.5, -0.5, 0.0, 0.5, -0.5, 0.0, 0.0, 0.5, 0.0) namespace['colors'] = (0.0, 1.0, 0.0, 0.5, 1.0, 1.0, 0.0, 0.5, 1.0, 0.0, 1.0, 0.5) namespace['data_point'] = bgl.Buffer(bgl.GL_FLOAT, len(namespace['points']), namespace['points']) namespace['data_color'] = bgl.Buffer(bgl.GL_FLOAT, len(namespace['colors']), namespace['colors']) namespace['vertex_shader_info'] = bgl.Buffer(bgl.GL_INT, 1) namespace['fragment_shader_info'] = bgl.Buffer(bgl.GL_INT, 1) namespace['shader_program_info'] = bgl.Buffer(bgl.GL_INT, 1) namespace['vao'] = bgl.Buffer(bgl.GL_INT, 1) namespace['vbo_point'] = bgl.Buffer(bgl.GL_INT, 1) namespace['vbo_color'] = bgl.Buffer(bgl.GL_INT, 1) bgl.glGenBuffers(1, namespace['vbo_point']) bgl.glGenBuffers(1, namespace['vbo_color']) # Shaders namespace['shader_program'] = bgl.glCreateProgram() namespace['vertex_shader'] = bgl.glCreateShader(bgl.GL_VERTEX_SHADER) namespace['fragment_shader'] = bgl.glCreateShader( bgl.GL_FRAGMENT_SHADER) bgl.glShaderSource(namespace['vertex_shader'], vertex_shader_source) bgl.glShaderSource(namespace['fragment_shader'], fragment_shader_source) bgl.glCompileShader(namespace['vertex_shader']) bgl.glCompileShader(namespace['fragment_shader']) bgl.glGetShaderiv(namespace['vertex_shader'], bgl.GL_COMPILE_STATUS, namespace['vertex_shader_info']) bgl.glGetShaderiv(namespace['fragment_shader'], bgl.GL_COMPILE_STATUS, namespace['fragment_shader_info']) if namespace['vertex_shader_info'][0] == bgl.GL_TRUE: print("Vertex shader compiled successfully.") elif namespace['vertex_shader_info'][0] == bgl.GL_FALSE: print("Vertex shader failed to compile.") if namespace['fragment_shader_info'][0] == bgl.GL_TRUE: print("Fragment shader compiled successfully.") elif namespace['fragment_shader_info'][0] == bgl.GL_FALSE: print("Fragment shader failed to compile.") bgl.glAttachShader(namespace['shader_program'], namespace['vertex_shader']) bgl.glAttachShader(namespace['shader_program'], namespace['fragment_shader']) bgl.glLinkProgram(namespace['shader_program']) bgl.glGetProgramiv(namespace['shader_program'], bgl.GL_LINK_STATUS, namespace['shader_program_info']) if namespace['shader_program_info'][0] == bgl.GL_TRUE: print("Shader program linked successfully.") elif namespace['shader_program_info'][0] == bgl.GL_FALSE: print("Shader program failed to link.") # glGetUniformLocation can only be used after the shader program is linked, as stated in the OpenGL Specification. namespace['perspective_uniform_location'] = bgl.glGetUniformLocation( namespace['shader_program'], "perspective") bgl.glValidateProgram(namespace['shader_program']) bgl.glGetProgramiv(namespace['shader_program'], bgl.GL_VALIDATE_STATUS, namespace['shader_program_info']) if namespace['shader_program_info'][0] == bgl.GL_TRUE: print("Shader program validated successfully.") elif namespace['shader_program_info'][0] == bgl.GL_FALSE: print("Shader program failed to validate.") draw_handler_add() namespace['timer'] = context.window_manager.event_timer_add( time_step=0.01, window=context.window) namespace['data_timer'] = bgl.Buffer(bgl.GL_FLOAT, 2, [ math.sin(namespace['timer'].time_duration), math.sin(namespace['timer'].time_duration) * 2 ]) context.window_manager.modal_handler_add(self) return {'RUNNING_MODAL'}
class GPU_Indices: shader = gpu.types.GPUShader(vert_3d, primitive_id_frag) unif_MVP = bgl.glGetUniformLocation(shader.program, 'MVP') unif_offset = bgl.glGetUniformLocation(shader.program, 'offset') attr_pos = bgl.glGetAttribLocation(shader.program, 'pos') attr_primitive_id = bgl.glGetAttribLocation(shader.program, 'primitive_id') # returns of public API # knot_co = bgl.Buffer(bgl.GL_FLOAT, 3) seg_co = bgl.Buffer(bgl.GL_FLOAT, (2, 3)) origin_co = bgl.Buffer(bgl.GL_FLOAT, 3) def __init__(self, obj): self._NULL = VoidBufValue(0) self.MVP = bgl.Buffer(bgl.GL_FLOAT, (4, 4)) # self.obj = obj self.first_index = 0 self.vbo_segs = None self.vbo_segs_co = None self.vbo_origin = None self.vbo_origin_co = None self.num_segs = 0 self.num_origins = 0 self._draw_segs = False self._draw_origins = False self.is_mesh = False self.snap_mode = 0 self.vao = bgl.Buffer(bgl.GL_INT, 1) bgl.glGenVertexArrays(1, self.vao) bgl.glBindVertexArray(self.vao[0]) _arrays = _Object_Arrays(obj) if _arrays.segs_co: self.vbo_segs_co = bgl.Buffer(bgl.GL_INT, 1) self.num_segs = len(_arrays.segs_co) bgl.glGenBuffers(1, self.vbo_segs_co) bgl.glBindBuffer(bgl.GL_ARRAY_BUFFER, self.vbo_segs_co[0]) bgl.glBufferData(bgl.GL_ARRAY_BUFFER, self.num_segs * 24, _arrays.segs_co, bgl.GL_STATIC_DRAW) segs_indices = np.repeat(np.arange(self.num_segs, dtype='f4'), 2) self.vbo_segs = bgl.Buffer(bgl.GL_INT, 1) bgl.glGenBuffers(1, self.vbo_segs) bgl.glBindBuffer(bgl.GL_ARRAY_BUFFER, self.vbo_segs[0]) bgl.glBufferData( bgl.GL_ARRAY_BUFFER, self.num_segs * 8, np_array_as_bgl_Buffer(segs_indices), bgl.GL_STATIC_DRAW ) del segs_indices self._draw_segs = True # objects origin if _arrays.origin_co: self.vbo_origin_co = bgl.Buffer(bgl.GL_INT, 1) self.num_origins = len(_arrays.origin_co) bgl.glGenBuffers(1, self.vbo_origin_co) bgl.glBindBuffer(bgl.GL_ARRAY_BUFFER, self.vbo_origin_co[0]) bgl.glBufferData(bgl.GL_ARRAY_BUFFER, self.num_origins * 12, _arrays.origin_co, bgl.GL_STATIC_DRAW) orig_indices = np.arange(self.num_origins, dtype='f4') self.vbo_origin = bgl.Buffer(bgl.GL_INT, 1) bgl.glGenBuffers(1, self.vbo_origin) bgl.glBindBuffer(bgl.GL_ARRAY_BUFFER, self.vbo_origin[0]) bgl.glBufferData( bgl.GL_ARRAY_BUFFER, self.num_origins * 4, np_array_as_bgl_Buffer(orig_indices), bgl.GL_STATIC_DRAW ) del orig_indices self.is_mesh = _arrays.is_mesh self._draw_origins = True del _arrays bgl.glBindVertexArray(0) def get_tot_elems(self): tot = 0 if self.draw_segs: tot += self.num_segs if self.draw_origin: tot += self.num_origins return tot @property def draw_segs(self): return self._draw_segs and self.vbo_segs_co is not None def set_snap_mode(self, snap_mode): self.snap_mode = snap_mode @property def draw_origin(self): return (self._draw_origins or (self._draw_segs and self.is_mesh)) and self.vbo_origin_co is not None def set_draw_mode(self, draw_segs, draw_origin): self._draw_segs = draw_segs self._draw_origins = draw_origin @classmethod def set_ProjectionMatrix(cls, P): cls.P = P def set_ModelViewMatrix(self, MV): self.MVP[:] = self.P @ MV def bind(self, co, buf_id, offset): bgl.glUniform1f(self.unif_offset, float(offset)) bgl.glBindBuffer(bgl.GL_ARRAY_BUFFER, co[0]) bgl.glVertexAttribPointer(self.attr_pos, 3, bgl.GL_FLOAT, bgl.GL_FALSE, 0, self._NULL.buf) bgl.glEnableVertexAttribArray(self.attr_pos) bgl.glBindBuffer(bgl.GL_ARRAY_BUFFER, buf_id[0]) bgl.glVertexAttribPointer(self.attr_primitive_id, 1, bgl.GL_FLOAT, bgl.GL_FALSE, 0, self._NULL.buf) bgl.glEnableVertexAttribArray(self.attr_primitive_id) def draw(self, index_offset): self.first_index = index_offset bgl.glUseProgram(self.shader.program) bgl.glBindVertexArray(self.vao[0]) bgl.glUniformMatrix4fv(self.unif_MVP, 1, bgl.GL_TRUE, self.MVP) # bgl.glUniform1f(self.unif_size, float(2.0)) if self.draw_segs: self.bind(self.vbo_segs_co, self.vbo_segs, index_offset) bgl.glDrawArrays(bgl.GL_LINES, 0, self.num_segs * 2) index_offset += self.num_segs if self.draw_origin: self.bind(self.vbo_origin_co, self.vbo_origin, index_offset) bgl.glDrawArrays(bgl.GL_POINTS, 0, self.num_origins) index_offset += self.num_origins bgl.glBindVertexArray(0) def get_seg_co(self, index): bgl.glBindVertexArray(self.vao[0]) bgl.glBindBuffer(bgl.GL_ARRAY_BUFFER, self.vbo_segs_co[0]) bgl.glGetBufferSubData(bgl.GL_ARRAY_BUFFER, index * 24, 24, self.seg_co) bgl.glBindVertexArray(0) return self.seg_co def get_origin_co(self, index): bgl.glBindVertexArray(self.vao[0]) bgl.glBindBuffer(bgl.GL_ARRAY_BUFFER, self.vbo_origin_co[0]) bgl.glGetBufferSubData(bgl.GL_ARRAY_BUFFER, index * 12, 12, self.origin_co) bgl.glBindVertexArray(0) return self.origin_co def __del__(self): del self._NULL if self.vbo_segs_co: bgl.glDeleteBuffers(1, self.vbo_segs_co) bgl.glDeleteBuffers(1, self.vbo_segs) if self.vbo_origin_co: bgl.glDeleteBuffers(1, self.vbo_origin_co) bgl.glDeleteBuffers(1, self.vbo_origin) bgl.glDeleteVertexArrays(1, self.vao)
class GPU_Indices: # if bpy.app.version >= (2, 91, 0): shader = gpu.types.GPUShader(vert_3d, primitive_id_frag) unif_MVP = shader.uniform_from_name("MVP") unif_offset = shader.uniform_from_name("offset") attr_pos = shader.attr_from_name('pos') attr_primitive_id = shader.attr_from_name('primitive_id') else: from .utils_shader import Shader shader = Shader(gl_version + vert_3d, None, gl_version + primitive_id_frag) unif_MVP = bgl.glGetUniformLocation(shader.program, 'MVP') unif_offset = bgl.glGetUniformLocation(shader.program, 'offset') attr_pos = bgl.glGetAttribLocation(shader.program, 'pos') attr_primitive_id = bgl.glGetAttribLocation(shader.program, 'primitive_id') # returns of public API # # knot_co = bgl.Buffer(bgl.GL_FLOAT, 3) seg_co = bgl.Buffer(bgl.GL_FLOAT, (2, 3)) origin_co = bgl.Buffer(bgl.GL_FLOAT, 3) bounds_co = bgl.Buffer(bgl.GL_FLOAT, 3) def __init__(self, obj, typ): self._NULL = VoidBufValue(0) self.MVP = bgl.Buffer(bgl.GL_FLOAT, (4, 4)) # self.obj = obj self.first_index = 0 self.vbo_segs = None self.vbo_segs_co = None self.vbo_origin = None self.vbo_origin_co = None self.vbo_bounds = None self.vbo_bounds_co = None self.num_segs = 0 self.num_origins = 0 self.num_bounds = 0 self._draw_segs = False self._draw_origins = False self._draw_bounds = False self.is_mesh = False self.snap_mode = 0 self.vao = bgl.Buffer(bgl.GL_INT, 1) bgl.glGenVertexArrays(1, self.vao) check_error("glGenVertexArrays(1, self.vao)") bgl.glBindVertexArray(self.vao[0]) check_error("glBindVertexArray(self.vao[0])") _arrays = _Object_Arrays(obj, typ) if _arrays.segs_co: self.vbo_segs_co = bgl.Buffer(bgl.GL_INT, 1) self.num_segs = len(_arrays.segs_co) bgl.glGenBuffers(1, self.vbo_segs_co) check_error("glGenBuffers") bgl.glBindBuffer(bgl.GL_ARRAY_BUFFER, self.vbo_segs_co[0]) check_error("glBindBuffer") bgl.glBufferData(bgl.GL_ARRAY_BUFFER, self.num_segs * 24, _arrays.segs_co, bgl.GL_STATIC_DRAW) check_error("glBufferData") segs_indices = np.repeat(np.arange(self.num_segs, dtype='f4'), 2) self.vbo_segs = bgl.Buffer(bgl.GL_INT, 1) bgl.glGenBuffers(1, self.vbo_segs) check_error("glGenBuffers") bgl.glBindBuffer(bgl.GL_ARRAY_BUFFER, self.vbo_segs[0]) check_error("glBindBuffer") bgl.glBufferData( bgl.GL_ARRAY_BUFFER, self.num_segs * 8, np_array_as_bgl_Buffer(segs_indices), bgl.GL_STATIC_DRAW ) check_error("glBufferData") del segs_indices self._draw_segs = True # objects origin if _arrays.origin_co: self.vbo_origin_co = bgl.Buffer(bgl.GL_INT, 1) self.num_origins = len(_arrays.origin_co) bgl.glGenBuffers(1, self.vbo_origin_co) bgl.glBindBuffer(bgl.GL_ARRAY_BUFFER, self.vbo_origin_co[0]) check_error("glBindBuffer") bgl.glBufferData(bgl.GL_ARRAY_BUFFER, self.num_origins * 12, _arrays.origin_co, bgl.GL_STATIC_DRAW) check_error("glBufferData") orig_indices = np.arange(self.num_origins, dtype='f4') self.vbo_origin = bgl.Buffer(bgl.GL_INT, 1) bgl.glGenBuffers(1, self.vbo_origin) check_error("glGenBuffers") bgl.glBindBuffer(bgl.GL_ARRAY_BUFFER, self.vbo_origin[0]) check_error("glBindBuffer") bgl.glBufferData( bgl.GL_ARRAY_BUFFER, self.num_origins * 4, np_array_as_bgl_Buffer(orig_indices), bgl.GL_STATIC_DRAW ) check_error("glBufferData") del orig_indices self.is_mesh = _arrays.is_mesh self._draw_origins = True # objects bound box if _arrays.bounds_co: self.vbo_bounds_co = bgl.Buffer(bgl.GL_INT, 1) self.num_bounds = len(_arrays.bounds_co) bgl.glGenBuffers(1, self.vbo_bounds_co) bgl.glBindBuffer(bgl.GL_ARRAY_BUFFER, self.vbo_bounds_co[0]) bgl.glBufferData(bgl.GL_ARRAY_BUFFER, self.num_bounds * 12, _arrays.bounds_co, bgl.GL_STATIC_DRAW) bounds_indices = np.arange(self.num_bounds, dtype='f4') self.vbo_bounds = bgl.Buffer(bgl.GL_INT, 1) bgl.glGenBuffers(1, self.vbo_bounds) bgl.glBindBuffer(bgl.GL_ARRAY_BUFFER, self.vbo_bounds[0]) bgl.glBufferData( bgl.GL_ARRAY_BUFFER, self.num_bounds * 4, np_array_as_bgl_Buffer(bounds_indices), bgl.GL_STATIC_DRAW ) del bounds_indices self._draw_bounds = True del _arrays bgl.glBindVertexArray(0) check_error("glBindVertexArray(0)") def get_tot_elems(self): tot = 0 if self.draw_segs: tot += self.num_segs if self.draw_origin: tot += self.num_origins if self.draw_bounds: tot += self.num_bounds return tot @property def draw_segs(self): return self._draw_segs and self.vbo_segs is not None @property def draw_bounds(self): return self._draw_bounds and self.vbo_bounds is not None @property def draw_origin(self): # origins and isolated vertices return (self._draw_origins or (self._draw_segs and self.is_mesh)) and self.vbo_origin is not None def set_snap_mode(self, snap_mode): self.snap_mode = snap_mode def set_draw_mode(self, draw_segs, draw_origin, draw_bounds): self._draw_segs = draw_segs self._draw_origins = draw_origin self._draw_bounds = draw_bounds @classmethod def set_ProjectionMatrix(cls, P): cls.P = P def set_ModelViewMatrix(self, MV): self.MVP[:] = self.P @ MV def bind(self, co, buf_id, offset): bgl.glUniform1f(self.unif_offset, float(offset)) check_error("glUniform1f") bgl.glBindBuffer(bgl.GL_ARRAY_BUFFER, co[0]) check_error("glBindBuffer") bgl.glVertexAttribPointer(self.attr_pos, 3, bgl.GL_FLOAT, bgl.GL_FALSE, 0, self._NULL.buf) check_error("glVertexAttribPointer") bgl.glEnableVertexAttribArray(self.attr_pos) check_error("glEnableVertexAttribArray") bgl.glBindBuffer(bgl.GL_ARRAY_BUFFER, buf_id[0]) check_error("glBindBuffer") bgl.glVertexAttribPointer(self.attr_primitive_id, 1, bgl.GL_FLOAT, bgl.GL_FALSE, 0, self._NULL.buf) check_error("glVertexAttribPointer") bgl.glEnableVertexAttribArray(self.attr_primitive_id) check_error("glEnableVertexAttribArray") def draw(self, index_offset): self.first_index = index_offset bgl.glUseProgram(self.shader.program) check_error("glUseProgram") bgl.glBindVertexArray(self.vao[0]) check_error("glBindVertexArray(self.vao[0])") bgl.glUniformMatrix4fv(self.unif_MVP, 1, bgl.GL_TRUE, self.MVP) check_error("glUniformMatrix4fv") # 2.91 - require sequence of floats # self.shader.uniform_float("MVP", np.reshape(self.MVP, 16)) if self.draw_segs: self.bind(self.vbo_segs_co, self.vbo_segs, index_offset) check_error("draw_segs bind") # 2.91 # self.shader.uniform_float("offset", float(index_offset)) bgl.glDrawArrays(bgl.GL_LINES, 0, self.num_segs * 2) check_error("draw_segs glDrawArrays") index_offset += self.num_segs if self.draw_origin: self.bind(self.vbo_origin_co, self.vbo_origin, index_offset) check_error("draw_origin bind") # 2.91 # self.shader.uniform_float("offset", float(index_offset)) bgl.glDrawArrays(bgl.GL_POINTS, 0, self.num_origins) check_error("draw_origin glDrawArrays") index_offset += self.num_origins if self.draw_bounds: self.bind(self.vbo_bounds_co, self.vbo_bounds, index_offset) check_error("draw_bounds bind") # 2.91 # self.shader.uniform_float("offset", float(index_offset)) bgl.glDrawArrays(bgl.GL_POINTS, 0, self.num_bounds) check_error("draw_bounds glDrawArrays") index_offset += self.num_bounds bgl.glBindVertexArray(0) check_error("glBindVertexArray(0)") def get_seg_co(self, index): bgl.glBindVertexArray(self.vao[0]) check_error("glBindVertexArray(self.vao[0])") bgl.glBindBuffer(bgl.GL_ARRAY_BUFFER, self.vbo_segs_co[0]) check_error("glBindBuffer") bgl.glGetBufferSubData(bgl.GL_ARRAY_BUFFER, index * 24, 24, self.seg_co) check_error("glGetBufferSubData") bgl.glBindVertexArray(0) check_error("glBindVertexArray(0)") return self.seg_co def get_origin_co(self, index): bgl.glBindVertexArray(self.vao[0]) check_error("glBindVertexArray(self.vao[0])") bgl.glBindBuffer(bgl.GL_ARRAY_BUFFER, self.vbo_origin_co[0]) check_error("glBindBuffer") bgl.glGetBufferSubData(bgl.GL_ARRAY_BUFFER, index * 12, 12, self.origin_co) check_error("glGetBufferSubData") bgl.glBindVertexArray(0) check_error("glBindVertexArray(0)") return self.origin_co def get_bounds_co(self, index): bgl.glBindVertexArray(self.vao[0]) check_error("glBindVertexArray(self.vao[0])") bgl.glBindBuffer(bgl.GL_ARRAY_BUFFER, self.vbo_bounds_co[0]) check_error("glBindBuffer") bgl.glGetBufferSubData(bgl.GL_ARRAY_BUFFER, index * 12, 12, self.bounds_co) check_error("glGetBufferSubData") bgl.glBindVertexArray(0) check_error("glBindVertexArray(0)") return self.bounds_co def __del__(self): del self._NULL if self.vbo_segs_co: bgl.glDeleteBuffers(1, self.vbo_segs_co) bgl.glDeleteBuffers(1, self.vbo_segs) if self.vbo_origin_co: bgl.glDeleteBuffers(1, self.vbo_origin_co) bgl.glDeleteBuffers(1, self.vbo_origin) if self.vbo_bounds_co: bgl.glDeleteBuffers(1, self.vbo_bounds_co) bgl.glDeleteBuffers(1, self.vbo_bounds) bgl.glDeleteVertexArrays(1, self.vao)
def bindUniformf(self, name): self.findProgram() bgl.glUseProgram(self.program) pname = self.__class__.__name__ + '_' + name bgl.glUniform1f(bgl.glGetUniformLocation(self.program, pname), getattr(self, name))