## 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) if __name__ == '__main__': import getopt import sys, os options = getopt.getopt(sys.argv[1:], 'w:h:bsp:') width, height = 1280, 720 bsp = '../maps/test1.bsp' for option in options: for key, value in option: if key == '-w': width = int(value) elif key == '-h': height = int(value) elif key == '-bsp': bsp = value try: bsp = bsp_tool.bsp(bsp) # load bsp file for debug main(width, height, bsp) except Exception as exc: SDL_Quit() raise exc
glColor(1, 0, 1) glBegin(GL_POINTS) for p in props: position = [float(s) for s in p.origin.split()] glVertex(*position) glEnd() glPointSize(4) glEnable(GL_DEPTH_TEST) glEnable(GL_TEXTURE_2D) glPopMatrix() SDL_GL_SwapWindow(window) if __name__ == '__main__': width, height = 1280, 720 TF = 'E:/Steam/SteamApps/common/Team Fortress 2/tf/' mod = bsp_tool.tf2 ## bsp = '../maps/pl_upward.bsp' bsp = TF + 'maps/cp_cloak.bsp' ## bsp = TF + 'maps/cp_manor_event.bsp' ## bsp = TF + 'maps/cp_coldfront.bsp' ## bsp = TF + 'maps/koth_harvest_final.bsp' ## bsp, mod = "../maps/02a.bsp", bsp_tool.vindictus bsp_object = bsp_tool.bsp(bsp, mod) try: bsp_file = main(1280, 720, bsp_object) except Exception as exc: SDL_Quit() raise exc
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)
def list_maps(folder, ): return map(lambda y: y[:-4], filter(lambda x: x.endswith('.bsp'), os.listdir(folder))) STEAM = TF2 = 'E:/Steam/SteamApps/' TF2 = STEAM + 'common/Team Fortress 2/tf/maps/' TF2_D = STEAM + 'common/Team Fortress 2/tf/download/maps/' TF2_W = STEAM + 'workshop/content/440/' lump_maps = {} bytes_processed = 0 print('*** /tf/maps') for MAP in list_maps(TF2): try: MAP_bsp = bsp(f'{TF2}{MAP}') lump_maps[MAP] = MAP_bsp.lump_map bytes_processed += MAP_bsp.bytesize except: ... print('*** /tf/dowload/maps') for MAP in list_maps(TF2_D): try: MAP_bsp = bsp(f'{TF2_D}{MAP}') lump_maps[f'download/{MAP}'] = MAP_bsp.lump_map bytes_processed += MAP_bsp.bytesize except: ... #all workshop maps are compressed #therefore none can be read without modifying bsp_tool to skip compressed lumps # print('*** /tf/workshop/maps')
if game_mode not in polycounts: polycounts[game_mode] = {map_name: data} else: polycounts[game_mode][map_name] = data def list_maps(folder,): return map(lambda y: y[:-4], filter(lambda x: x.endswith('.bsp'), os.listdir(folder))) bytes_processed = 0 start = time.time() print('*** /tf/maps') TF2 = STEAM + 'common/Team Fortress 2/tf/maps/' for MAP in list_maps(TF2): try: MAP_bsp = bsp_tool.bsp(f'{TF2}{MAP}') MAP_data = calculate_polycount(MAP_bsp) bytes_processed += MAP_bsp.bytesize except KeyboardInterrupt as exc: raise exc except: MAP_data = ['COULD NOT LOAD'] * 7 log_map(MAP_bsp, MAP_data) official_polycounts = {gm: {m: d for m, d in ms.items() if f'{gm}_{m}' in official_maps} for gm, ms in polycounts.items()} official_polycounts = {gm: ms for gm, ms in official_polycounts.items() if ms != {}} outfile = open('official_polycounts.csv', 'w') for game_mode, maps in sorted(official_polycounts.items()): if game_mode in abbreviations: outfile.write('\n' + abbreviations[game_mode] + data_header) else:
sys.path.insert(0, '../') import bsp_tool import itertools def calcTriFanIndices(face, vertices, startIndex): indices = [] for i in range(1, len(vertices) - 1): indices += [startIndex, startIndex + i, startIndex + i + 1] return indices TF = 'E:/Steam/SteamApps/common/Team Fortress 2/tf/' bsp = '../maps/pl_upward.bsp' bsp = bsp_tool.bsp(bsp) print(bsp.filename.upper(), end=' ') print(f'{bsp.bytesize // 1024:,}KB BSP', end=' >>> ') filtered_faces = list(filter(lambda x: x['lightofs'] != -1, bsp.FACES)) #no sky or trigger ## filtered_faces = list(filter(lambda x: x['lightofs'] != -1 and x['dispinfo'] == -1, bsp.FACES)) #no sky, trigger or disp ## filtered_faces = list(filter(lambda x: x['styles'] == (-1, -1, -1, -1), bsp.FACES)) ## filtered_faces = bsp.FACES face_count = len(filtered_faces) current_face_index = 0 current_face = filtered_faces[current_face_index] current_face_verts = [v[0] for v in bsp.verts_of(current_face)] vertices = []
def main(width, height, bsp): bsp = bsp_tool.bsp(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) glClearColor(0, .5, 1, 0) ent_dicts = [] for e in bsp.ENTITIES[1:-1].split('}\n{'): ent_dicts.append(eval('{' + e.replace('" "', '": "').replace('"\n', '", ') + '}')) try: light_environment = [e for e in ent_dicts if e['classname'] == 'light_environment'][0] light_environment['angles'] = tuple(map(float, light_environment['angles'].split(' '))) light_environment['pitch'] = float(light_environment['pitch']) light_environment['_light'] = tuple(map(int, light_environment['_light'].split(' '))) light_environment['_ambient'] = tuple(map(int, light_environment['_ambient'].split(' '))) sun_vector = vec3(1, 0, 0).rotate(light_environment['angles'][2], -light_environment['pitch'], light_environment['angles'][1]) sun_colour = (*[x / 255 for x in light_environment['_light'][:3]], light_environment['_light'][-1]) # vec4 (R, G, B) + Strength sun_ambient = (*[x / 255 for x in light_environment['_ambient'][:3]], light_environment['_ambient'][-1]) # vec4 (R, G, B) + Strength glClearColor(*sun_ambient[:3], 0) except: # no light_environment in .bsp (defaults to goldrush) sun_vector = vec3(1, 0, 0).rotate(0, 35, 108) sun_colour = (1.00, 0.89, 0.73, 600) sun_ambient = (0.46, 0.45, 0.55, 350) glClearColor(0, 0, 0, 0) gluPerspective(90, width / height, 0.1, 4096 * 4) glPointSize(4) glPolygonMode(GL_BACK, GL_LINE) glEnable(GL_DEPTH_TEST) glFrontFace(GL_CW) glEnable(GL_CULL_FACE) glColor(1, 1, 1) filtered_faces = list(filter(lambda x: x['lightofs'] != -1, bsp.FACES)) #no sky or trigger ## filtered_faces = list(filter(lambda x: x['dispinfo'] != -1, bsp.FACES)) #disp only ## filtered_faces = list(filter(lambda x: x['lightofs'] != -1 and x['dispinfo'] == -1, bsp.FACES)) #no sky, trigger or disp ## filtered_faces = list(filter(lambda x: x['styles'] == (-1, -1, -1, -1), bsp.FACES)) ## filtered_faces = bsp.FACES face_count = len(filtered_faces) current_face_index = 0 current_face = filtered_faces[current_face_index] current_face_verts = [v[0] for v in bsp.verts_of(current_face)] all_faces = [] all_faces_map = [] start = 0 t1 = time() for face in filtered_faces: if face['dispinfo'] == -1: f_verts = bsp.verts_of(face) # add to vertex buffer here and fan the indices 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.dispverts_of(face) f_verts = bsp_tool.disp_tris(f_verts, power) all_faces += f_verts slow_faces = all_faces.copy() all_faces = list(itertools.chain(*itertools.chain(*all_faces))) all_faces_size = len(all_faces) vertices = all_faces indices = range(all_faces_size) ## print('compressing vertex buffer...') ## vertices = [] ## indices = [] ## currentIndex = 0 ## for face in filtered_faces: ## if face["dispinfo"] == -1: ## faceVerts = bsp.verts_of(face) ## faceIndices = calcTriFanIndices(faceVerts, currentIndex) ## else: ## power = bsp.DISP_INFO[face['dispinfo']]['power'] ## faceVerts = bsp_tool.disp_tris(bsp.dispverts_of(face), power) ## faceIndices = bsp_tool.disp_tris(range((2 ** power + 1) ** 2), power) ## vertices += faceVerts ## indices += faceIndices ## currentIndex = faceIndices[-1] + 1 # ? ## vertices = list(itertools.chain(*itertools.chain(*vertices))) ## RGB_LIGHTING = [] ## for RGBE_texel in struct.iter_unpack('3Bb', bsp.LIGHTING): ## RGBA_texel = vec3(RGBE_texel[:-1]) * 2 ** RGBE_texel[-1] ## RGBA_texel = [clamp(int(x) // 2, 0, 255) for x in RGBA_texel] ## RGB_LIGHTING.append(struct.pack('3Bb', *RGBA_texel, RGBE_texel[3])) ## RGB_LIGHTING = b''.join(RGB_LIGHTING) ## ## lightmap = [] # store on GPU ## for face in filtered_faces: ## lmap_start = face['lightofs'] ## if lmap_start != -1: ## bounds = face['LightmapTextureSizeinLuxels'] ## bounds = [x + 1 for x in bounds] ## num_styles = sum([1 if x is not -1 else 0 for x in face['styles']]) ## lmap_end = lmap_start + bounds[0] * bounds[1] * 4 * num_styles ## lmap_bytes = RGB_LIGHTING[lmap_start:lmap_end] ## lightmap.append([lmap_bytes, bounds]) t2 = time() print(bsp.filename.upper(), end=' ') print(f'{bsp.bytesize // 1024:,}KB BSP', end=' >>> ') print(f'{len(all_faces) // 9:,} TRIS', end=' & ') print(f'{(len(all_faces) * 4) // 1024:,}KB VRAM') print(f'ASSEMBLED IN {(t2 - t1) * 1000:,.3f}ms') print() # SHADERS (check GLSL version) USING_ES = False try: vertShader = compileShader(open('shaders/bsp_faces.v', 'rb'), GL_VERTEX_SHADER) fragShader = compileShader(open('shaders/bsp_faces.f', 'rb'), GL_FRAGMENT_SHADER) except Exception as exc: # requires PyOpenGL changes described elsewhere USING_ES = True # if OpenGL 4.5 is not supported, switch to GLES 3.0 vertShader = compileShader(open('shaders/bsp_faces_300_es.v', 'rb'), GL_VERTEX_SHADER) fragShader = compileShader(open('shaders/bsp_faces_300_es.f', 'rb'), GL_FRAGMENT_SHADER) raise exc # need error log if issue is not GLSL version bsp_shader = compileProgram(vertShader, fragShader) glLinkProgram(bsp_shader) glUseProgram(bsp_shader) # must UseProgram to set uniforms # UNIFORMS if USING_ES: # GLES vertex attribs attrib_position = glGetAttribLocation(bsp_shader, 'vertexPosition') attrib_normal = glGetAttribLocation(bsp_shader, 'vertexNormal') attrib_texture_uv = glGetAttribLocation(bsp_shader, 'vertexTexCoord') attrib_lightmap_uv = glGetAttribLocation(bsp_shader, 'vertexLightCoord') attrib_colour_uv = glGetAttribLocation(bsp_shader, 'vertexColour') ## ProjectionMatrixLoc = glGetUniformLocation(bsp_shader, 'ProjectionMatrix') ## # https://www.khronos.org/opengl/wiki/GluPerspective_code ## glUniformMatrix4fv(ProjectionMatrixLoc, 1, GL_FALSE, ProjectionMatrix) # bad input? else: # glsl 450 core uniforms glUniform3f(glGetUniformLocation(bsp_shader, 'sun_vector'), *sun_vector) glUniform4f(glGetUniformLocation(bsp_shader, 'sun_colour'), *sun_colour) glUniform4f(glGetUniformLocation(bsp_shader, 'sun_ambient'), *sun_ambient) VERTEX_BUFFER, INDEX_BUFFER = glGenBuffers(2) glBindBuffer(GL_ARRAY_BUFFER, VERTEX_BUFFER) glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, INDEX_BUFFER) glBufferData(GL_ELEMENT_ARRAY_BUFFER, len(indices) * 4, np.array(indices, dtype=np.uint32), GL_STATIC_DRAW) # INDICES glBufferData(GL_ARRAY_BUFFER, len(vertices) * 4, np.array(vertices, dtype=np.float32), GL_STATIC_DRAW) # VERTICES glEnableVertexAttribArray(0) #vertexPosition glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 52, GLvoidp(0)) glEnableVertexAttribArray(1) #vertexNormal glVertexAttribPointer(1, 3, GL_FLOAT, GL_TRUE, 52, GLvoidp(12)) glEnableVertexAttribArray(2) #vertexTexcoord glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 52, GLvoidp(24)) glEnableVertexAttribArray(3) #vertexLightmapCoord glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, 52, GLvoidp(32)) glEnableVertexAttribArray(4) #reflectivityColour glVertexAttribPointer(4, 3, GL_FLOAT, GL_FALSE, 52, GLvoidp(40)) # displacement alpha (seperate format or shared?) glEnable(GL_TEXTURE_2D) glActiveTexture(GL_TEXTURE0) # texture = open('materials/obsolete.bmp', 'rb') texture = open('materials/dev/reflectivity_100.bmp', 'rb') texture.seek(54) # glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB4, 256, 256, 0, GL_BGR, GL_UNSIGNED_BYTE, texture.read()) glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB4, 512, 512, 0, GL_BGR, GL_UNSIGNED_BYTE, texture.read()) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST) texture.close() del texture 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 = vec3(0, 0, 32) init_speed = 128 VIEW_CAMERA = camera.freecam(cam_spawn, None, init_speed) ## # http://heatmaps.tf/api.html ## url_tail = '.json?fields=id,timestamp,killer_class,killer_weapon,killer_x,killer_y,killer_z,victim_class,victim_x,victim_y,victim_z,customkill,damagebits,death_flags,team&limit=1024' #### heatmap = json.load(urllib.request.urlopen('http://heatmaps.tf/data/kills/' + bsp.filename[:-4] + url_tail)) # including the limit in the url is great for load times ## heatmap = json.load(open('heatmaps.tf/pl_upward_complete.json')) ## k_class = heatmap['fields'].index('killer_class') ## k_wep = heatmap['fields'].index('killer_weapon') ## MINI_SENTRY = -2 ## SENTRY = -1 ## WORLD = 0 ## SCOUT = 1 ## SNIPER = 2 ## SOLDIER = 3 ## DEMOMAN = 4 ## MEDIC = 5 ## HEAVY = 6 ## PYRO = 7 ## SPY = 8 ## ENGINEER = 9 ## k_x = heatmap['fields'].index('killer_x') ## v_class = heatmap['fields'].index('victim_class') ## v_x = heatmap['fields'].index('victim_x') ## kill_range = lambda kill: (vec3(*kill[v_x:v_x + 3]) - vec3(*kill[k_x:k_x + 3])).magnitude() ## ## filtered_kills = [*filter(lambda k: k[k_wep] == MINI_SENTRY, heatmap['kills'])][:1024] mousepos = vec2() keys = [] tickrate = 120 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 bsp 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 += 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) # turning sun sun_vector = sun_vector.rotate(.05, 0, 0) glUseProgram(bsp_shader) glUniform3f(glGetUniformLocation(bsp_shader, 'sun_vector'), *sun_vector) #update projection matrix if SDLK_BACKQUOTE in keys: ## print(VIEW_CAMERA) #FACES fe, ne = current_face['firstedge'], current_face['numedges'] se_loop = bsp.SURFEDGES[fe:fe + ne] e_loop = [bsp.EDGES[e] for e in se_loop] print(f'{bsp.filename}.FACES[{bsp.FACES.index(current_face)}]', '\n'.join([f'{k} = {v}' for k,v in current_face.items()]), sep='\n') print('\n\t', '\n\t'.join([f'{bsp.VERTICES[v]}' for v in itertools.chain(*e_loop)][::2]), sep='', end='\n\n') face_center = sum(map(vec3, current_face_verts), vec3()) / len(current_face_verts) face_normal = bsp.PLANES[current_face['planenum']]['normal'] VIEW_CAMERA.position = face_center + vec3(face_normal) * 32 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 += 5 if SDLK_LCTRL in keys: VIEW_CAMERA.speed -= 5 if SDLK_LEFT in keys or SDL_BUTTON_LEFT in keys: current_face_index -= 1 current_face = filtered_faces[current_face_index] current_face_verts = [v[0] for v in bsp.verts_of(current_face)] 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_face_index += 1 current_face = filtered_faces[current_face_index] current_face_verts = [v[0] for v in bsp.verts_of(current_face)] 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_FILL) glUseProgram(bsp_shader) ## for i, face in enumerate(all_faces_map): ## texture = lightmap[i] ## glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texture[1][0], texture[1][1], 0, GL_RGBA, GL_UNSIGNED_BYTE, texture[0]) ## glDrawArrays(GL_TRIANGLES, face[0], face[1]) ## glDrawArrays(GL_TRIANGLES, 0, all_faces_size) # supported in gl3.0 Mesa? glDrawElements(GL_TRIANGLES, len(indices), GL_UNSIGNED_INT, GLvoidp(0)) # for when shaders are too much work ## glBegin(GL_TRIANGLES) ## for pos, normal, uv, uv2, colour in slow_faces[:2048]: ## glColor(*colour) ## glTexCoord(*uv) ## glVertex(*pos) ## glEnd() # CENTER MARKER ## 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() glUseProgram(0) glDisable(GL_TEXTURE_2D) glPolygonMode(GL_FRONT_AND_BACK, GL_LINE) glColor(1, 1, 1) glDisable(GL_DEPTH_TEST) ## glBegin(GL_LINE_LOOP) ## for vertex in current_face_verts: ## glVertex(*vertex) ## glEnd() ## glBegin(GL_POINTS) ## for vertex in current_face_verts: ## glVertex(*vertex) ## glEnd() glPointSize(24) glBegin(GL_POINTS) glVertex(*(sun_vector * 4096)) glEnd() glPointSize(4) glEnable(GL_DEPTH_TEST) glEnable(GL_TEXTURE_2D) ## glTranslate(0, 0, 64) ## glBegin(GL_LINES) ## for kill in filtered_kills: ## glColor(*colorsys.hsv_to_rgb(kill[k_class] / 9, 1, .75)) ## glVertex(*kill[k_x:k_x + 3]) ## glColor(*colorsys.hsv_to_rgb(kill[v_class] / 9, 1, 1)) ## glVertex(*kill[v_x:v_x + 3]) ## glEnd() glPopMatrix() SDL_GL_SwapWindow(window)
print('Done!') if __name__ == "__main__": import argparse # -g --game [tf2/hl2/vindictus] # -o --outfile ## 3 error levels -W -Warn # -W strict // stop if cannot load ANY chunk # -W lazy // ignore any and all chunks that cannot be loaded import sys sys.path.insert(0, "../") import bsp_tool if len(sys.argv) > 1: # drag & drop obj converter for map_path in sys.argv[1:]: bsp = bsp_tool.bsp(map_path) start = time.time() obj_file = open(map_path + '.obj', 'w') buffer = "" for line in write_obj(bsp): buffer += line if len(buffer) > 2048: obj_file.write(buffer) buffer = "" obj_file.close() conversion_time = time.time() - start print( f'Converting {bsp.filename} took {conversion_time // 60:.0f}:{conversion_time % 60:.3f}' ) else: