def setup_render_vertexbuffer(): ''' Create the vertexbuffer object for the rendering program ''' gl.glGenVertexArrays(1, ctypes.byref(render_vao)) gl.glGenBuffers(1, ctypes.byref(render_vertexbuffer)) loc_position = gl.glGetAttribLocation(render_program, ctypes.create_string_buffer(b'position')) loc_color = gl.glGetAttribLocation(render_program, ctypes.create_string_buffer(b'color')) if loc_position < 0: print('Warning: position is not used in the shader') if loc_color < 0: print('Warning: color is not used in the shader') gl.glBindVertexArray(render_vao) gl.glEnableVertexAttribArray(loc_position) gl.glEnableVertexAttribArray(loc_color) gl.glBindBuffer(gl.GL_ARRAY_BUFFER, render_vertexbuffer) gl.glVertexAttribPointer(loc_position, 2, gl.GL_FLOAT, False, ctypes.sizeof(COLOR_VERTEX), ctypes.c_void_p(COLOR_VERTEX.position.offset)) gl.glVertexAttribPointer(loc_color, 4, gl.GL_FLOAT, False, ctypes.sizeof(COLOR_VERTEX), ctypes.c_void_p(COLOR_VERTEX.color.offset)) gl.glBindVertexArray(0)
def __init__(self): self.seed() self.contactListener_keepref = FrictionDetector(self) self.world = Box2D.b2World( (0, 0), contactListener=self.contactListener_keepref) self.viewer = None self.invisible_state_window = None self.invisible_video_window = None self.road = None self.car = None self.reward = 0.0 self.prev_reward = 0.0 self.action_space = spaces.Box(np.array([-1, 0, 0]), np.array([+1, +1, +1])) # steer, gas, brake self.observation_space = spaces.Box(low=0, high=255, shape=(STATE_H, STATE_W, 3), dtype=np.uint8) #VBO stuff self.vertex_vbo_id = gl.GLuint() self.color_vbo_id = gl.GLuint() gl.glGenBuffers(1, self.vertex_vbo_id) gl.glGenBuffers(1, self.color_vbo_id) self.initialized = 0
def vertex_attrib(self, name, data, size=2, stride=0, offset=0): """ Set vertex attribute data in a shader, lacks the flexibility of setting several attributes in one vertex buffer. Parameters ---------- name: the attribute name in the shader. data: a list of vertex attributes (positions, colors, ...) Example: name = "positions", data = [0, 0, 0, 1, 1, 0, 1, 1]. """ data_ctype = (gl.GLfloat * len(data))(*data) vbo_id = gl.GLuint(0) gl.glGenBuffers(1, ct.byref(vbo_id)) gl.glBindBuffer(gl.GL_ARRAY_BUFFER, vbo_id) gl.glBufferData(gl.GL_ARRAY_BUFFER, ct.sizeof(data_ctype), data_ctype, gl.GL_STATIC_DRAW) location = gl.glGetAttribLocation(self.program, name.encode("ascii")) gl.glEnableVertexAttribArray(location) gl.glVertexAttribPointer(location, size, gl.GL_FLOAT, gl.GL_FALSE, stride, ct.c_void_p(offset)) gl.glBindBuffer(gl.GL_ARRAY_BUFFER, 0) return vbo_id
def create_line_generic(draw_type: int, point_list: PointList, color: Color, line_width: float=1): """ This function is used by ``create_line_strip`` and ``create_line_loop``, just changing the OpenGL type for the line drawing. """ data = [] for point in point_list: data.append(point[0]) data.append(point[1]) vbo_id = gl.GLuint() gl.glGenBuffers(1, ctypes.pointer(vbo_id)) # Create a buffer with the data # This line of code is a bit strange. # (gl.GLfloat * len(data)) creates an array of GLfloats, one for each number # (*data) initalizes the list with the floats. *data turns the list into a # tuple. data2 = (gl.GLfloat * len(data))(*data) gl.glBindBuffer(gl.GL_ARRAY_BUFFER, vbo_id) gl.glBufferData(gl.GL_ARRAY_BUFFER, ctypes.sizeof(data2), data2, gl.GL_STATIC_DRAW) shape = VertexBuffer(vbo_id, len(data) // 2, draw_type) shape.color = color shape.line_width = line_width return shape
def set_vertex_attrib(self, name, data): ''' this is an ugly way to set vertex attribute data in a shader. lacks the flexibility of setting several attributes in one vertex buffer. name: the attribute name in the shader. data: a list of vertex attributes (positions, colors, texcoords, normals,...) example: name = 'positions' data = [(1, 1, 0), (2, 2, 1), ...] the items in data must all be 1D lists(or tuples) of the same length. ''' data_flatten = [x for vertex in data for x in vertex] size = len(data[0]) data_ctype = (gl.GLfloat * len(data_flatten))(*data_flatten) vbo_id = gl.GLuint(0) gl.glGenBuffers(1, ct.byref(vbo_id)) gl.glBindBuffer(gl.GL_ARRAY_BUFFER, vbo_id) gl.glBufferData(gl.GL_ARRAY_BUFFER, ct.sizeof(data_ctype), data_ctype, gl.GL_STATIC_DRAW) location = gl.glGetAttribLocation(self.program, name.encode('ascii')) gl.glEnableVertexAttribArray(location) gl.glVertexAttribPointer(location, size, gl.GL_FLOAT, gl.GL_FALSE, 0, 0) gl.glBindBuffer(gl.GL_ARRAY_BUFFER, 0) return vbo_id
def __init__(self, **args): super(Window, self).__init__(**args) self.vao = gl.GLuint(0) gl.glGenVertexArrays(1, ctypes.byref(self.vao)) gl.glBindVertexArray(self.vao) self.vbo = gl.GLuint(0) gl.glGenBuffers(1, ctypes.byref(self.vbo)) gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self.vbo) gl.glBufferData(gl.GL_ARRAY_BUFFER, ctypes.sizeof(gl.GLfloat * len(vertex_positions)), (gl.GLfloat * len(vertex_positions))(*vertex_positions), gl.GL_STATIC_DRAW) gl.glVertexAttribPointer(0, 3, gl.GL_FLOAT, gl.GL_FALSE, 0, 0) gl.glEnableVertexAttribArray(0) self.ibo = gl.GLuint(0) gl.glGenBuffers(1, self.ibo) gl.glBindBuffer(gl.GL_ELEMENT_ARRAY_BUFFER, self.ibo) gl.glBufferData(gl.GL_ELEMENT_ARRAY_BUFFER, ctypes.sizeof(gl.GLuint * len(indices)), (gl.GLuint * len(indices))(*indices), gl.GL_STATIC_DRAW)
def __init__(self): self.fbo = gl.GLuint(0) self.rendered_texture = gl.GLuint(0) self.depthrenderbuffer = gl.GLuint(0) self.pickingbuffer = gl.GLuint(0) self.vertex_buffer = gl.GLuint(0) self.program = GlProgram(shaders.vertex_copy, shaders.fragment_copy) gl.glGenBuffers(1, pointer(self.vertex_buffer)) data = (gl.GLfloat * 16)(-1, -1, 0, 0, - 1, 1, 0, 1, 1, 1, 1, 1, 1, -1, 1, 0) gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self.vertex_buffer) gl.glBufferData(gl.GL_ARRAY_BUFFER, sizeof(data), data, gl.GL_STATIC_DRAW) gl.glGenFramebuffers(1, pointer(self.fbo)) if not self.fbo: logging.error('failed fbo') gl.glBindFramebuffer(gl.GL_FRAMEBUFFER, self.fbo) gl.glGenTextures(1, pointer(self.rendered_texture)) if not self.rendered_texture: logging.error('failed rendered_texture') gl.glGenRenderbuffers(1, pointer(self.depthrenderbuffer)) gl.glGenRenderbuffers(1, pointer(self.pickingbuffer)) self.resize(1, 1)
def setup_copy_vertexbuffer(): ''' Create the vertexbuffer object for the copying program ''' # gl.glGenVertexArrays(1, ctypes.byref(copy_vao)) gl.glGenBuffers(1, ctypes.byref(copy_vertexbuffer)) loc_position = gl.glGetAttribLocation( copy_program, ctypes.create_string_buffer(b'position')) loc_texcoord = gl.glGetAttribLocation( copy_program, ctypes.create_string_buffer(b'texcoord')) if loc_position < 0: print('Warning: position is not used in the shader') if loc_texcoord < 0: print('Warning: texcoord is not used in the shader') gl.glBindVertexArray(copy_vao) gl.glEnableVertexAttribArray(loc_position) gl.glEnableVertexAttribArray(loc_texcoord) gl.glBindBuffer(gl.GL_ARRAY_BUFFER, copy_vertexbuffer) gl.glVertexAttribPointer(loc_position, 2, gl.GL_FLOAT, False, ctypes.sizeof(TEXTURE_VERTEX), ctypes.c_void_p(TEXTURE_VERTEX.position.offset)) gl.glVertexAttribPointer(loc_texcoord, 2, gl.GL_FLOAT, False, ctypes.sizeof(TEXTURE_VERTEX), ctypes.c_void_p(TEXTURE_VERTEX.texcoord.offset)) gl.glBindVertexArray(0)
def setup_render_vertexbuffer(): ''' Create the vertexbuffer object for the rendering program ''' gl.glGenVertexArrays(1, ctypes.byref(render_vao)) gl.glGenBuffers(1, ctypes.byref(render_vertexbuffer)) loc_position = gl.glGetAttribLocation( render_program, ctypes.create_string_buffer(b'position')) loc_color = gl.glGetAttribLocation(render_program, ctypes.create_string_buffer(b'color')) if loc_position < 0: print('Warning: position is not used in the shader') if loc_color < 0: print('Warning: color is not used in the shader') gl.glBindVertexArray(render_vao) gl.glEnableVertexAttribArray(loc_position) gl.glEnableVertexAttribArray(loc_color) gl.glBindBuffer(gl.GL_ARRAY_BUFFER, render_vertexbuffer) gl.glVertexAttribPointer(loc_position, 2, gl.GL_FLOAT, False, ctypes.sizeof(COLOR_VERTEX), ctypes.c_void_p(COLOR_VERTEX.position.offset)) gl.glVertexAttribPointer(loc_color, 4, gl.GL_FLOAT, False, ctypes.sizeof(COLOR_VERTEX), ctypes.c_void_p(COLOR_VERTEX.color.offset)) gl.glBindVertexArray(0)
def __init__(self, data, dimension=3): """ Vertex Buffer Object for storing data in OpenGl. Args: data: An array of values. dimension: Whether the array is 1D, 2D, 3D or 4D. """ data_type = c_float elements = len(data) buffer_type = data_type * elements buffer = buffer_type() buffer[:] = data # About 2.5 times faster than passing arguments during initialization. handle = c_uint() glGenBuffers(1, handle) glBindBuffer(GL_ARRAY_BUFFER, handle) glBufferData(GL_ARRAY_BUFFER, elements * sizeof(data_type), buffer, GL_STATIC_DRAW) glBindBuffer(GL_ARRAY_BUFFER, 0) super(VBO, self).__init__(handle.value) self.data_type = GL_FLOAT self.count = elements // dimension self.dimension = dimension
def set_vertex_attrib(self, name, data): """This is an ugly way to set vertex attribute data in a shader, it lacks the flexibility of setting several attributes in one vertex buffer. name: the attribute name in the shader. data: a list of vertex attributes (positions, colors, texcoords, normals,...) example: name = 'positions', data = [(1, 1, 0), (2, 2, 1), ...] the items in data must all be 1D lists(or tuples) of the same length. """ data_flatten = [x for vertex in data for x in vertex] size = len(data[0]) data_ctype = (gl.GLfloat * len(data_flatten))(*data_flatten) vbo_id = gl.GLuint(0) gl.glGenBuffers(1, ct.byref(vbo_id)) gl.glBindBuffer(gl.GL_ARRAY_BUFFER, vbo_id) gl.glBufferData(gl.GL_ARRAY_BUFFER, ct.sizeof(data_ctype), data_ctype, gl.GL_STATIC_DRAW) location = gl.glGetAttribLocation(self.program, name.encode('ascii')) gl.glEnableVertexAttribArray(location) gl.glVertexAttribPointer(location, size, gl.GL_FLOAT, gl.GL_FALSE, 0, 0) gl.glBindBuffer(gl.GL_ARRAY_BUFFER, 0) return vbo_id
def __init__( self, ctx, data: Optional[Any] = None, reserve: int = 0, usage: str = "static" ): """ :param Context ctx: The context this buffer belongs to :param Any data: The data this buffer should contain. It can be bytes or any object supporting the buffer protocol. :param int reserve: Create a buffer of a specific byte size :param str usage: A hit of this buffer is ``static`` or ``dynamic`` (can mostly be ignored) """ self._ctx = ctx self._glo = glo = gl.GLuint() self._size = -1 self._usage = Buffer._usages[usage] gl.glGenBuffers(1, byref(self._glo)) # print(f"glGenBuffers() -> {self._glo.value}") if self._glo.value == 0: raise RuntimeError("Cannot create Buffer object.") # print(f"glBindBuffer({self._glo.value})") gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self._glo) # print(f"glBufferData(gl.GL_ARRAY_BUFFER, {self._size}, data, {self._usage})") if data is not None and len(data) > 0: self._size, data = data_to_ctypes(data) gl.glBufferData(gl.GL_ARRAY_BUFFER, self._size, data, self._usage) elif reserve > 0: self._size = reserve gl.glBufferData(gl.GL_ARRAY_BUFFER, self._size, None, self._usage) else: raise ValueError("Buffer takes byte data or number of reserved bytes") self.ctx.stats.incr("buffer") weakref.finalize(self, Buffer.release, self.ctx, glo)
def setup_copy_vertexbuffer(): ''' Create the vertexbuffer object for the copying program ''' # gl.glGenVertexArrays(1, ctypes.byref(copy_vao)) gl.glGenBuffers(1, ctypes.byref(copy_vertexbuffer)) loc_position = gl.glGetAttribLocation(copy_program, ctypes.create_string_buffer(b'position')) loc_texcoord = gl.glGetAttribLocation(copy_program, ctypes.create_string_buffer(b'texcoord')) if loc_position < 0: print('Warning: position is not used in the shader') if loc_texcoord < 0: print('Warning: texcoord is not used in the shader') gl.glBindVertexArray(copy_vao) gl.glEnableVertexAttribArray(loc_position) gl.glEnableVertexAttribArray(loc_texcoord) gl.glBindBuffer(gl.GL_ARRAY_BUFFER, copy_vertexbuffer) gl.glVertexAttribPointer(loc_position, 2, gl.GL_FLOAT, False, ctypes.sizeof(TEXTURE_VERTEX), ctypes.c_void_p(TEXTURE_VERTEX.position.offset)) gl.glVertexAttribPointer(loc_texcoord, 2, gl.GL_FLOAT, False, ctypes.sizeof(TEXTURE_VERTEX), ctypes.c_void_p(TEXTURE_VERTEX.texcoord.offset)) gl.glBindVertexArray(0)
def create_ellipse(width, height, color): """ This creates an ellipse vertex buffer object (VBO). It can later be drawn with ``render_ellipse_filled``. This method of drawing an ellipse is much faster than calling ``draw_ellipse_filled`` each frame. """ num_segments = 64 data = [] for i in range(num_segments + 1): theta = 2.0 * 3.1415926 * i / num_segments x = width * math.cos(theta) y = height * math.sin(theta) data.extend([x, y]) vbo_id = GL.GLuint() GL.glGenBuffers(1, ctypes.pointer(vbo_id)) v2f = data data2 = (GL.GLfloat*len(v2f))(*v2f) GL.glBindBuffer(GL.GL_ARRAY_BUFFER, vbo_id) GL.glBufferData(GL.GL_ARRAY_BUFFER, ctypes.sizeof(data2), data2, GL.GL_STATIC_DRAW) shape = VertexBuffer(vbo_id, len(v2f)//2, width, height, color) return shape
def __init__(self, buffer_type, nums_per_vertex, data, data_type): self.type = buffer_type self.nums_per_vertex = nums_per_vertex self.uploaded = False self.data = data self.data_type = data_type self.handle = GLuint() glGenBuffers(1, self.handle)
def __init__(self, type, data): self.type = type self.data = data self.id = gl.GLuint() gl.glGenBuffers(1, ctypes.pointer(self.id)) self.data_ptr = (gl.GLfloat * len(data))(*data) gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self.id) gl.glBufferData(gl.GL_ARRAY_BUFFER, ctypes.sizeof(self.data_ptr), self.data_ptr, gl.GL_STATIC_DRAW)
def createVertexbuffer(vertexData, vertexSize=3, bufferType=GL.GL_VERTEX_ARRAY): """Create a static, single-storage Vertex Buffer Object (VBO). Parameters ---------- vertexData : :obj:`list` or :obj:`tuple` of :obj:`float` Coordinates as a 1D array of floats (e.g. [X0, Y0, Z0, X1, Y1, Z1, ...]) vertexSize : :obj:`int` Number of coordinates per-vertex, default is 3. bufferType : :obj:`int` The type of data stored in the buffer (e.g. GL_VERTEX_ARRAY, GL_TEXTURE_COORD_ARRAY, GL_NORMAL_ARRAY, etc.) Returns ------- Vertexbuffer A descriptor with vertex buffer information. Examples -------- # vertices of a triangle verts = [ 1.0, 1.0, 0.0, # v0 0.0, -1.0, 0.0, # v1 -1.0, 1.0, 0.0] # v2 # load vertices to graphics device, return a descriptor vboDesc = createVertexbuffer(verts, 3) # draw GL.glBindBuffer(GL.GL_ARRAY_BUFFER, vboDesc.id) GL.glVertexPointer(vboDesc.vertexSize, vboDesc.dtype, 0, None) GL.glEnableClientState(vboDesc.bufferType) GL.glDrawArrays(GL.GL_TRIANGLES, 0, vboDesc.indices) GL.glFlush() """ # convert values to ctypes float array count = len(vertexData) c_array = (GL.GLfloat * count)(*vertexData) # create a vertex buffer ID vboId = GL.GLuint() GL.glGenBuffers(1, ctypes.byref(vboId)) # new vertex descriptor vboDesc = Vertexbuffer(vboId, vertexSize, count, int(count / vertexSize), GL.GL_STATIC_DRAW, bufferType, GL.GL_FLOAT) # always float # bind and upload GL.glBindBuffer(GL.GL_ARRAY_BUFFER, vboId) GL.glBufferData(GL.GL_ARRAY_BUFFER, ctypes.sizeof(c_array), c_array, GL.GL_STATIC_DRAW) # GL.glBindBuffer(GL.GL_ARRAY_BUFFER, 0) return vboDesc
def _create_device_objects(self): # save state last_texture = gl.GLint() gl.glGetIntegerv(gl.GL_TEXTURE_BINDING_2D, byref(last_texture)) last_array_buffer = gl.GLint() gl.glGetIntegerv(gl.GL_ARRAY_BUFFER_BINDING, byref(last_array_buffer)) last_vertex_array = gl.GLint() gl.glGetIntegerv(gl.GL_VERTEX_ARRAY_BINDING, byref(last_vertex_array)) self._shader_handle = gl.glCreateProgram() # note: no need to store shader parts handles after linking vertex_shader = gl.glCreateShader(gl.GL_VERTEX_SHADER) fragment_shader = gl.glCreateShader(gl.GL_FRAGMENT_SHADER) gl.glShaderSource(vertex_shader, 1, make_string_buffer(self.VERTEX_SHADER_SRC), None) gl.glShaderSource(fragment_shader, 1, make_string_buffer(self.FRAGMENT_SHADER_SRC), None) gl.glCompileShader(vertex_shader) gl.glCompileShader(fragment_shader) gl.glAttachShader(self._shader_handle, vertex_shader) gl.glAttachShader(self._shader_handle, fragment_shader) gl.glLinkProgram(self._shader_handle) # note: after linking shaders can be removed gl.glDeleteShader(vertex_shader) gl.glDeleteShader(fragment_shader) self._attrib_location_tex = gl.glGetUniformLocation(self._shader_handle, create_string_buffer(b"Texture")) self._attrib_proj_mtx = gl.glGetUniformLocation(self._shader_handle, create_string_buffer(b"ProjMtx")) self._attrib_location_position = gl.glGetAttribLocation(self._shader_handle, create_string_buffer(b"Position")) self._attrib_location_uv = gl.glGetAttribLocation(self._shader_handle, create_string_buffer(b"UV")) self._attrib_location_color = gl.glGetAttribLocation(self._shader_handle, create_string_buffer(b"Color")) self._vbo_handle = gl.GLuint() gl.glGenBuffers(1, byref(self._vbo_handle)) self._elements_handle = gl.GLuint() gl.glGenBuffers(1, byref(self._elements_handle)) self._vao_handle = gl.GLuint() gl.glGenVertexArrays(1, byref(self._vao_handle)) gl.glBindVertexArray(self._vao_handle) gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self._vbo_handle) gl.glEnableVertexAttribArray(self._attrib_location_position) gl.glEnableVertexAttribArray(self._attrib_location_uv) gl.glEnableVertexAttribArray(self._attrib_location_color) gl.glVertexAttribPointer(self._attrib_location_position, 2, gl.GL_FLOAT, gl.GL_FALSE, imgui.VERTEX_SIZE, c_void_p(imgui.VERTEX_BUFFER_POS_OFFSET)) gl.glVertexAttribPointer(self._attrib_location_uv, 2, gl.GL_FLOAT, gl.GL_FALSE, imgui.VERTEX_SIZE, c_void_p(imgui.VERTEX_BUFFER_UV_OFFSET)) gl.glVertexAttribPointer(self._attrib_location_color, 4, gl.GL_UNSIGNED_BYTE, gl.GL_TRUE, imgui.VERTEX_SIZE, c_void_p(imgui.VERTEX_BUFFER_COL_OFFSET)) # restore state gl.glBindTexture(gl.GL_TEXTURE_2D, cast((c_int*1)(last_texture), POINTER(c_uint)).contents) gl.glBindBuffer(gl.GL_ARRAY_BUFFER, cast((c_int*1)(last_array_buffer), POINTER(c_uint)).contents) gl.glBindVertexArray(cast((c_int*1)(last_vertex_array), POINTER(c_uint)).contents)
def create_rectangle(center_x: float, center_y: float, width: float, height: float, color: Color, border_width: float = 0, tilt_angle: float = 0, filled=True) -> VertexBuffer: """ This function creates a rectangle using a vertex buffer object. Creating the rectangle, and then later drawing it with ``render_rectangle`` is faster than calling ``draw_rectangle``. >>> import arcade >>> arcade.open_window(800,600,"Drawing Example") >>> my_rect = arcade.create_rectangle(200, 200, 50, 50, (0, 255, 0), 3, 45) >>> arcade.render(my_rect) >>> arcade.finish_render() >>> arcade.quick_run(0.25) """ data = get_rectangle_points(center_x, center_y, width, height, tilt_angle) # print(data) vbo_id = gl.GLuint() gl.glGenBuffers(1, ctypes.pointer(vbo_id)) # Create a buffer with the data # This line of code is a bit strange. # (gl.GLfloat * len(data)) creates an array of GLfloats, one for each number # (*data) initalizes the list with the floats. *data turns the list into a # tuple. data2 = (gl.GLfloat * len(data))(*data) gl.glBindBuffer(gl.GL_ARRAY_BUFFER, vbo_id) gl.glBufferData(gl.GL_ARRAY_BUFFER, ctypes.sizeof(data2), data2, gl.GL_STATIC_DRAW) if filled: shape_mode = gl.GL_QUADS else: shape_mode = gl.GL_LINE_LOOP shape = VertexBuffer(vbo_id, len(data) // 2, shape_mode) # Colors shape.vbo_color_id = gl.GLuint() gl.glGenBuffers(1, ctypes.pointer(shape.vbo_color_id)) color_data = _fix_color_list((color, color, color, color)) gl_color_list = (gl.GLfloat * len(color_data))(*color_data) gl.glBindBuffer(gl.GL_ARRAY_BUFFER, shape.vbo_color_id) gl.glBufferData(gl.GL_ARRAY_BUFFER, ctypes.sizeof(gl_color_list), gl_color_list, gl.GL_STATIC_DRAW) shape.line_width = border_width return shape
def _create_vbo() -> gl.GLuint: """ This creates a new vertex buffer id. """ vbo_id = gl.GLuint() gl.glGenBuffers(1, ctypes.pointer(vbo_id)) return vbo_id
def __init__(self, ec, fill_color, line_color, line_width, line_loop): self._ec = ec self._line_width = line_width self._line_loop = line_loop # whether or not lines drawn are looped # initialize program and shaders from pyglet import gl self._program = gl.glCreateProgram() vertex = gl.glCreateShader(gl.GL_VERTEX_SHADER) buf = create_string_buffer(tri_vert.encode('ASCII')) ptr = cast(pointer(pointer(buf)), POINTER(POINTER(c_char))) gl.glShaderSource(vertex, 1, ptr, None) gl.glCompileShader(vertex) _check_log(vertex, gl.glGetShaderInfoLog) fragment = gl.glCreateShader(gl.GL_FRAGMENT_SHADER) buf = create_string_buffer(tri_frag.encode('ASCII')) ptr = cast(pointer(pointer(buf)), POINTER(POINTER(c_char))) gl.glShaderSource(fragment, 1, ptr, None) gl.glCompileShader(fragment) _check_log(fragment, gl.glGetShaderInfoLog) gl.glAttachShader(self._program, vertex) gl.glAttachShader(self._program, fragment) gl.glLinkProgram(self._program) _check_log(self._program, gl.glGetProgramInfoLog) gl.glDetachShader(self._program, vertex) gl.glDetachShader(self._program, fragment) gl.glUseProgram(self._program) # Prepare buffers and bind attributes loc = gl.glGetUniformLocation(self._program, b'u_view') view = ec.window_size_pix view = np.diag([2. / view[0], 2. / view[1], 1., 1.]) view[-1, :2] = -1 view = view.astype(np.float32).ravel() gl.glUniformMatrix4fv(loc, 1, False, (c_float * 16)(*view)) self._counts = dict() self._colors = dict() self._buffers = dict() self._points = dict() self._tris = dict() for kind in ('line', 'fill'): self._counts[kind] = 0 self._colors[kind] = (0., 0., 0., 0.) self._buffers[kind] = dict(array=gl.GLuint()) gl.glGenBuffers(1, pointer(self._buffers[kind]['array'])) self._buffers['fill']['index'] = gl.GLuint() gl.glGenBuffers(1, pointer(self._buffers['fill']['index'])) gl.glUseProgram(0) self.set_fill_color(fill_color) self.set_line_color(line_color)
def __init__(self, data: List[int], structure=gl.GLuint): self.name = gl.GLuint() self.structure = structure gl.glGenBuffers(1, byref(self.name)) gl.glBindBuffer(gl.GL_ELEMENT_ARRAY_BUFFER, self.name) self.length = len(data) self.size = self.length * sizeof(structure) gl.glBufferData(gl.GL_ELEMENT_ARRAY_BUFFER, self.size, (structure * len(data))(*data), gl.GL_STATIC_DRAW) gl.glBindBuffer(gl.GL_ELEMENT_ARRAY_BUFFER, 0)
def create(cls, data, dimension, type=GLfloat, draw_mode=GL_STATIC_DRAW): assert type in VBO.VALID_TYPES, "Invalid type for VBO!" handle = GLuint() glGenBuffers(1, handle) glBindBuffer(VBO.TARGET, handle) glBufferData(VBO.TARGET, len(data) * sizeof(type), (type * len(data))(*data), draw_mode) return cls(handle, dimension, GL_TYPE_TO_CONSTANT[type])
def __init__(self, vertices: np.ndarray, indices: np.ndarray, mode=None, texture=None): if mode is None: mode = gl.GL_TRIANGLES self.vertices = vertices self.indices = indices self.indices_size = indices.size self.mode = mode self.texture = texture self.vao = gl.GLuint(0) gl.glGenVertexArrays(1, ctypes.byref(self.vao)) gl.glBindVertexArray(self.vao) self.vbo = gl.GLuint(0) gl.glGenBuffers(1, ctypes.byref(self.vbo)) gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self.vbo) gl.glBufferData( gl.GL_ARRAY_BUFFER, # target vertices.nbytes, # size (gl.GLbyte * vertices.nbytes)(*vertices.tobytes()), # data gl.GL_STATIC_DRAW, ) # usage self.ebo = gl.GLuint(0) gl.glGenBuffers(1, ctypes.byref(self.ebo)) gl.glBindBuffer(gl.GL_ELEMENT_ARRAY_BUFFER, self.ebo) gl.glBufferData( gl.GL_ELEMENT_ARRAY_BUFFER, indices.nbytes, (gl.GLbyte * indices.nbytes)(*indices.tobytes()), gl.GL_STATIC_DRAW, ) for ind, fld in enumerate( sorted([f for f in vertices.dtype.fields.items()], key=lambda i: i[1][1])): gl.glVertexAttribPointer( ind, # index vertices[0][fld[0]].size, # size gl.GL_FLOAT, # type gl.GL_FALSE, # normalized vertices.itemsize, # stride ctypes.c_void_p(fld[1][1]), ) # pointer gl.glEnableVertexAttribArray(ind) if texture is not None: texture_image = pyglet.image.load(texture) self.texture = texture_image.get_texture() gl.glBindVertexArray(0)
def __init__(self, data, usage=GL_STATIC_DRAW): """ Initiate the vertex buffer object on the CPU """ self.buffer = GLuint(0) glGenBuffers(1, self.buffer) self.buffer = self.buffer.value glBindBuffer(GL_ARRAY_BUFFER, self.buffer) glBufferData(GL_ARRAY_BUFFER, ADT.arrayByteCount(data), ADT.voidDataPointer(data), usage)
def __alloc(cls, target, format, usage): buf = super().__new__(cls) buf.owned = True buf.bid = GLuint() glGenBuffers(1, byref(buf.bid)) glBindBuffer(target, buf.bid) buf._usage = usage buf.format = BufferFormat.new(format) buf.target = target buf.mapinfo = None return buf
def initialize_gl(self): self.program = GlProgram(shaders.vertex_scene, shaders.fragment_scene) self.program.uniform2f(b'scroll_offset', 0, 0) self.sprite_program = GlProgram(shaders.vertex_scene, shaders.fragment_sprite) self.sprite_texture = gltexture.make_texture('sprites.png') self.buffer = gl.GLuint(0) gl.glGenBuffers(1, ctypes.pointer(self.buffer)) gl.glEnable(gl.GL_BLEND) gl.glEnable(gl.GL_DEPTH_TEST) gl.glBlendFunc(gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA)
def __init__(self, data: bytes, usage: str = 'static'): self.buffer_id = buffer_id = gl.GLuint() self.size = len(data) gl.glGenBuffers(1, byref(self.buffer_id)) if self.buffer_id.value == 0: raise ShaderException("Cannot create Buffer object.") gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self.buffer_id) self.usage = Buffer.usages[usage] gl.glBufferData(gl.GL_ARRAY_BUFFER, self.size, data, self.usage) weakref.finalize(self, Buffer.release, buffer_id)
def __init__(self, buffer, data_type=GLuint): # TODO Make so you don't have to initialize with a buffer. super().__init__() count = len(buffer) size = count * sizeof(data_type) Array = data_type * count glGenBuffers(1, self) glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, self) glBufferData(GL_ELEMENT_ARRAY_BUFFER, size, Array(*buffer), GL_STATIC_DRAW) self.count = count self.size = size
def create_vbo_for_rects(v2f): vbo_id = GL.GLuint() GL.glGenBuffers(1, ctypes.pointer(vbo_id)) data2 = (GL.GLfloat*len(v2f))(*v2f) GL.glBindBuffer(GL.GL_ARRAY_BUFFER, vbo_id) GL.glBufferData(GL.GL_ARRAY_BUFFER, ctypes.sizeof(data2), data2, GL.GL_STATIC_DRAW) shape = VertexBuffer(vbo_id, len(v2f)//2) return shape
def __init__(self, **args): super().__init__(**args) # create vertex array object self.vao = gl.GLuint(0) gl.glGenVertexArrays(1, ctypes.byref(self.vao)) gl.glBindVertexArray(self.vao) # create vertex buffer object self.vbo = gl.GLuint(0) gl.glGenBuffers(1, ctypes.byref(self.vbo)) gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self.vbo) gl.glBufferData(gl.GL_ARRAY_BUFFER, ctypes.sizeof(gl.GLfloat * len(vertex_positions)), (gl.GLfloat * len(vertex_positions))(*vertex_positions), gl.GL_STATIC_DRAW) gl.glVertexAttribPointer(0, 3, gl.GL_FLOAT, gl.GL_FALSE, 0, 0) gl.glEnableVertexAttribArray(0) # create index buffer object self.ibo = gl.GLuint(0) gl.glGenBuffers(1, self.ibo) gl.glBindBuffer(gl.GL_ELEMENT_ARRAY_BUFFER, self.ibo) gl.glBufferData(gl.GL_ELEMENT_ARRAY_BUFFER, ctypes.sizeof(gl.GLuint * len(indices)), (gl.GLuint * len(indices))(*indices), gl.GL_STATIC_DRAW) # create shader self.shader = shader.Shader("vert.glsl", "frag.glsl") self.shader_matrix_location = self.shader.find_uniform( b"matrix") # get the shader matrix uniform location self.shader.use() # create matrices self.mv_matrix = matrix.Matrix() # modelview self.p_matrix = matrix.Matrix() # projection self.x = 0 # temporary variable pyglet.clock.schedule_interval( self.update, 1.0 / 60) # call update function every 60th of a second
def gen_vertices(self): # Just make a cube for now self.vertices = (GLfloat * 108)(*[ -1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0, 1.0, -1.0, -1.0, 1.0, -1.0, -1.0, -1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, 1.0, -1.0, 1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 1.0, 1.0, 1.0, -1.0, 1.0 ]) glGenVertexArrays(1, self.vao) glGenBuffers(1, self.vbo) glBindBuffer(GL_ARRAY_BUFFER, self.vbo) glBufferData(GL_ARRAY_BUFFER, sizeof(self.vertices), self.vertices, GL_STATIC_DRAW) glBindVertexArray(self.vao) glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), 0) glEnableVertexAttribArray(0)
def _create_filled_with_colors(point_list, color_list, shape_mode): number_points = len(point_list) vertex_data = [] for point in point_list: vertex_data.append(point[0]) vertex_data.append(point[1]) color_data = [] for color in color_list: color_data.append(color[0] / 255.) color_data.append(color[1] / 255.) color_data.append(color[2] / 255.) if len(color) == 3: color_data.append(1.0) else: color_data.append(color[3] / 255.) vbo_vertex_id = gl.GLuint() gl.glGenBuffers(1, ctypes.pointer(vbo_vertex_id)) # Create a buffer with the data # This line of code is a bit strange. # (gl.GLfloat * len(data)) creates an array of GLfloats, one for each number # (*data) initalizes the list with the floats. *data turns the list into a # tuple. data2 = (gl.GLfloat * len(vertex_data))(*vertex_data) gl.glBindBuffer(gl.GL_ARRAY_BUFFER, vbo_vertex_id) gl.glBufferData(gl.GL_ARRAY_BUFFER, ctypes.sizeof(data2), data2, gl.GL_STATIC_DRAW) # Colors vbo_color_id = gl.GLuint() gl.glGenBuffers(1, ctypes.pointer(vbo_color_id)) gl_color_list = (gl.GLfloat * len(color_data))(*color_data) gl.glBindBuffer(gl.GL_ARRAY_BUFFER, vbo_color_id) gl.glBufferData(gl.GL_ARRAY_BUFFER, ctypes.sizeof(gl_color_list), gl_color_list, gl.GL_STATIC_DRAW) shape = VertexBuffer(vbo_vertex_id, number_points, shape_mode, vbo_color_id=vbo_color_id) return shape
def create_filled_rectangles_with_colors(point_list, color_list) -> VertexBuffer: """ This function creates multiple rectangle/quads using a vertex buffer object. Creating the rectangles, and then later drawing it with ``render`` is faster than calling ``draw_rectangle``. >>> import arcade >>> arcade.open_window(800,600,"Drawing Example") >>> point_list = [0, 0, 100, 0, 100, 100, 0, 100] >>> color_list = [0, 255, 0] >>> my_shape = arcade.create_filled_rectangles_with_colors(point_list, color_list) >>> my_shape_list = ShapeElementList() >>> my_shape_list.append(my_shape) >>> my_shape_list.draw() >>> arcade.finish_render() >>> arcade.quick_run(0.25) """ vbo_vertex_id = gl.GLuint() gl.glGenBuffers(1, ctypes.pointer(vbo_vertex_id)) # Create a buffer with the data # This line of code is a bit strange. # (gl.GLfloat * len(data)) creates an array of GLfloats, one for each number # (*data) initalizes the list with the floats. *data turns the list into a # tuple. gl_point_list = (gl.GLfloat * len(point_list))(*point_list) gl.glBindBuffer(gl.GL_ARRAY_BUFFER, vbo_vertex_id) gl.glBufferData(gl.GL_ARRAY_BUFFER, ctypes.sizeof(gl_point_list), gl_point_list, gl.GL_STATIC_DRAW) # Colors vbo_color_id = gl.GLuint() gl.glGenBuffers(1, ctypes.pointer(vbo_color_id)) gl_color_list = (gl.GLfloat * len(color_list))(*color_list) gl.glBindBuffer(gl.GL_ARRAY_BUFFER, vbo_color_id) gl.glBufferData(gl.GL_ARRAY_BUFFER, ctypes.sizeof(gl_color_list), gl_color_list, gl.GL_STATIC_DRAW) shape_mode = gl.GL_QUADS shape = VertexBuffer(vbo_vertex_id, len(point_list) // 2, shape_mode, vbo_color_id=vbo_color_id) return shape
def __init__(self, world, chunk_position): self.chunk_position = chunk_position self.position = ( # get a world-space position for the chunk self.chunk_position[0] * CHUNK_WIDTH, self.chunk_position[1] * CHUNK_HEIGHT, self.chunk_position[2] * CHUNK_LENGTH) self.world = world self.blocks = [ [ [ 0 # create an array of blocks filled with "air" (block number 0) for z in range(CHUNK_LENGTH) ] for y in range(CHUNK_HEIGHT) ] for x in range(CHUNK_WIDTH) ] # mesh variables self.has_mesh = False self.mesh_vertex_positions = [] self.mesh_tex_coords = [] self.mesh_shading_values = [] self.mesh_index_counter = 0 self.mesh_indices = [] # create vertex array object self.vao = gl.GLuint(0) gl.glGenVertexArrays(1, self.vao) gl.glBindVertexArray(self.vao) # create vertex position vbo self.vertex_position_vbo = gl.GLuint(0) gl.glGenBuffers(1, self.vertex_position_vbo) # create tex coord vbo self.tex_coord_vbo = gl.GLuint(0) gl.glGenBuffers(1, self.tex_coord_vbo) # create shading values vbo self.shading_values_vbo = gl.GLuint(0) gl.glGenBuffers(1, self.shading_values_vbo) # create index buffer object self.ibo = gl.GLuint(0) gl.glGenBuffers(1, self.ibo)
def create_line(start_x: float, start_y: float, end_x: float, end_y: float, color: Color, line_width: float = 1): """ Create a line to be rendered later. This works faster than draw_line because the vertexes are only loaded to the graphics card once, rather than each frame. :Example: >>> import arcade >>> arcade.open_window(800,600,"Drawing Example") >>> arcade.start_render() >>> line1 = arcade.create_line(0, 0, 100, 100, (255, 0, 0), 2) >>> arcade.render(line1) >>> arcade.finish_render() >>> arcade.quick_run(0.25) """ data = [start_x, start_y, end_x, end_y] # print(data) vbo_id = gl.GLuint() gl.glGenBuffers(1, ctypes.pointer(vbo_id)) # Create a buffer with the data # This line of code is a bit strange. # (gl.GLfloat * len(data)) creates an array of GLfloats, one for each number # (*data) initalizes the list with the floats. *data turns the list into a # tuple. data2 = (gl.GLfloat * len(data))(*data) gl.glBindBuffer(gl.GL_ARRAY_BUFFER, vbo_id) gl.glBufferData(gl.GL_ARRAY_BUFFER, ctypes.sizeof(data2), data2, gl.GL_STATIC_DRAW) shape_mode = gl.GL_LINES shape = VertexBuffer(vbo_id, len(data) // 2, shape_mode) shape.color = color shape.line_width = line_width return shape
def init_gl(self): '''initialize the opengl resources needed for presenting windows * a shader program * a vertex buffer * a texture for Label windows ''' self.program = GlProgram(shaders.vertex_flat, shaders.fragment_flat) self.buffer = gl.GLuint(0) gl.glGenBuffers(1, pointer(self.buffer)) self.texture = gl.GLuint(0) gl.glGenTextures(1, pointer(self.texture)) gl.glBindTexture(gl.GL_TEXTURE_2D, self.texture) gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_NEAREST) gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_NEAREST) gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_S, gl.GL_CLAMP_TO_EDGE) gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_T, gl.GL_CLAMP_TO_EDGE) gl.glBindTexture(gl.GL_TEXTURE_2D, 0)
def create_rect(width, height, color): """ Create a vertex buffer for a rectangle. """ v2f = [-width / 2, -height / 2, width / 2, -height / 2, width / 2, height / 2, -width / 2, height / 2] vbo_id = GL.GLuint() GL.glGenBuffers(1, ctypes.pointer(vbo_id)) data2 = (GL.GLfloat*len(v2f))(*v2f) GL.glBindBuffer(GL.GL_ARRAY_BUFFER, vbo_id) GL.glBufferData(GL.GL_ARRAY_BUFFER, ctypes.sizeof(data2), data2, GL.GL_STATIC_DRAW) shape = VertexBuffer(vbo_id, len(v2f)//2, width, height, color) return shape
def create_colors(rect_list): """ Create a vertex buffer for a set of rectangles. """ v2f = [] for shape in rect_list: for i in range(4): v2f.extend(shape.color) vbo_id = GL.GLuint() GL.glGenBuffers(1, ctypes.pointer(vbo_id)) data2 = (GL.GLfloat*len(v2f))(*v2f) GL.glBindBuffer(GL.GL_ARRAY_BUFFER, vbo_id) GL.glBufferData(GL.GL_ARRAY_BUFFER, ctypes.sizeof(data2), data2, GL.GL_STATIC_DRAW) return vbo_id
def create_rects(rect_list): """ Create a vertex buffer for a set of rectangles. """ v2f = [] for shape in rect_list: v2f.extend([-shape.width / 2, -shape.height / 2, shape.width / 2, -shape.height / 2, shape.width / 2, shape.height / 2, -shape.width / 2, shape.height / 2]) vbo_id = GL.GLuint() GL.glGenBuffers(1, ctypes.pointer(vbo_id)) data2 = (GL.GLfloat*len(v2f))(*v2f) GL.glBindBuffer(GL.GL_ARRAY_BUFFER, vbo_id) GL.glBufferData(GL.GL_ARRAY_BUFFER, ctypes.sizeof(data2), data2, GL.GL_STATIC_DRAW) shape = VertexBuffer(vbo_id, len(v2f)//2) return shape
def __init__(self, size=0, dtype=numpy.float32, usage=gl.GL_DYNAMIC_DRAW): ''' size - how much storage to allocate for this buffer in advance (in items, not bytes) dtype - type of items in storage (float, float16, float32, int, etc.) usage - one of GL_{STREAM,STATIC,DYNAMIC}_{READ,COPY,DRAW} Description copied from OpenGL reference pages: The frequency of access may be one of these: STREAM The data store contents will be modified once and used at most a few times. STATIC The data store contents will be modified once and used many times. DYNAMIC The data store contents will be modified repeatedly and used many times. The nature of access may be one of these: DRAW The data store contents are modified by the application, and used as the source for GL drawing and image specification commands. READ The data store contents are modified by reading data from the GL, and used to return that data when queried by the application. COPY The data store contents are modified by reading data from the GL, and used as the source for GL drawing and image specification commands.''' self.usage = usage self.dtype = numpy.dtype(dtype) bufid = ctypes.c_uint(0) gl.glGenBuffers(1, ctypes.byref(bufid)) self.bufid = bufid self.bound = _GLBufferContext(self.bufid) if size > 0: with self.bound: gl.glBufferData(gl.GL_ARRAY_BUFFER, size * self.dtype.itemsize, None, self.usage)
def create_rectangle(width, height, color): """ This function creates a rectangle using a vertex buffer object. Creating the rectangle, and then later drawing it with ``render_rectangle`` is faster than calling ``draw_rectangle``. """ data = [-width / 2, -height / 2, width / 2, -height / 2, width / 2, height / 2, -width / 2, height / 2] vbo_id = GL.GLuint() GL.glGenBuffers(1, ctypes.pointer(vbo_id)) v2f = data data2 = (GL.GLfloat*len(v2f))(*v2f) GL.glBindBuffer(GL.GL_ARRAY_BUFFER, vbo_id) GL.glBufferData(GL.GL_ARRAY_BUFFER, ctypes.sizeof(data2), data2, GL.GL_STATIC_DRAW) shape = VertexBuffer(vbo_id, len(v2f)//2, width, height, color) return shape
def __init__(self): self.__value = None buf = ct.c_uint() gl.glGenBuffers(1, ct.byref(buf)) self.__value = buf.value
def create_raw_buffer(): buf = GLuint() glGenBuffers(1, byref(buf)) glBindBuffer(GL_ARRAY_BUFFER, buf) return buf.value
def generate(self): for buffer in ["vertex", "color", "normal", "texture_coords"]: self.buffers[buffer] = gl.GLuint(0) gl.glGenBuffers(1, self.buffers[buffer]) gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self.buffers[buffer]) gl.glBufferData(gl.GL_ARRAY_BUFFER, self.buffer_size, None, gl.GL_DYNAMIC_DRAW)