def draw_textures(self, BoundingBox=None, glFunc=None): self.setup_composite_rendering() glFunc = gl.GL_FUNC_ADD if not self.FixedImageArray is None: FixedColor = None if (glFunc == gl.GL_FUNC_ADD): FixedColor = (1.0, 0.0, 1.0, 1) self.DrawFixedImage(self.FixedImageArray, FixedColor, BoundingBox=BoundingBox, z=0.25) if not self.WarpedImageArray is None: WarpedColor = None if (glFunc == gl.GL_FUNC_ADD): gl.glBlendEquation(glFunc) WarpedColor = (0, 1.0, 0, 1) self.DrawWarpedImage(self.WarpedImageArray, tex_color=WarpedColor, BoundingBox=BoundingBox, z=0.75, glFunc=glFunc) self.clear_composite_rendering()
def on_draw(self): """Redraw the current image.""" # the pyglet.window docs specify: # > The window will already have the GL context, so there is no need to # > call `.switch_to`. The window’s `.flip` method will be called after # > this event, so your event handler should not. # self.switch_to() # gl.glClearColor(0, 0, 0, 0) self.clear() if hasattr(self, 'texture'): # do not interpolate when resizing textures gl.glTexParameteri(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_NEAREST) # textures with alpha channels require gl blending capability gl.glEnable(gl.GL_BLEND) # Additive blending `R = S * F_s + D * F_d` for `c4f` f-RGBA gl.glBlendEquation(gl.GL_FUNC_ADD) # Factors `F_s = S_a` and `F_d = 1 - S_a` give transparency fx, # >>> gl.glBlendFunc(gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA) # but we set `F_s = 1.` and `F_d = 0.` for complete overwrite. # see https://learnopengl.com/Advanced-OpenGL/Blending # and https://www.khronos.org/opengl/wiki/Blending # and https://stackoverflow.com/a/18497511 (for opacity eqn) gl.glBlendFunc(gl.GL_ONE, gl.GL_ZERO) # draw the image data into the window's buffer as a texture # blit transforms the texture data only virtually: the texture's # `.width` and `.height` dims still retain original array's shape. self.texture.blit(0, 0, width=self.width, height=self.height)
def _draw_veils(self): triangles = [] colors = [] self._veil_lines = [] for veil in self.state.current_page.veils: if (not veil['covered'] and (not self.state.is_master or not self.show_veils)): continue minx, miny = self.map_to_screen(veil['minx'], veil['miny']) maxx, maxy = self.map_to_screen(veil['maxx'], veil['maxy']) if (minx >= self.pane.x1 or maxx <= self.pane.x0 or miny >= self.pane.y1 or maxy <= self.pane.y0): continue clamp_x0 = max(self.pane.x0, minx) clamp_y0 = max(self.pane.y0, miny) clamp_x1 = min(self.pane.x1, maxx) clamp_y1 = min(self.pane.y1, maxy) triangles.extend([ clamp_x0, clamp_y0, clamp_x1, clamp_y0, clamp_x1, clamp_y1, clamp_x0, clamp_y1, clamp_x0, clamp_y0, clamp_x1, clamp_y1 ]) if self.state.is_master: if veil['covered']: if self.show_veils: colors.extend([128] * 18) else: colors.extend([64] * 18) else: colors.extend([64] * 18) if self.show_veils: for x0, y0, x1, y1 in ( (clamp_x0, clamp_y0, clamp_x1, clamp_y0), (clamp_x1, clamp_y0, clamp_x1, clamp_y1), (clamp_x1, clamp_y1, clamp_x0, clamp_y1), (clamp_x0, clamp_y1, clamp_x0, clamp_y0) ): if not (x0 <= self.pane.x0 and x1 <= self.pane.x0 or x0 >= self.pane.x1 and x1 >= self.pane.x1 or y0 <= self.pane.y0 and y1 <= self.pane.y0 or y1 >= self.pane.y1 and y1 >= self.pane.y1): self._veil_lines.extend([x0, y0, x1, y1]) else: colors.extend([255] * 18) gl.glEnable(gl.GL_BLEND) gl.glBlendFunc(gl.GL_ONE, gl.GL_ONE) gl.glBlendEquation(gl.GL_FUNC_REVERSE_SUBTRACT) pyglet.graphics.draw(len(triangles) // 2, gl.GL_TRIANGLES, ('v2f', triangles), ('c3B', colors)) gl.glDisable(gl.GL_BLEND) gl.glBlendEquation(gl.GL_FUNC_ADD)
def DrawTextureWithBuffers(texture, vertarray, buffers, verts, color=None, glFunc=gl.GL_FUNC_ADD): if color is None: color = (1.0,1.0,1.0,1.0) gl.glBlendEquation(glFunc) gl.glBindTexture(gl.GL_TEXTURE_2D, texture) pyglet.gl.glColor4f(color[0], color[1], color[2], color[3]) # pyglet.graphics.draw_indexed(len(vertarray) / 3, # gl.GL_TRIANGLES, # verts.tolist(), # ('v3f', vertarray), # ('t2f', texarray)) draw_indexed_from_buffer(len(vertarray) / 3, gl.GL_TRIANGLES, verts.tolist(), buffers)
def draw_textures(self, BoundingBox=None, glFunc=None): self.setup_composite_rendering() glFunc = gl.GL_FUNC_ADD if not self.FixedImageArray is None: FixedColor = None if(glFunc == gl.GL_FUNC_ADD): FixedColor = (1.0, 0.0, 1.0, 1) self.DrawFixedImage(self.FixedImageArray, FixedColor, BoundingBox=BoundingBox, z=0.25) if not self.WarpedImageArray is None: WarpedColor = None if(glFunc == gl.GL_FUNC_ADD): gl.glBlendEquation(glFunc) WarpedColor = (0, 1.0, 0, 1) self.DrawWarpedImage(self.WarpedImageArray, tex_color=WarpedColor, BoundingBox=BoundingBox, z=0.75, glFunc=glFunc) self.clear_composite_rendering()
def DrawTextureWithBuffers(texture, vertarray, buffers, verts, color=None, glFunc=gl.GL_FUNC_ADD): if color is None: color = (1.0, 1.0, 1.0, 1.0) gl.glBlendEquation(glFunc) gl.glBindTexture(gl.GL_TEXTURE_2D, texture) pyglet.gl.glColor4f(color[0], color[1], color[2], color[3]) # pyglet.graphics.draw_indexed(len(vertarray) / 3, # gl.GL_TRIANGLES, # verts.tolist(), # ('v3f', vertarray), # ('t2f', texarray)) draw_indexed_from_buffer( len(vertarray) / 3, gl.GL_TRIANGLES, verts.tolist(), buffers)
def ClearDrawTextureState(): '''Reset the GL device from drawing textures''' gl.glBlendEquation(gl.GL_FUNC_ADD) pyglet.gl.glColor4f(1.0, 1.0, 1.0, 1.0) gl.glDisable(gl.GL_BLEND)
def main(level_file): clock = events.dispatcher('Clock') keyboard = events.dispatcher('Keyboard') pygame.init() pygame.display.gl_set_attribute(pygame.GL_ALPHA_SIZE, 8) pygame.display.set_mode((1000, 600), pygame.OPENGL | pygame.DOUBLEBUF | pygame.RESIZABLE) handle_resize(1000, 600) screen_center = (500, 300) camera_offset = 230 gl.glEnable(gl.GL_TEXTURE_2D) gl.glEnable(gl.GL_BLEND) gl.glBlendEquation(gl.GL_FUNC_ADD) gl.glBlendFunc(gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA) gl.glClearColor(0, 0, 0, 1) tick_event = pygame.event.Event(constants.TICK) datadir = find_datadir() loader = pyglet.resource.Loader(datadir) player1 = viking(datadir, clock, keyboard, pygame.K_a, pygame.K_d, pygame.K_w, pygame.K_j) player2 = viking(datadir, clock, keyboard, pygame.K_LEFT, pygame.K_RIGHT, pygame.K_UP, pygame.K_RETURN) player2.location[0] = 900 entities = [player1, player2] scream = pygame.mixer.Sound(os.path.join(datadir, 'wilhelm.wav')) background = load_sprite(datadir, 'background') backgroundbuf = GLBuffer(4 * 4, numpy.float32, gl.GL_STATIC_DRAW) backgroundbuf[:] = background.xyuv if level_file is None: walls = [components.hitbox((-5, -5), (10, 610)), components.hitbox((995, -5), (10, 610)), components.hitbox((-5, 595), (1010, 5)), ] else: walls = level.load(level_file) for w in walls: numpy.round(w.point, out=w.point) numpy.round(w.size, out=w.size) walls_tlbr = numpy.empty((2, len(walls), 2)) walls_tlbr[0] = [w.point for w in walls] walls_tlbr[1] = [w.point + w.size for w in walls] # vertex positions for walls quads = numpy.empty((len(walls), 4, 2), dtype=numpy.float32) quads[:, 0, :] = [w.point for w in walls] quads[:, 2, :] = [w.size for w in walls] quads[:, 2, :] += quads[:, 0, :] quads[:, 1, 0] = quads[:, 0, 0] quads[:, 1, 1] = quads[:, 2, 1] quads[:, 3, 0] = quads[:, 2, 0] quads[:, 3, 1] = quads[:, 0, 1] wallbuf = GLBuffer(quads.size, numpy.float32, gl.GL_STATIC_DRAW) wallbuf[:] = quads del quads # contains vertex and texture positions for sprites entitybuf = GLBuffer(dtype=numpy.float32) # walls program wallprog = shaders.wall() spriteprog = shaders.sprite() dragonprog = shaders.psycho() dragonpalette = load_texture(os.path.join(datadir, 'wallpalette.png'), dimensions=1) dragonsprite_scales = load_sprite(datadir, 'dragon_scales') dragonsprite_contours = load_sprite(datadir, 'dragon_contours') dragonbuf = GLBuffer(4 * 4, numpy.float32, gl.GL_STATIC_DRAW) dragonbuf[:] = dragonsprite_scales.xyuv + (-100, 145, 0, 0) contourbuf = GLBuffer(4 * 4, numpy.float32, gl.GL_STATIC_DRAW) contourbuf[:] = dragonsprite_contours.xyuv + (-100, 145, 0, 0) debug_draw = False pause = False do_frame = False ticks_done = 0 while True: start = time.clock() key_events = [] resize_event = None for event in pygame.event.get(): if event.type == pygame.QUIT: return 0 elif event.type == pygame.KEYDOWN or event.type == pygame.KEYUP: key_events.append(event) elif event.type == pygame.VIDEORESIZE: resize_event = event if event.type == pygame.KEYDOWN: if event.key == pygame.K_ESCAPE: return 0 if event.key == pygame.K_F2: debug_draw = not debug_draw elif event.key == pygame.K_F3: entities.append(sheep(datadir, clock)) elif event.key == pygame.K_F4: entities.append(drake(datadir, clock)) elif event.key == pygame.K_F5: entities.append(floaty_sheep(datadir, clock)) elif event.key == pygame.K_p: pause = not pause elif event.key == pygame.K_PERIOD and pause: do_frame = True if resize_event: handle_resize(resize_event.w, resize_event.h) screen_center = (resize_event.w // 2, resize_event.h // 2) background.xyuv[:, :2] = [[0, 0], [0, resize_event.h], [resize_event.w, resize_event.h], [resize_event.w, 0]] backgroundbuf[:] = background.xyuv if (not pause) or do_frame: for event in key_events: keyboard.dispatch(event) location = components.entity.location delta = numpy.array(location) motion_a = components.entity.motion_a motion_v = components.entity.motion_v active_tl = components.entity.active_tl active_br = components.entity.active_br passive_tl = components.entity.passive_tl passive_br = components.entity.passive_br instances = components.entity._all[:components.entity._nentities] do_translate = components.entity.translate_all GROUNDED = intern('grounded') motion_a[:] = (0, constants.G) clock.dispatch(tick_event) for thing in entities: thing.tags.discard(GROUNDED) motion_v[:] += motion_a collisions.resolve_passive_active_collisions(instances, active_tl, active_br, passive_tl, passive_br) attempts = 0 adjust_significant = True rppc = collisions.resolve_passive_passive_collisions rwc = collisions.resolve_wall_collisions grounded_mask = numpy.zeros((len(instances),), dtype=bool) stop = numpy.empty((len(instances),2), dtype=bool) adjust, sides = rwc(motion_v, passive_tl, passive_br, walls_tlbr[0], walls_tlbr[1]) numpy.logical_or.reduce(sides.reshape(-1, 2, 2), out=stop, axis=2) motion_v[stop] = 0 do_translate(motion_v[:]) while attempts < 20 and adjust_significant: adjust, sides, done_impulse = rppc(motion_v, passive_tl, passive_br) grounded_mask |= sides[:,3] adjust *= 0.5 do_translate(adjust) adjust_significant = not numpy.allclose(adjust, 0, atol=0.125) adjust_significant |= done_impulse > 0.125 del adjust, sides adjust, sides = rwc(motion_v, passive_tl, passive_br, walls_tlbr[0], walls_tlbr[1]) adjust_significant |= not numpy.allclose(adjust, 0, atol=0.5) do_translate(adjust) numpy.logical_or.reduce(sides.reshape(-1, 2, 2), out=stop, axis=2) motion_v[stop] = 0 grounded_mask |= sides[:,3] attempts += 1 for thing in numpy.compress(grounded_mask, instances): thing.tags.add(GROUNDED) do_frame = False ticks_done += 1 dead = [] gl.glLoadIdentity() gl.glEnableVertexAttribArray(0) gl.glUseProgram(spriteprog.id) gl.glBindTexture(gl.GL_TEXTURE_2D, background.texid) spriteprog['texture'] = 0 with backgroundbuf.bound: gl.glVertexAttribPointer(0, 4, gl.GL_FLOAT, gl.GL_FALSE, 0, 0) gl.glDrawArrays(gl.GL_TRIANGLE_FAN, 0, 4) # Now move camera camera_location = (screen_center - numpy.round(entities[0].location)) + (0, camera_offset) gl.glTranslated(camera_location[0], camera_location[1], 0.0) for thing in entities: if thing.hitpoints <= 0 or thing.location[1] > 10000: dead.append(thing) continue for thing in dead: scream.play() if thing.name == 'Player': thing.hitpoints = 100 thing.location[:] = (500, -10) thing.motion_v[:] = 0 if thing.physics is not None: thing.physics.last_position[:] = thing.location else: entities.remove(thing) thing.dispose() xyuv = numpy.empty((4, 4), dtype=numpy.float32) texid = [0] * len(entities) with entitybuf.bound: for n, thing in enumerate(entities): xyuv[:] = thing.graphics.sprite.xyuv xy = xyuv[:, 0:2] xy[:] += thing.graphics.anchor xy[:] += thing.location numpy.round(xy, out=xy) offset = n * 16 entitybuf[offset:] = xyuv texid[n] = thing.graphics.sprite.texid #print('Loaded data for entity', n, xyuv, 'texid', texid[n]) gl.glVertexAttribPointer(0, 4, gl.GL_FLOAT, gl.GL_FALSE, 0, 0) for n, t in enumerate(texid): gl.glBindTexture(gl.GL_TEXTURE_2D, t) gl.glDrawArrays(gl.GL_TRIANGLE_FAN, n * 4, 4) # draw walls gl.glUseProgram(wallprog.id) wallprog['color'] = (162.0/255.0, 153.0/255.0, 118.0/255.0, 1.0) with wallbuf.bound: gl.glVertexAttribPointer(0, 2, gl.GL_FLOAT, gl.GL_FALSE, 0, 0) gl.glDrawArrays(gl.GL_QUADS, 0, len(walls) * 8) # draw some shaders gl.glUseProgram(dragonprog.id) gl.glBindTexture(gl.GL_TEXTURE_2D, dragonsprite_scales.texid) gl.glActiveTexture(gl.GL_TEXTURE0 + 1) gl.glBindTexture(gl.GL_TEXTURE_1D, dragonpalette) gl.glActiveTexture(gl.GL_TEXTURE0) dragonprog['texture'] = 0 dragonprog['palette'] = 1 dragonprog['perturb'] = (ticks_done % 1024) / 128 dragonprog['shift'] = ticks_done / 600 with dragonbuf.bound: gl.glVertexAttribPointer(0, 4, gl.GL_FLOAT, gl.GL_FALSE, 0, 0) gl.glDrawArrays(gl.GL_TRIANGLE_FAN, 0, 4) # now draw the rest of the f****n' dragon gl.glUseProgram(spriteprog.id) gl.glBindTexture(gl.GL_TEXTURE_2D, dragonsprite_contours.texid) spriteprog['texture'] = 0 with contourbuf.bound: gl.glVertexAttribPointer(0, 4, gl.GL_FLOAT, gl.GL_FALSE, 0, 0) gl.glDrawArrays(gl.GL_TRIANGLE_FAN, 0, 4) if debug_draw: gl.glUseProgram(wallprog.id) wallprog['color'] = (0.89, 0.89, 0.89, 1.0) quads = numpy.zeros((len(entities), 4, 2), dtype=numpy.float32) quads[:, 0, :] = components.entity.passive_tl quads[:, 2, :] = components.entity.passive_br quads[:, 1, 0] = quads[:, 0, 0] quads[:, 1, 1] = quads[:, 2, 1] quads[:, 3, 0] = quads[:, 2, 0] quads[:, 3, 1] = quads[:, 0, 1] gl.glVertexAttribPointer(0, 2, gl.GL_FLOAT, gl.GL_FALSE, 0, quads.ctypes.data) gl.glDrawArrays(gl.GL_QUADS, 0, quads.size // 2) gl.glColor3f(1, 1, 1) gl.glEnable(gl.GL_TEXTURE_2D) #screen.fill((120, 50, 50), pygame.Rect(0, 10, player1.hitpoints * 2, 10)) #screen.fill((120, 50, 50), pygame.Rect(1000 - player2.hitpoints * 2, 10, player2.hitpoints * 2, 10)) pygame.display.flip() delta = time.clock() - start if delta < constants.FRAME: time.sleep(constants.FRAME - delta)
def render(self, draw_data): # perf: local for faster access io = self.io display_width, display_height = io.display_size fb_width = int(display_width * io.display_fb_scale[0]) fb_height = int(display_height * io.display_fb_scale[1]) if fb_width == 0 or fb_height == 0: return draw_data.scale_clip_rects(*io.display_fb_scale) # backup GL state # todo: provide cleaner version of this backup-restore code last_program = gl.GLint() gl.glGetIntegerv(gl.GL_CURRENT_PROGRAM, byref(last_program)) last_texture = gl.GLint() gl.glGetIntegerv(gl.GL_TEXTURE_BINDING_2D, byref(last_texture)) last_active_texture = gl.GLint() gl.glGetIntegerv(gl.GL_ACTIVE_TEXTURE, byref(last_active_texture)) last_array_buffer = gl.GLint() gl.glGetIntegerv(gl.GL_ARRAY_BUFFER_BINDING, byref(last_array_buffer)) last_element_array_buffer = gl.GLint() gl.glGetIntegerv(gl.GL_ELEMENT_ARRAY_BUFFER_BINDING, byref(last_element_array_buffer)) last_vertex_array = gl.GLint() gl.glGetIntegerv(gl.GL_VERTEX_ARRAY_BINDING, byref(last_vertex_array)) last_blend_src = gl.GLint() gl.glGetIntegerv(gl.GL_BLEND_SRC, byref(last_blend_src)) last_blend_dst = gl.GLint() gl.glGetIntegerv(gl.GL_BLEND_DST, byref(last_blend_dst)) last_blend_equation_rgb = gl.GLint() gl.glGetIntegerv(gl.GL_BLEND_EQUATION_RGB, byref(last_blend_equation_rgb)) last_blend_equation_alpha = gl.GLint() gl.glGetIntegerv(gl.GL_BLEND_EQUATION_ALPHA, byref(last_blend_equation_alpha)) last_viewport = (gl.GLint*4)() gl.glGetIntegerv(gl.GL_VIEWPORT, last_viewport) last_scissor_box = (gl.GLint*4)() gl.glGetIntegerv(gl.GL_SCISSOR_BOX, last_scissor_box) last_enable_blend = gl.GLint() gl.glIsEnabled(gl.GL_BLEND, byref(last_enable_blend)) last_enable_cull_face = gl.GLint() gl.glIsEnabled(gl.GL_CULL_FACE, byref(last_enable_cull_face)) last_enable_depth_test = gl.GLint() gl.glIsEnabled(gl.GL_DEPTH_TEST, byref(last_enable_depth_test)) last_enable_scissor_test = gl.GLint() gl.glIsEnabled(gl.GL_SCISSOR_TEST, byref(last_enable_scissor_test)) gl.glEnable(gl.GL_BLEND) gl.glBlendEquation(gl.GL_FUNC_ADD) gl.glBlendFunc(gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA) gl.glDisable(gl.GL_CULL_FACE) gl.glDisable(gl.GL_DEPTH_TEST) gl.glEnable(gl.GL_SCISSOR_TEST) gl.glActiveTexture(gl.GL_TEXTURE0) gl.glViewport(0, 0, int(fb_width), int(fb_height)) ortho_projection = [ 2.0/display_width, 0.0, 0.0, 0.0, 0.0, 2.0/-display_height, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, -1.0, 1.0, 0.0, 1.0 ] gl.glUseProgram(self._shader_handle) gl.glUniform1i(self._attrib_location_tex, 0) gl.glUniformMatrix4fv(self._attrib_proj_mtx, 1, gl.GL_FALSE, (gl.GLfloat * 16)(*ortho_projection)) gl.glBindVertexArray(self._vao_handle) for commands in draw_data.commands_lists: idx_buffer_offset = 0 gl.glBindBuffer(gl.GL_ARRAY_BUFFER, self._vbo_handle) # todo: check this (sizes) gl.glBufferData(gl.GL_ARRAY_BUFFER, commands.vtx_buffer_size * imgui.VERTEX_SIZE, c_void_p(commands.vtx_buffer_data), gl.GL_STREAM_DRAW) gl.glBindBuffer(gl.GL_ELEMENT_ARRAY_BUFFER, self._elements_handle) # todo: check this (sizes) gl.glBufferData(gl.GL_ELEMENT_ARRAY_BUFFER, commands.idx_buffer_size * imgui.INDEX_SIZE, c_void_p(commands.idx_buffer_data), gl.GL_STREAM_DRAW) # todo: allow to iterate over _CmdList for command in commands.commands: gl.glBindTexture(gl.GL_TEXTURE_2D, command.texture_id) # todo: use named tuple x, y, z, w = command.clip_rect gl.glScissor(int(x), int(fb_height - w), int(z - x), int(w - y)) if imgui.INDEX_SIZE == 2: gltype = gl.GL_UNSIGNED_SHORT else: gltype = gl.GL_UNSIGNED_INT gl.glDrawElements(gl.GL_TRIANGLES, command.elem_count, gltype, c_void_p(idx_buffer_offset)) idx_buffer_offset += command.elem_count * imgui.INDEX_SIZE # restore modified GL state gl.glUseProgram(cast((c_int*1)(last_program), POINTER(c_uint)).contents) gl.glActiveTexture(cast((c_int*1)(last_active_texture), POINTER(c_uint)).contents) gl.glBindTexture(gl.GL_TEXTURE_2D, cast((c_int*1)(last_texture), POINTER(c_uint)).contents) gl.glBindVertexArray(cast((c_int*1)(last_vertex_array), POINTER(c_uint)).contents) gl.glBindBuffer(gl.GL_ARRAY_BUFFER, cast((c_int*1)(last_array_buffer), POINTER(c_uint)).contents) gl.glBindBuffer(gl.GL_ELEMENT_ARRAY_BUFFER, cast((c_int*1)(last_element_array_buffer), POINTER(c_uint)).contents) gl.glBlendEquationSeparate(cast((c_int*1)(last_blend_equation_rgb), POINTER(c_uint)).contents, cast((c_int*1)(last_blend_equation_alpha), POINTER(c_uint)).contents) gl.glBlendFunc(cast((c_int*1)(last_blend_src), POINTER(c_uint)).contents, cast((c_int*1)(last_blend_dst), POINTER(c_uint)).contents) if last_enable_blend: gl.glEnable(gl.GL_BLEND) else: gl.glDisable(gl.GL_BLEND) if last_enable_cull_face: gl.glEnable(gl.GL_CULL_FACE) else: gl.glDisable(gl.GL_CULL_FACE) if last_enable_depth_test: gl.glEnable(gl.GL_DEPTH_TEST) else: gl.glDisable(gl.GL_DEPTH_TEST) if last_enable_scissor_test: gl.glEnable(gl.GL_SCISSOR_TEST) else: gl.glDisable(gl.GL_SCISSOR_TEST) gl.glViewport(last_viewport[0], last_viewport[1], last_viewport[2], last_viewport[3]) gl.glScissor(last_scissor_box[0], last_scissor_box[1], last_scissor_box[2], last_scissor_box[3])