def run(self):
        controller = self.controller
        drawcalls = controller.GetDrawcalls()
        relevant_drawcalls, capture_type = self.extractRelevantCalls(drawcalls)
        print(f"Scraping capture from {capture_type}...")

        if MAX_BLOCKS <= 0:
            max_drawcall = len(relevant_drawcalls)
        else:
            max_drawcall = min(MAX_BLOCKS, len(relevant_drawcalls))

        for drawcallId, draw in enumerate(relevant_drawcalls[:max_drawcall]):
            print("Draw call: " + draw.name)
            
            controller.SetFrameEvent(draw.eventId, True)
            state = controller.GetPipelineState()

            ib = state.GetIBuffer()
            vbs = state.GetVBuffers()
            attrs = state.GetVertexInputs()
            meshes = [makeMeshData(attr, ib, vbs, draw) for attr in attrs]

            try:
                # Position
                m = meshes[0]
                m.fetchTriangle(controller)
                indices = m.fetchIndices(controller)
                with open("{}{:05d}-indices.bin".format(FILEPREFIX, drawcallId), 'wb') as file:
                    pickle.dump(indices, file)
                unpacked = m.fetchData(controller)
                with open("{}{:05d}-positions.bin".format(FILEPREFIX, drawcallId), 'wb') as file:
                    pickle.dump(unpacked, file)

                # UV
                m = meshes[2 if capture_type == "Google Earth" else 1]
                m.fetchTriangle(controller)
                unpacked = m.fetchData(controller)
                with open("{}{:05d}-uv.bin".format(FILEPREFIX, drawcallId), 'wb') as file:
                    pickle.dump(unpacked, file)
            except Exception as err:
                print("(Skipping because of error: {})".format(err))
                continue

            # Vertex Shader Constants
            shader = state.GetShader(rd.ShaderStage.Vertex)
            ep = state.GetShaderEntryPoint(rd.ShaderStage.Vertex)
            ref = state.GetShaderReflection(rd.ShaderStage.Vertex)
            constants = self.getVertexShaderConstants(draw, state=state)
            constants["DrawCall"] = {
                "topology": 'TRIANGLE_STRIP' if draw.topology == rd.Topology.TriangleStrip else 'TRIANGLES',
                "type": capture_type
            }
            with open("{}{:05d}-constants.bin".format(FILEPREFIX, drawcallId), 'wb') as file:
                pickle.dump(constants, file)

            self.extractTexture(drawcallId, state)
    def run(self):
        controller = self.controller
        drawcalls = controller.GetDrawcalls()
        relevant_drawcalls, capture_type = self.extractRelevantCalls(drawcalls)
        print(f"Scrapping capture from {capture_type}...")

        if MAX_BLOCKS <= 0:
            max_drawcall = len(relevant_drawcalls)
        else:
            max_drawcall = min(MAX_BLOCKS, len(relevant_drawcalls))

        for drawcallId, draw in enumerate(relevant_drawcalls[:max_drawcall]):
            print("Draw call: " + draw.name)
            
            controller.SetFrameEvent(draw.eventId, True)
            state = controller.GetPipelineState()

            ib = state.GetIBuffer()
            vbs = state.GetVBuffers()
            attrs = state.GetVertexInputs()
            meshes = [makeMeshData(attr, ib, vbs, draw) for attr in attrs]

            try:
                # Position
                m = meshes[0]
                m.fetchTriangle(controller)
                indices = m.fetchIndices(controller)
                with open("{}{:05d}-indices.bin".format(FILEPREFIX, drawcallId), 'wb') as file:
                    pickle.dump(indices, file)
                unpacked = m.fetchData(controller)
                with open("{}{:05d}-positions.bin".format(FILEPREFIX, drawcallId), 'wb') as file:
                    pickle.dump(unpacked, file)

                # UV
                m = meshes[2 if capture_type == "Google Earth" else 1]
                m.fetchTriangle(controller)
                unpacked = m.fetchData(controller)
                with open("{}{:05d}-uv.bin".format(FILEPREFIX, drawcallId), 'wb') as file:
                    pickle.dump(unpacked, file)
            except RuntimeError as err:
                print("(Skipping: {})".format(err))
                continue

            # Vertex Shader Constants
            shader = state.GetShader(rd.ShaderStage.Vertex)
            ep = state.GetShaderEntryPoint(rd.ShaderStage.Vertex)
            ref = state.GetShaderReflection(rd.ShaderStage.Vertex)
            constants = self.getVertexShaderConstants(draw, state=state)
            constants["DrawCall"] = {
                "topology": 'TRIANGLE_STRIP' if draw.topology == rd.Topology.TriangleStrip else 'TRIANGLES',
                "type": capture_type
            }
            with open("{}{:05d}-constants.bin".format(FILEPREFIX, drawcallId), 'wb') as file:
                pickle.dump(constants, file)

            # Texture
            # dirty
            bindpoints = state.GetBindpointMapping(rd.ShaderStage.Fragment)
            texture_bind = bindpoints.samplers[-1].bind
            resources = state.GetReadOnlyResources(rd.ShaderStage.Fragment)
            rid = resources[texture_bind].resources[0].resourceId
            
            texsave = rd.TextureSave()
            texsave.resourceId = rid
            texsave.mip = 0
            texsave.slice.sliceIndex = 0
            texsave.alpha = rd.AlphaMapping.Preserve
            texsave.destType = rd.FileType.PNG
            controller.SaveTexture(texsave, "{}{:05d}-texture.png".format(FILEPREFIX, drawcallId))
