def dispverts_of(self, face): # add format argument (lightmap uv, 2 uvs, etc) """vertex format [Position, Normal, TexCoord, LightCoord, Colour] normal is inherited from face returns rows, not tris""" verts = self.verts_of(face) if face.disp_info == -1: raise RuntimeError('face is not a displacement!') if len(verts) != 4: raise RuntimeError( 'face does not have 4 corners (probably t-junctions)') disp_info = self.DISP_INFO[face.disp_info] start = list(disp_info.start_position) start = [round(x, 1) for x in start] # approximate match round_verts = [] for vert in [v[0] for v in verts]: round_verts.append([round(x, 1) for x in vert]) if start in round_verts: # "rotate" index = round_verts.index(start) verts = verts[index:] + verts[:index] A, B, C, D = [vector.vec3(*v[0]) for v in verts] Auv, Buv, Cuv, Duv = [vector.vec2(*v[2]) for v in verts] Auv2, Buv2, Cuv2, Duv2 = [vector.vec2(*v[3]) for v in verts] # scale is wrong AD = D - A ADuv = Duv - Auv ADuv2 = Duv2 - Auv2 BC = C - B BCuv = Cuv - Buv BCuv2 = Cuv2 - Buv2 power2 = 2**disp_info.power full_power = (power2 + 1)**2 start = disp_info.disp_vert_start stop = disp_info.disp_vert_start + full_power new_verts, uvs, uv2s = [], [], [] for index, disp_vert in enumerate(self.DISP_VERTS[start:stop]): t1 = index % (power2 + 1) / power2 t2 = index // (power2 + 1) / power2 bary_vert = vector.lerp(A + (AD * t1), B + (BC * t1), t2) disp_vert = [x * disp_vert.distance for x in disp_vert.vector] new_verts.append([a + b for a, b in zip(bary_vert, disp_vert)]) uvs.append(vector.lerp(Auv + (ADuv * t1), Buv + (BCuv * t1), t2)) uv2s.append( vector.lerp(Auv2 + (ADuv2 * t1), Buv2 + (BCuv2 * t1), t2)) normal = [verts[0][1]] * full_power colour = [verts[0][4]] * full_power verts = list(zip(new_verts, normal, uvs, uv2s, colour)) return verts
def __init__(self, game: 'Game', x: int, y: int): self.pos: vec2 = vec2(x, y) self.game = game self.batch = graphics.Batch() self.e_boxes = [] for pos in self.game.world.room_map.keys(): box = shapes.Rectangle(x + (pos.x * Map.size), y + ((Map.rows - pos.y) * Map.size), Map.size, Map.size, color=(50, 50, 50), batch=self.batch) self.e_boxes.append(box) self.e_player = shapes.Rectangle(x, y, Map.size, Map.size, color=(255, 255, 255), batch=self.batch)
def parse_world(game, filename='resources/map.txt') -> World: """Parse a world file.""" world = World(game) x, y = 0, 0 # the current world location we are reading at print('loading world...') with open(filename, 'r') as file: for c in file.read(): if c == '\n': x = 0 # reset x back to 0 y += 1 # increment y continue # try to find the room type in our mapping room_type = room_mapping.get(c, None) if room_type: print(f'\tsetting loc {x, y} to {room_type.__name__}') world.set_room_at(vec2(x, y), room_type(game)) x += 1 print('world loaded.') return world
def __init__(self): Logger.__init__(self, 20) # self.scr: 'CursesScreen' = scr # the current colorscheme to use self.colorscheme = Colors() # a string describing the current situation self.status = '' # the next key to read from the user self.input_key = "" # the current room the player is in self.room = None self.turns = None # load the world self.world = world.parse_world(self) # the current Player instance self.player: Player = Player(self) self.player.pos = vec2(2, 4) # the state of the game # 'input' -> game is waiting for player input # 'running' -> time is progressing self.game_state = 'input' self.menu = MainMenu(self) # the state of the action menu # tells the game what actions to display self.menu_state = 'main' # holds an item previously selected through the menu self.menu_selected_item = None # holds the command string that is being typed by the user self.menu_cmd_buffer = '' # if true, try to quit the game self.quit = False # update the current room self.set_current_room() print('loaded a new game')
def draw_dcel_hedge(self, e, **options): if options == {}: options = {'arrow':LAST, 'arrowshape':(7,6,2), 'fill': '#444444'} offset = .02 sx,sy = e.origin.x, e.origin.y ex,ey = e.twin.origin.x, e.twin.origin.y vx,vy = ex - sx, ey - sy v = vec2(vx, vy) v_ = v.orthogonal_l()*offset v = v - v.normalized()*.25 ex, ey = sx+v.x, sy+v.y return self.draw.edge( (sx+v_.x, sy+v_.y), (ex+v_.x, ey+v_.y) , **options)
def draw_dcel_hedge(self, e, **options): if options == {}: options = { 'arrow': LAST, 'arrowshape': (7, 6, 2), 'fill': '#444444' } offset = .02 sx, sy = e.origin.x, e.origin.y ex, ey = e.twin.origin.x, e.twin.origin.y vx, vy = ex - sx, ey - sy v = vec2(vx, vy) v_ = v.orthogonal_l() * offset v = v - v.normalized() * .25 ex, ey = sx + v.x, sy + v.y return self.draw.edge((sx + v_.x, sy + v_.y), (ex + v_.x, ey + v_.y), **options)
def verts_of(self, face): # why so many crazy faces? """vertex format [Position, Normal, TexCoord, LightCoord, Colour]""" verts, uvs, uv2s = [], [], [] first_edge = face.first_edge for surfedge in self.SURFEDGES[first_edge:first_edge + face.num_edges]: edge = self.EDGES[surfedge] if surfedge >= 0 else self.EDGES[ -surfedge][::-1] # ? verts.append(self.VERTICES[edge[0]]) verts.append(self.VERTICES[edge[1]]) verts = verts[::2] # why skip in this way? # github.com/VSES/SourceEngine2007/blob/master/src_main/engine/matsys_interface.cpp # SurfComputeTextureCoordinate & SurfComputeLightmapCoordinate tex_info = self.TEXINFO[face.tex_info] # index error? tex_data = self.TEXDATA[tex_info.tex_data] texture = tex_info.texture lightmap = tex_info.lightmap normal = lambda P: (P.x, P.y, P.z) # return the normal of plane (P) for vert in verts: uv = [ vector.dot(vert, normal(texture.s)) + texture.s.offset, vector.dot(vert, normal(texture.t)) + texture.t.offset ] uv[0] /= tex_data.view_width uv[1] /= tex_data.view_height uvs.append(vector.vec2(*uv)) uv2 = [ vector.dot(vert, normal(lightmap.s)) + lightmap.s.offset, vector.dot(vert, normal(lightmap.t)) + lightmap.t.offset ] uv2[0] -= face.lightmap_texture_mins_in_luxels.s uv2[1] -= face.lightmap_texture_mins_in_luxels.t try: uv2[0] /= face.lightmap_texture_size_in_luxels.s uv2[1] /= face.lightmap_texture_size_in_luxels.t except ZeroDivisionError: uv2 = [0, 0] uv2s.append(uv2) vert_count = len(verts) normal = [self.PLANES[face.plane_num].normal] * vert_count colour = [tex_data.reflectivity] * vert_count return list(zip(verts, normal, uvs, uv2s, colour))
def verts_of(self, face): # why so many crazy faces? """vertex format [Position, Normal, TexCoord, LightCoord, Colour]""" texinfo = self.TEXINFO[face['texinfo']] texdata = self.TEXDATA[texinfo['texdata']] texvecs = texinfo['textureVecs'] lightvecs = texinfo['lightmapVecs'] verts, uvs, uv2s = [], [], [] first_edge = face['firstedge'] for surfedge in self.SURFEDGES[first_edge:first_edge + face['numedges']]: edge = self.EDGES[surfedge] if surfedge >= 0 else self.EDGES[-surfedge][::-1] verts.append(self.VERTICES[edge[0]]) verts.append(self.VERTICES[edge[1]]) #verts[::2] is faster. why is this approach used? # verts = [tuple(v) for v in verts] # verts = {v: None for v in verts} # verts = [list(v) for v in verts] verts = verts[::2] # github.com/VSES/SourceEngine2007/blob/master/src_main/engine/matsys_interface.cpp # SurfComputeTextureCoordinate & SurfComputeLightmapCoordinate for vert in verts: uv = [vector.dot(vert, texvecs[0][:-1]) + texvecs[0][3], vector.dot(vert, texvecs[1][:-1]) + texvecs[1][3]] uv[0] /= texdata['view_width'] uv[1] /= texdata['view_height'] uvs.append(vector.vec2(*uv)) uv2 = [vector.dot(vert, lightvecs[0][:-1]) + lightvecs[0][3], vector.dot(vert, lightvecs[1][:-1]) + lightvecs[1][3]] uv2[0] -= face['LightmapTextureMinsinLuxels'][0] uv2[1] -= face['LightmapTextureMinsinLuxels'][1] try: uv2[0] /= face['LightmapTextureSizeinLuxels'][0] uv2[1] /= face['LightmapTextureSizeinLuxels'][1] except ZeroDivisionError: uv2 = [0, 0] uv2s.append(uv2) vert_count = len(verts) normal = [self.PLANES[face['planenum']]['normal']] * vert_count colour = [texdata['reflectivity']] * vert_count verts = list(zip(verts, normal, uvs, uv2s, colour)) return verts
def __init__(self, game): InventoryHolder.__init__(self, game) LivingEntity.__init__(self, game, name='You') # the position of the player self.pos = vec2(0, 0) self.victory = False self.game = game self.give_item(items.Gold(game, 15), items.Rock(game)) # slots self.item_slots = {} # strings # ------- self.str_possessive = "Your" self.str_name = "You"
from vector import vec2 from screen import CursesScreen from elements.map import Map from elements.text import Text from game import Game from entity import LivingEntity from pyglet import (window, app, text, clock, gl) import re import actions win = window.Window(1280, 720) game = Game() map_size = vec2(10, 10) # map_center = map_size // 2 map_center = vec2(0, 0) map_view = None @win.event def on_key_press(key, modifiers): if key == window.key.Q: win.close() keymap = { '_1': '1', '_2': '2', '_3': '3', '_4': '4',
def get_room(self, x, y) -> str: """Get a room by its coordinates.""" return self.world.get_room_at(vec2(x, y))
def main(width, height): SDL_Init(SDL_INIT_VIDEO) window = SDL_CreateWindow(b'SDL2 OpenGL', SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, SDL_WINDOW_OPENGL | SDL_WINDOW_BORDERLESS) glContext = SDL_GL_CreateContext(window) SDL_GL_SetSwapInterval(0) glClearColor(0.1, 0.1, 0.1, 0.0) gluPerspective(90, width / height, 0.1, 4096) glRotate(90, -1, 0, 0) glTranslate(0, 8, 0) glPolygonMode(GL_FRONT_AND_BACK, GL_LINE) glEnable(GL_DEPTH_TEST) glPointSize(8) mouse = vector.vec2(0, 0) spec_mouse = mouse keys = [] bsp = bsp_tool.bsp("../mapsrc/bsp_import_props.bsp") filtered_faces = list(filter(lambda x: x['lightofs'] != -1, bsp.FACES)) global planes planes = {} # planes = {plane: [*faces], ...} for face in filtered_faces: plane = bsp.PLANES[face['planenum']] verts = bsp.verts_of(face) face_bounds = aabb(*verts_to_box(verts)) plane_key = (plane['normal'], plane['dist']) if plane_key in planes.keys(): planes[plane_key].append(face_bounds) else: planes[plane_key] = [face_bounds] bsptris = list( itertools.chain(*[bsp.verts_of(face) for face in filtered_faces])) client0 = client('b!scuit') #TODO: draw client name at client position spectator_camera = camera.freecam((0, 0, 128), (0, 0, 0), speed=368) active_camera = 0 SDL_SetRelativeMouseMode(SDL_TRUE) SDL_SetWindowGrab(window, SDL_TRUE) SDL_CaptureMouse(SDL_TRUE) global physFrozen physFrozen = False global tickrate tickrate = 1 / 0.015 #66.67 for tf2 (~15ms per frame) tick_number = 0 dt = 1 / tickrate oldtime = time() event = SDL_Event() while True: while SDL_PollEvent(ctypes.byref(event)) != 0: if event.type == SDL_QUIT or event.key.keysym.sym == SDLK_ESCAPE and event.type == SDL_KEYDOWN: SDL_GL_DeleteContext(glContext) SDL_DestroyWindow(window) SDL_Quit() return False if event.type == SDL_KEYDOWN: keys.append(event.key.keysym.sym) if event.type == SDL_KEYUP: while event.key.keysym.sym in keys: keys.remove(event.key.keysym.sym) if event.type == SDL_MOUSEMOTION: mouse = vector.vec2(event.motion.xrel, event.motion.yrel) SDL_WarpMouseInWindow(window, width // 2, height // 2) if event.type == SDL_MOUSEBUTTONDOWN: if event.button.button == SDL_BUTTON_RIGHT: active_camera = 0 if active_camera == 1 else 1 if SDLK_r in keys: client0.spawn((0, 0, 2048)) if SDLK_BACKQUOTE in keys: physFrozen = False if SDLK_SPACE in keys: physFrozen = True dt = time() - oldtime if dt >= 1 / tickrate: if not physFrozen: print('TICK #{}'.format(tick_number)) tick_number += 1 client0.report() if active_camera == 0: if not physFrozen: client0.update(mouse, keys, 1 / tickrate) else: spec_mouse += mouse spectator_camera.update(spec_mouse, keys, 1 / tickrate) if not physFrozen: client0.update( vector.vec2(0, 0), [], 1 / tickrate) #inputless update to maintain physics mouse = vector.vec2(0, 0) dt -= 1 / tickrate oldtime = time() #DISPLAY glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) glLoadIdentity() gluPerspective(90, width / height, 0.1, 4096) if active_camera == 0: if not physFrozen: client0.set_view_lerp(dt) else: client0.set_view() else: spectator_camera.set() glPolygonMode(GL_BACK, GL_FILL) for face in filtered_faces: normal = bsp.PLANES[face['planenum']]['normal'] normal = [(x + 1) / 2 for x in normal] colour = normal[0] / 3 + 1 / 3 * normal[1] / 3 + 2 / 3 * normal[ 2] / 3 glColor(*[[colour] * 3]) glBegin(GL_POLYGON) for vertex in bsp.verts_of(face): glVertex(*vertex) glEnd() glPolygonMode(GL_BACK, GL_LINE) # normal indicator ## glBegin(GL_LINES) ## for plane in planes: ## center = sum(plane.aabb, vector.vec3()) / 2 ## glColor(0, 1, 0) ## glVertex(*center) ## glColor(.1, .1, .1) ## glVertex(*(center + plane.normal * 64)) ## glEnd() if not physFrozen: client0.draw_lerp(dt) else: client0.draw() SDL_GL_SwapWindow(window)
if room_type: print(f'\tsetting loc {x, y} to {room_type.__name__}') world.set_room_at(vec2(x, y), room_type(game)) x += 1 print('world loaded.') return world # old parser # ------------------------------------------------------------------------------ _world = {} starting_position = vec2(2, 4) def load_tiles(): """Parses a file that describes the world space into the _world object""" with open('resources/map.txt', 'r') as f: rows = f.readlines() x_max = len(rows[0].split('\t')) for y in range(len(rows)): cols = rows[y].split('\t') for x in range(x_max): tile_name = cols[x].replace('\n', '') if tile_name == 'StartingRoom': global starting_position starting_position = (x, y) _world[(x, y)] = None if tile_name == '' else getattr(
def main(width, height): SDL_Init(SDL_INIT_VIDEO) window = SDL_CreateWindow(b'SDL2 OpenGL', SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, SDL_WINDOW_OPENGL | SDL_WINDOW_BORDERLESS) glContext = SDL_GL_CreateContext(window) SDL_GL_SetSwapInterval(0) glClearColor(0.1, 0.1, 0.1, 0.0) gluPerspective(90, width / height, 0.1, 4096) glPolygonMode(GL_BACK, GL_LINE) mousepos = vector.vec2(0, 0) keys = set() VIEW_CAMERA = camera.freecam(None, None, 32) pixel_formats = {SDL_PIXELFORMAT_BGR24: GL_BGR} # 24bpp .bmp # {name: {width, height, pixel_format, ...}} loaded_textures = dict() # load each texture once vmt_map = dict() # {vmt_filename: vtf_filename} bsp_skyname = 'sky_hydro_01' # worldspawn (first entity in LUMP_ENTITIES) tails = ['dn', 'up', 'rt', 'lf', 'ft', 'bk'] # Z-up cubemap_faces = [ 'POSITIVE_Y', 'NEGATIVE_Y', 'POSITIVE_Z', 'NEGATIVE_Z', 'POSITIVE_X', 'NEGATIVE_X' ] {'dn': 'POSITIVE_Y', 'up': 'NEGATIVE_Y'} # reorient textures sky_scale = 512 sky_textures = dict() for t in tails: vmt_filename = f'materials/skybox/{bsp_skyname}{t}.vmt' vmt = vmf_tool.namespace_from(open(vmt_filename)) ## filename = f"materials/{vmt.sky['$basetexture']}.bmp" filename = f"materials/skybox/{bsp_skyname}{t}.bmp" vmt_map[vmt_filename] = filename if filename not in loaded_textures: bmp = texture.load_BMP(filename) x_scale = sky_scale / bmp.width y_scale = sky_scale / bmp.height scaled_texture = bmp.scale(x_scale, y_scale) loaded_textures[filename] = scaled_texture else: print(f'{t} already loaded: {filename}') sky_textures[vmt_filename] = filename # use already loaded textures texture_SKYBOX = glGenTextures(1) glActiveTexture(GL_TEXTURE0) glBindTexture(GL_TEXTURE_CUBE_MAP, texture_SKYBOX) for tex, face in zip(sky_textures, cubemap_faces): tex = loaded_textures[vmt_map[tex]] ## tex = loaded_textures['materials/skybox/sky_upwardside.bmp'] target = eval(f'GL_TEXTURE_CUBE_MAP_{face}') glTexImage2D(target, 0, GL_RGBA, tex.width, tex.height, 0, tex.pixel_format, GL_UNSIGNED_BYTE, tex.pixels) glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR) glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR) glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE) glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE) glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE) glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS) # OpenGL 3.5+ vertices = [] for i in range(8): x = 1 if i // 4 % 2 == 0 else -1 y = 1 if i // 2 % 2 == 0 else -1 z = 1 if i % 2 == 0 else -1 vertices.append((x, y, z)) indices = [ 6, 4, 0, 2, 3, 1, 5, 7, 7, 5, 4, 6, 2, 0, 1, 3, 0, 4, 5, 1, 6, 2, 3, 7 ] sky_vert = compileShader(open('shaders/skybox_300_es.v', 'rb'), GL_VERTEX_SHADER) sky_frag = compileShader(open('shaders/skybox_300_es.f', 'rb'), GL_FRAGMENT_SHADER) sky_shader = compileProgram(sky_vert, sky_frag) glLinkProgram(sky_shader) glUseProgram(sky_shader) MVP_MATRIX = glGetFloatv(GL_MODELVIEW_MATRIX) MVP_LOCATION = glGetUniformLocation(sky_shader, 'mvpMatrix') glUniformMatrix4fv(MVP_LOCATION, 1, GL_FALSE, *MVP_MATRIX) SDL_SetRelativeMouseMode(SDL_TRUE) SDL_SetWindowGrab(window, SDL_TRUE) SDL_CaptureMouse(SDL_TRUE) oldtime = time() tick_ms = 0.015 dt = tick_ms event = SDL_Event() while True: while SDL_PollEvent(ctypes.byref(event)) != 0: if event.type == SDL_QUIT or event.key.keysym.sym == SDLK_ESCAPE and event.type == SDL_KEYDOWN: SDL_GL_DeleteContext(glContext) SDL_DestroyWindow(window) SDL_Quit() return False if event.type == SDL_KEYDOWN: keys.add(event.key.keysym.sym) if event.type == SDL_KEYUP: keys.remove(event.key.keysym.sym) if event.type == SDL_MOUSEMOTION: mousepos += vector.vec2(event.motion.xrel, event.motion.yrel) SDL_WarpMouseInWindow(window, width // 2, height // 2) if event.type == SDL_MOUSEBUTTONDOWN: if event.button.button == SDL_BUTTON_RIGHT: active = 0 if active == 1 else 1 if SDLK_r in keys: VIEW_CAMERA = camera.freecam(None, None, 256) if SDLK_BACKQUOTE in keys: print(f'{VIEW_CAMERA.position:.3f}') dt = time() - oldtime if dt >= tick_ms: VIEW_CAMERA.update(mousepos, keys, tick_ms) # parse inputs # do logic dt -= tick_ms oldtime = time() #DISPLAY glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) glLoadIdentity() gluPerspective(90, width / height, 0.1, 128) # rotate camera glDepthMask(GL_FALSE) glRotate(-90, 1, 0, 0) glRotate(VIEW_CAMERA.rotation.x, 1, 0, 0) glRotate(VIEW_CAMERA.rotation.z, 0, 0, 1) glDisable(GL_DEPTH_TEST) # draw skybox glUseProgram(sky_shader) # GLES attribs MVP_MATRIX = glGetFloatv(GL_MODELVIEW_MATRIX) glUniformMatrix4fv(MVP_LOCATION, 1, GL_FALSE, *MVP_MATRIX) glBegin(GL_QUADS) for i in indices: glVertex(*vertices[i]) glEnd() glUseProgram(0) glEnable(GL_DEPTH_TEST) # move camera glTranslate(-VIEW_CAMERA.position.x, -VIEW_CAMERA.position.y, -VIEW_CAMERA.position.z) glDepthMask(GL_TRUE) # not the skybox (so, the world i guess) glColor(1, .5, 0) glBegin(GL_QUADS) glTexCoord(0, 0) glVertex(1, 1) glTexCoord(1, 0) glVertex(-1, 1) glTexCoord(1, 1) glVertex(-1, -1) glTexCoord(0, 1) glVertex(1, -1) glEnd() # positive axes glBegin(GL_LINES) glColor(1, 0, 0) glVertex(0, 0, 0) glVertex(1, 0, 0) glColor(0, 1, 0) glVertex(0, 0, 0) glVertex(0, 1, 0) glColor(0, 0, 1) glVertex(0, 0, 0) glVertex(0, 0, 1) glEnd() SDL_GL_SwapWindow(window)
def main(width, height): SDL_Init(SDL_INIT_VIDEO) window = SDL_CreateWindow(b'SDL2 OpenGL', SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, SDL_WINDOW_OPENGL | SDL_WINDOW_BORDERLESS) glContext = SDL_GL_CreateContext(window) SDL_GL_SetSwapInterval(0) glClearColor(0.1, 0.1, 0.1, 0.0) gluPerspective(90, width / height, 0.1, 4096) glRotate(90, -1, 0, 0) glTranslate(0, 8, 0) glPolygonMode(GL_FRONT_AND_BACK, GL_LINE) glPointSize(8) mouse = vector.vec2(0, 0) keys = [] #import bsp_tool #bsp = bsp_tool.bsp("../f1.bsp") #tris to render bsp #import and setup bsp face shader global planes #planes = [] #for face in bsp.FACES: # plane = bsp.PLANES[face.planenum] # aabb = (-1024, -1024, -1024), (1024, 1024, 1024), # planes.append(plane['normal'], plane['distance'], *aabb) planes = [ plane_struct((0, 0, 1), 0, (-8, -8, -0.1), (8, 8, 0.1)), plane_struct((0, 0, 1), -16, (-32, -32, -15.9), (32, 32, -16.1)) ] client0 = client('b!scuit') #TODO: draw client name at client position spectator_camera = camera.fixed((-24, -24, 4), (0, -30, 45)) #CAMERA SWITCHING SYSTEM IS UGLY cameras = [client0.set_view, spectator_camera.set] active = 1 SDL_SetRelativeMouseMode(SDL_TRUE) SDL_SetWindowGrab(window, SDL_TRUE) SDL_CaptureMouse(SDL_TRUE) oldtime = time() tickrate = 125 dt = 1 / tickrate event = SDL_Event() while True: while SDL_PollEvent(ctypes.byref(event)) != 0: if event.type == SDL_QUIT or event.key.keysym.sym == SDLK_ESCAPE and event.type == SDL_KEYDOWN: SDL_GL_DeleteContext(glContext) SDL_DestroyWindow(window) SDL_Quit() return False if event.type == SDL_KEYDOWN: keys.append(event.key.keysym.sym) if event.type == SDL_KEYUP: while event.key.keysym.sym in keys: keys.remove(event.key.keysym.sym) if event.type == SDL_MOUSEMOTION: mouse = vector.vec2(event.motion.xrel, event.motion.yrel) SDL_WarpMouseInWindow(window, width // 2, height // 2) if event.type == SDL_MOUSEBUTTONDOWN: if event.button.button == SDL_BUTTON_RIGHT: active = 0 if active == 1 else 1 if SDLK_r in keys: client0.spawn() if SDLK_BACKQUOTE in keys: client0.report() dt = time() - oldtime if dt >= 1 / tickrate: client0.update(mouse, keys, 1 / tickrate) mouse = vector.vec2(0, 0) dt -= 1 / tickrate oldtime = time() #DISPLAY glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) glLoadIdentity() gluPerspective(90, width / height, 0.1, 128) cameras[active].__call__() #ew #floor glColor(1, 0.5, 0) glBegin(GL_QUADS) glVertex(-8, 8) glVertex(8, 8) glVertex(8, -8) glVertex(-8, -8) glEnd() glBegin(GL_TRIANGLE_FAN) glVertex(-32, 32, -16) glVertex(32, 32, -16) glVertex(32, -32, -16) glVertex(-32, -32, -16) glEnd() #client client0.draw() SDL_GL_SwapWindow(window)
def __init__(self, position, rotation, radius, offset=(0, 0)): self.position = vec3(position) if position != None else vec3() self.rotation = vec3(rotation) if rotation != None else vec3() self.radius = radius if radius != None else 0 self.offset = vec2(offset)
def main(width, height, bsp): SDL_Init(SDL_INIT_VIDEO) window = SDL_CreateWindow(bytes(bsp.filename, 'utf-8'), SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, SDL_WINDOW_OPENGL | SDL_WINDOW_BORDERLESS) #SDL_WINDOW_FULLSCREEN glContext = SDL_GL_CreateContext(window) glColor(0, 0, 0, 0) gluPerspective(90, width / height, 0.1, 4096 * 4) glPointSize(2) glPolygonMode(GL_BACK, GL_LINE) glEnable(GL_DEPTH_TEST) glColor(1, 1, 1) glFrontFace(GL_CW) FACE = iter(bsp.FACES) current_face = next(FACE) current_face_verts = bsp.verts_of(current_face) all_faces = [] all_faces_map = [] start = 0 for face in bsp.FACES: if face['dispinfo'] == -1: f_verts = bsp.verts_of(face) out = f_verts[:3] f_verts = f_verts[3:] for vert in f_verts: out += [out[0], out[-1], vert] f_verts = out f_verts_len = len(f_verts) all_faces_map.append((start, f_verts_len)) start += f_verts_len else: power = bsp.DISP_INFO[face['dispinfo']]['power'] f_verts = bsp_tool.disp_tris(bsp.dispverts_of(face), power) all_faces += f_verts ## all_faces = list(itertools.chain(*all_faces)) NODE = iter(filter(lambda x: x['children'][1] < 0, bsp.NODES)) NODE = sorted(bsp.NODES, key=lambda node: sum( [x[1] for x in node_faces(node, bsp, all_faces_map)])) current_node = NODE[0] current_node_index = 0 draw_calls = node_faces(current_node, bsp, all_faces_map) current_node_aabb = aabb(current_node['mins'], current_node['maxs']) cnff = current_node['firstface'] current_node_faces = all_faces_map[cnff:cnff + current_node['numfaces']] try: cn_start = current_node_faces[0][0] cn_count = sum([x[1] for x in current_node_faces]) except: cn_start = 0 cn_count = 0 all_nodes = list(map(lambda x: aabb(x['mins'], x['maxs']), bsp.NODES)) all_leaves = list(map(lambda x: aabb(x['mins'], x['maxs']), bsp.LEAVES)) print(bsp.filename.upper(), end=' ') print('{:,}KB BSP'.format(bsp.bytesize // 1024), '>>>', end=' ') print('{:,} TRIS'.format(len(all_faces) // 9), end=' & ') print('{:,}KB VRAM'.format((len(all_faces) * 4) // 1024)) print('{:,} NODES'.format(len(bsp.NODES))) # shader & vertex buffer would go here SDL_GL_SetSwapInterval(0) SDL_CaptureMouse(SDL_TRUE) SDL_WarpMouseInWindow(window, width // 2, height // 2) SDL_SetRelativeMouseMode(SDL_TRUE) SDL_SetWindowGrab(window, SDL_TRUE) cam_spawn = vector.vec3(0, 0, 0) init_speed = 128 VIEW_CAMERA = camera.freecam(cam_spawn, None, init_speed) mousepos = vector.vec2() keys = [] tickrate = 120 event = SDL_Event() oldtime = time() while True: while SDL_PollEvent(ctypes.byref(event)) != 0: if event.type == SDL_QUIT or event.key.keysym.sym == SDLK_ESCAPE and event.type == SDL_KEYDOWN: SDL_GL_DeleteContext(glContext) SDL_DestroyWindow(window) SDL_Quit() return False if event.type == SDL_KEYDOWN: if event.key.keysym.sym not in keys: keys.append(event.key.keysym.sym) if event.type == SDL_KEYUP: while event.key.keysym.sym in keys: keys.remove(event.key.keysym.sym) if event.type == SDL_MOUSEMOTION: mousepos += vector.vec2(event.motion.xrel, event.motion.yrel) SDL_WarpMouseInWindow(window, width // 2, height // 2) if event.type == SDL_MOUSEWHEEL: VIEW_CAMERA.speed += event.wheel.y * 32 if event.type == SDL_MOUSEBUTTONDOWN: if event.button.button not in keys: keys.append(event.button.button) if event.type == SDL_MOUSEBUTTONUP: while event.button.button in keys: keys.remove(event.button.button) dt = time() - oldtime while dt >= 1 / tickrate: VIEW_CAMERA.update(mousepos, keys, 1 / tickrate) if SDLK_BACKQUOTE in keys: #NODES print(current_node, draw_calls, sep='\n\n') cn_center = (current_node_aabb.mins + current_node_aabb.maxs) / 2 VIEW_CAMERA.position = cn_center while SDLK_BACKQUOTE in keys: keys.remove(SDLK_BACKQUOTE) if SDLK_r in keys: VIEW_CAMERA = camera.freecam(cam_spawn, None, init_speed) if SDLK_LSHIFT in keys: VIEW_CAMERA.speed += VIEW_CAMERA.speed * .125 if SDLK_LCTRL in keys: VIEW_CAMERA.speed -= VIEW_CAMERA.speed * .125 if SDLK_LEFT in keys or SDL_BUTTON_LEFT in keys: current_node_index -= 1 current_node = NODE[current_node_index] draw_calls = node_faces(current_node, bsp, all_faces_map) current_node_aabb = aabb(current_node['mins'], current_node['maxs']) VIEW_CAMERA.position = current_node_aabb.center cnff = current_node['firstface'] current_node_faces = all_faces_map[cnff:cnff + current_node['numfaces']] try: cn_start = current_node_faces[0][0] cn_count = sum([x[1] for x in current_node_faces]) except: cn_start = 0 cn_count = 0 while SDLK_LEFT in keys: keys.remove(SDLK_LEFT) while SDL_BUTTON_LEFT in keys: keys.remove(SDL_BUTTON_LEFT) if SDLK_RIGHT in keys or SDL_BUTTON_RIGHT in keys: current_node_index += 1 current_node = NODE[current_node_index] draw_calls = node_faces(current_node, bsp, all_faces_map) current_node_aabb = aabb(current_node['mins'], current_node['maxs']) VIEW_CAMERA.position = current_node_aabb.center cnff = current_node['firstface'] current_node_faces = all_faces_map[cnff:cnff + current_node['numfaces']] try: cn_start = current_node_faces[0][0] cn_count = sum([x[1] for x in current_node_faces]) except: cn_start = 0 cn_count = 0 while SDLK_RIGHT in keys: keys.remove(SDLK_RIGHT) while SDL_BUTTON_RIGHT in keys: keys.remove(SDL_BUTTON_RIGHT) dt -= 1 / tickrate oldtime = time() glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) glPushMatrix() VIEW_CAMERA.set() glPolygonMode(GL_FRONT, GL_LINE) ## glUseProgram(0) glColor(1, 0, 1) glBegin(GL_LINES) current_node_aabb.draw() glEnd() glColor(1, 1, 1) glDrawArrays(GL_TRIANGLES, cn_start, cn_count) ## glUseProgram(bsp_shader) glColor(1, .5, 0) glPolygonMode(GL_FRONT, GL_FILL) glPolygonMode(GL_BACK, GL_LINE) try: for draw_call in draw_calls: glDrawArrays(GL_TRIANGLES, draw_call[0], draw_call[1]) except: pass #CENTER POINT ## glUseProgram(0) ## glBegin(GL_LINES) ## glColor(1, 0, 0) ## glVertex(0, 0, 0) ## glVertex(128, 0, 0) ## glColor(0, 1, 0) ## glVertex(0, 0, 0) ## glVertex(0, 128, 0) ## glColor(0, 0, 1) ## glVertex(0, 0, 0) ## glVertex(0, 0, 128) ## glEnd() glPopMatrix() SDL_GL_SwapWindow(window)
def main(width, height): SDL_Init(SDL_INIT_VIDEO) window = SDL_CreateWindow(b'SDL2 OpenGL', SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, SDL_WINDOW_OPENGL | SDL_WINDOW_BORDERLESS) glContext = SDL_GL_CreateContext(window) SDL_GL_SetSwapInterval(0) glClearColor(0.1, 0.1, 0.1, 0.0) gluPerspective(90, width / height, 0.1, 4096) glPolygonMode(GL_FRONT_AND_BACK, GL_LINE) glPointSize(8) glEnable(GL_BLEND) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) mouse = vector.vec2(0, 0) keys = [] global planes planes = [ plane_struct((0, 0, 1), 0, (-8, -16, -0.1), (8, 16, 0.1)), plane_struct((0, 0, 1), -16, (-32, -32, -15.9), (32, 32, -16.1)), plane_struct((1, 0, 1), 0, (-16, -16, 0), (16, 16, 4)) ] # convert planes within aabbs to drawable geo # slice planes with other planes to create ngons client0 = client('b!scuit') # TODO: draw client name at client position spectator_camera = utils.camera.fixed((0, 0, 16), (90, 0, 0)) # CAMERA SWITCHING SYSTEM IS UGLY cameras = [client0.set_view, spectator_camera.set] active = 1 SDL_SetRelativeMouseMode(SDL_TRUE) SDL_SetWindowGrab(window, SDL_TRUE) SDL_CaptureMouse(SDL_TRUE) oldtime = time() tickrate = 125 dt = 1 / tickrate event = SDL_Event() while True: while SDL_PollEvent(ctypes.byref(event)) != 0: if event.type == SDL_QUIT or event.key.keysym.sym == SDLK_ESCAPE and event.type == SDL_KEYDOWN: SDL_GL_DeleteContext(glContext) SDL_DestroyWindow(window) SDL_Quit() return False if event.type == SDL_KEYDOWN: keys.append(event.key.keysym.sym) if event.type == SDL_KEYUP: while event.key.keysym.sym in keys: keys.remove(event.key.keysym.sym) if event.type == SDL_MOUSEMOTION: mouse = vector.vec2(event.motion.xrel, event.motion.yrel) SDL_WarpMouseInWindow(window, width // 2, height // 2) if event.type == SDL_MOUSEBUTTONDOWN: if event.button.button == SDL_BUTTON_RIGHT: active = 0 if active == 1 else 1 if SDLK_r in keys: client0.spawn() if SDLK_BACKQUOTE in keys: client0.report() dt = time() - oldtime if dt >= 1 / tickrate: client0.update(mouse, keys, 1 / tickrate) mouse = vector.vec2(0, 0) dt -= 1 / tickrate oldtime = time() # DISPLAY glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) glLoadIdentity() gluPerspective(90, width / height, 0.1, 128) cameras[active]() # ew # floor glPolygonMode(GL_FRONT_AND_BACK, GL_FILL) glColor(1, 0.5, 0, 0.25) glBegin(GL_QUADS) glVertex(-8, 16) glVertex(8, 16) glVertex(8, -16) glVertex(-8, -16) glEnd() glBegin(GL_TRIANGLE_FAN) glVertex(-32, 32, -16) glVertex(32, 32, -16) glVertex(32, -32, -16) glVertex(-32, -32, -16) glEnd() glBegin(GL_QUADS) glVertex(-8, 16, 4) glVertex(8, 16, -4) glVertex(8, -16, -4) glVertex(-8, -16, 4) glEnd() glColor(0, 0.5, 1) glBegin(GL_LINES) for plane in planes: glVertex(*(plane.normal * plane.distance)) glVertex(*(plane.normal * (plane.distance + 1))) glEnd() glPolygonMode(GL_FRONT_AND_BACK, GL_LINE) # client client0.draw() SDL_GL_SwapWindow(window)