Exemple #1
0
 def __init__(self, geometries, board, parent):
     format = QGLFormat()
     format.setSampleBuffers(True)
     format.setSamples(8)
     super(GLWidget, self).__init__(format, parent)
     self.camera = Camera()
     self.light = Light()
     self.mouse = Mouse()
     self.geometries = geometries
     self.board = board
Exemple #2
0
class GLWidget(QGLWidget):
    def __init__(self, geometries, board, parent):
        format = QGLFormat()
        format.setSampleBuffers(True)
        format.setSamples(8)
        super(GLWidget, self).__init__(format, parent)
        self.camera = Camera()
        self.light = Light()
        self.mouse = Mouse()
        self.geometries = geometries
        self.board = board

    def initializeGL(self):
        # init window and context
        glClearColor(0.5, 0.5, 1.0, 1.0)

        # load VBOs
        self.VBOs = defaultdict(lambda: [])
        for name, geo in self.geometries.items():
            for i in range(len(geo.vertices)):
                vertices = geo.vertices[i]
                normals = geo.normals[i]
                tangents = geo.tangents[i]
                bitangents = geo.bitangents[i]
                self.VBOs[name].append(vbo.VBO(np.concatenate((vertices, normals, tangents, bitangents), axis=1)))

        glEnable(GL_CULL_FACE)
        glCullFace(GL_FRONT)

        self.fbo_factory = FBOFactory()
        self.fbo_factory.resize(self.width(), self.height())

        self.object_fbo = self.fbo_factory.create()
        self.gaussian1_fbo = self.fbo_factory.create(depth_buffer=False)
        self.gaussian2_fbo = self.fbo_factory.create()
        self.brightparts_fbo = self.fbo_factory.create()
        self.edgedetection_fbo = self.fbo_factory.create()

        self.main_program = MainProgram()
        self.chessboard_program = ChessboardProgram()
        self.texture_program = TextureProgram()
        self.edge_program = EdgeDetectionProgram()
        self.brightparts_program = BrightpartsProgram()
        self.twotextures_program = TwoTexturesProgram()
        self.gaussianblur1 = GaussianBlurPass1Program()
        self.gaussianblur2 = GaussianBlurPass2Program()

        self.animations = []

        QTimer.singleShot(0, self.update)

    def paintGL(self):
        now = time()
        # draw chessman to get contour
        with self.object_fbo:
            glEnable(GL_DEPTH_TEST)
            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
            self.main_program.set_view_matrix(self._view_matrix())
            self.main_program.set_light(self.light)
            self.main_program.set_camera(self.camera)
            for name, position in self._scene_objects():
                self._draw_object(name, position)

        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
        self._draw_board()
        for name, position in self._scene_objects():
            self._draw_object(name, position)

        glDisable(GL_DEPTH_TEST)

        # glow on bright parts
        with self.brightparts_fbo:
            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
            self.brightparts_program.set_threshold(0.9)
            self.brightparts_program.set_fbo(self.object_fbo)
            self.brightparts_program.draw()

        with self.gaussian1_fbo:
            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
            self.gaussianblur1.set_fbo(self.brightparts_fbo)
            self.gaussianblur1.draw()

        with self.gaussian2_fbo:
            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
            self.gaussianblur2.set_fbo(self.gaussian1_fbo)
            self.gaussianblur2.draw()

        glEnable(GL_BLEND)
        glBlendFunc(GL_ONE_MINUS_SRC_ALPHA, GL_DST_ALPHA)
        self.texture_program.set_fbo(self.gaussian2_fbo)
        self.texture_program.draw()
        glDisable(GL_BLEND)

        with self.edgedetection_fbo:
            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
            self.edge_program.set_threshold(2)
            self.edge_program.set_fbo(self.object_fbo)
            self.edge_program.set_view_matrix(self._view_matrix())
            for name, position in self._scene_objects():
                self._draw_edge(name, position)

        with self.gaussian1_fbo:
            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
            self.gaussianblur1.set_fbo(self.edgedetection_fbo)
            self.gaussianblur1.draw()

        with self.gaussian2_fbo:
            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
            self.gaussianblur2.set_fbo(self.gaussian1_fbo)
            self.gaussianblur2.draw()

        glEnable(GL_BLEND)
        glBlendFunc(GL_ONE_MINUS_SRC_ALPHA, GL_DST_COLOR)
        self.texture_program.set_fbo(self.gaussian2_fbo)
        self.texture_program.draw()

        glDisable(GL_BLEND)
        fps = 1/(time() - now)
        # print(fps)


    def resizeGL(self, width, height):
        # projection matrix
        glViewport(0, 0, self.width(), self.height())
        self.main_program.set_projection_matrix(self._projection_matrix())
        self.chessboard_program.set_projection_matrix(self._projection_matrix())
        self.texture_program.resize(width, height)
        self.edge_program.resize(self._projection_matrix(), width, height)
        self.brightparts_program.resize(width, height)
        self.fbo_factory.resize(width, height)
        self.gaussianblur1.resize(width, height)
        self.gaussianblur2.resize(width, height)

    def mousePressEvent(self, event):
        self.mouse.x = event.pos().x()
        self.mouse.y = event.pos().y()
        z = glReadPixels(self.mouse.x, self.mouse.y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT)[0][0]
        self._detect_collision(self.mouse.x, self.mouse.y, z)

    def mouseMoveEvent(self, event):
        if event.buttons() & Qt.LeftButton:
            self.camera.go_right(event.pos().x() - self.mouse.x)
            self.camera.go_up(event.pos().y() - self.mouse.y)
            self.updateGL()

        self.mouse.x = event.pos().x()
        self.mouse.y = event.pos().y()

    def wheelEvent(self, event):
        self.camera.go_forward(event.delta()/5000)

    def update(self):
        try:
            for i in range(len(self.animations)):
                anim = self.animations[i]
                if anim.update():
                    del self.animations[i]
            self.updateGL()
        finally:
            QTimer.singleShot(0, self.update)

    def _detect_collision(self, x, y, z):
        # normalize
        x = (2 * x) / self.width() - 1
        y = 1 - (2 * y) / self.height()
        z = 2 * z - 1
        position = np.array([x, y, z, 1], dtype=np.float64)
        # print(position)
        position = position.dot(np.linalg.inv(self._projection_matrix()))
        print(position)
        # position = position.dot(np.linalg.inv(self._view_matrix()))
        position /= position[3]
        print(position)
        print()

    def _projection_matrix(self):
        return perspective(45, self.width()/self.height(), 0.1, 100)
        # return ortho(-30, 30, -30, 30, 0, 100)

    def _view_matrix(self):
        return look_at(self.camera.position, self.camera.direction, (0,1,0))

    def _model_matrix(self, geo, position):
        return reduce(np.dot, [scale(geo.scaling),
                               rotate(geo.rotation[0], [1, 0, 0]),
                               rotate(geo.rotation[1], [0, 1, 0]),
                               rotate(geo.rotation[2], [0, 0, 1]),
                               translate(geo.translation),
                               translate([(position[0])*4, 0, (position[1])*4])])

    def _scene_objects(self):
        for cell in self.board:
            if isinstance(cell, King):
                if cell.color == Color.WHITE:
                    name = 'WhiteKing'
                else:
                    name = 'BlackKing'
            elif isinstance(cell, Queen):
                if cell.color == Color.WHITE:
                    name = 'WhiteQueen'
                else:
                    name = 'BlackQueen'
            elif isinstance(cell, Bishop):
                if cell.color == Color.WHITE:
                    name = 'WhiteBishop'
                else:
                    name = 'BlackBishop'
            elif isinstance(cell, Knight):
                if cell.color == Color.WHITE:
                    name = 'WhiteKnight'
                else:
                    name = 'BlackKnight'
            elif isinstance(cell, Rook):
                if cell.color == Color.WHITE:
                    name = 'WhiteRook'
                else:
                    name = 'BlackRook'
            elif isinstance(cell, Pawn):
                if cell.color == Color.WHITE:
                    name = 'WhitePawn'
                else:
                    name = 'BlackPawn'
            yield name, cell.position

    def _draw_board(self):
        self.chessboard_program.set_view_matrix(self._view_matrix())
        self.chessboard_program.set_light(self.light)
        self.chessboard_program.set_camera(self.camera)
        vbos = self.VBOs['Chessboard']
        geo = self.geometries['Chessboard']
        for i in range(len(vbos)):
            vbo = vbos[i]
            effect = geo.materials[i]
            model = self._model_matrix(geo, [0, 0])
            self.chessboard_program.draw(vbo, model, effect)


    def _draw_object(self, name, position):
        vbos = self.VBOs[name]
        geo = self.geometries[name]
        for i in range(len(vbos)):
            vbo = vbos[i]
            effect = geo.materials[i]
            model = self._model_matrix(geo, position)
            self.main_program.draw(vbo, model, effect)

    def _draw_edge(self, name, position):
        vbos = self.VBOs[name]
        geo = self.geometries[name]
        for vbo in vbos:
            model = self._model_matrix(geo, position)
            self.edge_program.draw(vbo, model)