Ejemplo n.º 1
0
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)
Ejemplo n.º 2
0
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)
Ejemplo n.º 3
0
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)
Ejemplo n.º 4
0
def main(width, height, json_file):
    SDL_Init(SDL_INIT_VIDEO)
    window = SDL_CreateWindow(
        b'OpenGL Heatmap', SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
        width, height,
        SDL_WINDOW_OPENGL)  #| SDL_WINDOW_BORDERLESS) #SDL_WINDOW_FULLSCREEN
    glContext = SDL_GL_CreateContext(window)

    glClearColor(0, 0, 0, 0)
    gluPerspective(90, width / height, 0.1, 4096 * 4)
    glPointSize(2)
    glPolygonMode(GL_BACK, GL_LINE)
    glEnable(GL_DEPTH_TEST)
    glFrontFace(GL_CW)
    glEnable(GL_CULL_FACE)
    glColor(1, 1, 1)

    SDL_GL_SetSwapInterval(0)
    SDL_CaptureMouse(SDL_TRUE)
    SDL_WarpMouseInWindow(window, width // 2, height // 2)
    SDL_SetRelativeMouseMode(SDL_TRUE)
    SDL_SetWindowGrab(window, SDL_TRUE)

    heatmap = json.load(open(json_file))
    k_class = heatmap['fields'].index('killer_class')
    UNKNOWN = 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')
    filtered_kills = [
        *filter(lambda k: k[k_x:k_x + 3] != [0, 0, 0], heatmap['kills'])
    ][:256]

    cam_spawn = vec3(0, 0, 32)
    init_speed = 128
    VIEW_CAMERA = camera.freecam(cam_spawn, None, init_speed)
    mousepos = 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 += 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:
                ...
            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
            dt -= 1 / tickrate
            oldtime = time()

        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
        glPushMatrix()
        VIEW_CAMERA.set()

        glBegin(GL_LINES)
        for x in range(3):
            axis = [0, 0, 0]
            axis[x] = 1
            glColor(*axis)
            glVertex(0, 0, 0)
            axis[x] = 128
            glVertex(*axis)
        glEnd()

        glTranslate(0, 0, 64)
        glBegin(GL_LINES)
        for kill in filtered_kills:
            glColor(*colorsys.hsv_to_rgb(kill[k_class] / 9, 1, .5))
            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)
Ejemplo n.º 5
0
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)