Beispiel #3
0
def main(controller):
    drawcalls = controller.GetDrawcalls()
    relevant_drawcalls = list_relevant_calls(drawcalls)

    for drawcallId, draw in enumerate(relevant_drawcalls):
        print("Draw call: " + draw.name)
        if not draw.name.startswith("glDrawElements"):
            print("(Skipping)")
            continue

        controller.SetFrameEvent(draw.eventId, True)
        state = controller.GetPipelineState()

        ib = state.GetIBuffer()
        vbs = state.GetVBuffers()
        attrs = state.GetVertexInputs()
        meshes = [makeMeshData(attr, ib, vbs, draw) for attr in attrs]

        try:
            # Position
            m = meshes[0]
            m.fetchTriangle(controller)
            indices = m.fetchIndices(controller)
            with open("{}{:05d}-indices.bin".format(FILEPREFIX, drawcallId),
                      'wb') as file:
                pickle.dump(indices, file)
            unpacked = m.fetchData(controller)
            with open("{}{:05d}-positions.bin".format(FILEPREFIX, drawcallId),
                      'wb') as file:
                pickle.dump(unpacked, file)

            # UV
            m = meshes[1]
            m.fetchTriangle(controller)
            unpacked = m.fetchData(controller)
            with open("{}{:05d}-uv.bin".format(FILEPREFIX, drawcallId),
                      'wb') as file:
                pickle.dump(unpacked, file)
        except RuntimeError as err:
            print("(Skipping: {})".format(err))
            continue

        # Vertex Shader Constants
        shader = state.GetShader(rd.ShaderStage.Vertex)
        ep = state.GetShaderEntryPoint(rd.ShaderStage.Vertex)
        ref = state.GetShaderReflection(rd.ShaderStage.Vertex)
        constants = {}
        for cb in ref.constantBlocks:
            block = {}
            variables = controller.GetCBufferVariableContents(
                shader, ep, cb.bindPoint, rd.ResourceId.Null(), 0)
            for var in variables:
                val = 0
                if var.members:
                    val = []
                    for member in var.members:
                        memval = 0
                        if member.type == rd.VarType.Float:
                            memval = member.value.fv[:member.rows *
                                                     member.columns]
                        elif member.type == rd.VarType.Int:
                            memval = member.value.iv[:member.rows *
                                                     member.columns]
                        # ...
                        val.append(memval)
                else:
                    if var.type == rd.VarType.Float:
                        val = var.value.fv[:var.rows * var.columns]
                    elif var.type == rd.VarType.Int:
                        val = var.value.iv[:var.rows * var.columns]
                    # ...
                block[var.name] = val
            constants[cb.name] = block
        with open("{}{:05d}-constants.bin".format(FILEPREFIX, drawcallId),
                  'wb') as file:
            pickle.dump(constants, file)

        # Texture
        # dirty
        resources = state.GetReadOnlyResources(rd.ShaderStage.Fragment)
        rid = resources[0].resources[0].resourceId

        texsave = rd.TextureSave()
        texsave.resourceId = rid
        texsave.mip = 0
        texsave.slice.sliceIndex = 0
        texsave.alpha = rd.AlphaMapping.Preserve
        texsave.destType = rd.FileType.PNG
        controller.SaveTexture(
            texsave, "{}{:05d}-texture.png".format(FILEPREFIX, drawcallId))