Exemple #1
0
    def _init_shader(self):

        self._logger.debug('Initialise Shader')

        import ShaderProgramesV4 as ShaderProgrames
        self.shader_manager = ShaderProgrames.shader_manager
        self.position_shader_interface = ShaderProgrames.position_shader_program_interface
        self.rule_shader_interface = ShaderProgrames.rule_shader_program_interface
        self.text_shader_interface = ShaderProgrames.text_shader_program_interface

        # Fixme: share interface
        self._viewport_uniform_buffer = GlUniformBuffer()
        viewport_uniform_block = self.position_shader_interface.uniform_blocks.viewport
        self._viewport_uniform_buffer.bind_buffer_base(
            viewport_uniform_block.binding_point)
    def _init_shader(self):

        self.logger.debug('Initialise Shader')

        import ShaderProgramesV4 as ShaderProgrames
        self.shader_manager = ShaderProgrames.shader_manager
        self.position_shader_interface = ShaderProgrames.position_shader_program_interface

        # Fixme: share interface
        self._viewport_uniform_buffer = GlUniformBuffer()
        viewport_uniform_block = self.position_shader_interface.uniform_blocks.viewport
        self._viewport_uniform_buffer.bind_buffer_base(viewport_uniform_block.binding_point)
    def _init_shader(self):

        self._logger.debug('Initialise Shader')

        from PyGeoPortail.GraphicEngine import ShaderProgrames as ShaderProgrames
        self.shader_manager = ShaderProgrames.shader_manager
        self.position_shader_interface = ShaderProgrames.program_interfaces['position_shader_program_interface']

        # Fixme: share interface
        self._viewport_uniform_buffer = GlUniformBuffer()
        viewport_uniform_block = self.position_shader_interface.uniform_blocks.viewport
        self._viewport_uniform_buffer.bind_buffer_base(viewport_uniform_block.binding_point)
Exemple #4
0
    def _init_shader(self):

        self.logger.debug('Initialise Shader')

        # try:
        import ShaderProgramesV3 as ShaderProgrames
        # except:
        # #? QtGui.QApplication.instance().quit()
        # import sys
        # sys.exit(1)
        self.shader_manager = ShaderProgrames.shader_manager
        self.position_shader_interface = ShaderProgrames.position_shader_program_interface

        # Fixme: share interface
        self._viewport_uniform_buffer = GlUniformBuffer()
        viewport_uniform_block = self.position_shader_interface.uniform_blocks.viewport
        self._viewport_uniform_buffer.bind_buffer_base(viewport_uniform_block.binding_point)
class GlWidget(GlWidgetBase):

    logger = logging.getLogger(__name__)

    ##############################################

    def __init__(self, parent):

        self.logger.debug('Initialise GlWidget')

        super(GlWidget, self).__init__(parent)

    ##############################################

    def wheelEvent(self, event):

        self.logger.debug('Wheel Event')

        return self.wheel_zoom(event)

    ##############################################

    def init_glortho2d(self):

        # Set max_area so as to correspond to max_binning zoom centered at the origin
        area_size = 10**3
        max_area = IntervalInt2D([-area_size, area_size], [-area_size, area_size])

        super(GlWidget, self).init_glortho2d(max_area, zoom_manager=None)

    ##############################################

    def initializeGL(self):

        self.logger.debug('Initialise GL')

        super(GlWidget, self).initializeGL()

        # Require compatibility profile
        GL.glEnable(GL.GL_POINT_SMOOTH)
        GL.glEnable(GL.GL_LINE_SMOOTH)

        self._init_shader()
        self.create_vertex_array_objects()

    ##############################################

    def _init_shader(self):

        self.logger.debug('Initialise Shader')

        import ShaderProgramesV4 as ShaderProgrames
        self.shader_manager = ShaderProgrames.shader_manager
        self.position_shader_interface = ShaderProgrames.position_shader_program_interface

        # Fixme: share interface
        self._viewport_uniform_buffer = GlUniformBuffer()
        viewport_uniform_block = self.position_shader_interface.uniform_blocks.viewport
        self._viewport_uniform_buffer.bind_buffer_base(viewport_uniform_block.binding_point)

    ##############################################

    def update_model_view_projection_matrix(self):

        self.logger.debug('Update Model View Projection Matrix'
                         '\n' + str(self.glortho2d))

        # To test NVPath API
        # See also DSA http://www.opengl.org/registry/specs/EXT/direct_state_access.txt
        #compat# GL.glMatrixMode(GL.GL_PROJECTION)
        #compat# GL.glLoadIdentity()
        #GLU# GLU.gluOrtho2D(* self.glortho2d.ortho2d_bounding_box())

        viewport_uniform_buffer_data = self.glortho2d.viewport_uniform_buffer_data(self.size())
        self.logger.debug('Viewport Uniform Buffer Data '
                          '\n' + str(viewport_uniform_buffer_data))
        self._viewport_uniform_buffer.set(viewport_uniform_buffer_data)

    ##############################################

    def create_vertex_array_objects(self):

        self.create_grid()
        if nvpath is not None:
            self.create_path()
        self.create_lines()
        self.create_textures()
        self.create_text()

    ##############################################

    def create_grid(self):

        step = 100
        x_min, x_max = -1000, 1000
        y_min, y_max = -1000, 1000

        segments = []
        for x in range(x_min, x_max +1, step):
            p1 = Point(x, y_min)
            p2 = Point(x, y_max)
            segments.append(Segment(p1, p2))
        for y in range(y_min, y_max +1, step):
            p1 = Point(y_min, y)
            p2 = Point(y_max, y)
            segments.append(Segment(p1, p2))

        self.grid_vertex_array = GlSegmentVertexArray(segments)
        self.grid_vertex_array.bind_to_shader(self.position_shader_interface.attributes.position)

    ##############################################

    def create_path(self):

        self.path_object = nvpath.glGenPathsNV(1)
        # six.print_(self.path_object)
        start_ps_path = """ 100 180 moveto 40 10 lineto 190 120 lineto 10 120 lineto 160 10 lineto closepath   """
        nvpath.glPathStringNV(self.path_object, nvpath.GL_PATH_FORMAT_PS_NV, len(start_ps_path), start_ps_path)
        nvpath.glPathParameteriNV(self.path_object, nvpath.GL_PATH_JOIN_STYLE_NV, nvpath.GL_ROUND_NV)
        nvpath.glPathParameterfNV(self.path_object, nvpath.GL_PATH_STROKE_WIDTH_NV, 6.5)

    ##############################################

    def create_lines(self):

        def simple_square_generator(radius):
            p1 = Point(-radius, -radius)
            p2 = Point(-radius,  radius)
            p3 = Point( radius,  radius)
            p4 = Point( radius, -radius)
            return (Segment(p1, p2),
                    Segment(p2, p3),
                    Segment(p3, p4),
                    Segment(p4, p1),
                    )

        segments = simple_square_generator(radius=10)
        self.simple_square_vertex_array = GlSegmentVertexArray(segments)
        self.simple_square_vertex_array.bind_to_shader(self.position_shader_interface.attributes.position)

        def segment_generator(radius):
            p1 = Point(-radius, -radius)
            p2 = Point(      0,  radius)
            p3 = Point( radius, -radius)
            return (Segment(p1, p2),
                    Segment(p2, p3),
                    Segment(p3, p1),
                    )

        segments = segment_generator(radius=5)
        self.segment_vertex_array1 = GlSegmentVertexArray(segments)
        self.segment_vertex_array1.bind_to_shader(self.position_shader_interface.attributes.position)

        segments2 = segment_generator(radius=10)
        self.segment_vertex_array2 = GlSegmentVertexArray(segments2)
        self.segment_vertex_array2.bind_to_shader(self.position_shader_interface.attributes.position)

        segments3 = (Segment(Point(-5, 0), Point(5, 0)),
                     Segment(Point(-5, 1), Point(5, 1)),
                     Segment(Point(0, -5), Point(0, 5)),
                     Segment(Point(1, -5), Point(1, 5)),
                     )
        self.segment_vertex_array3 = GlSegmentVertexArray(segments3)
        self.segment_vertex_array3.bind_to_shader(self.position_shader_interface.attributes.position)


        rectangles = (Rectangle(Point(0, 0), Offset(5, 5)),
                      Rectangle(Point(-5, -5), Offset(6, 6)),
                      )
        self.rectangle_vertex_array = GlRectangleVertexArray(rectangles)
        self.rectangle_vertex_array.bind_to_shader(self.position_shader_interface.attributes.position)

        centred_rectangles = (Rectangle(Point(0, 0), Offset(1, 1)),
                              )
        self.centred_rectangle_vertex_array = GlRectangleVertexArray(centred_rectangles)
        self.centred_rectangle_vertex_array.bind_to_shader(self.position_shader_interface.attributes.position)

        segments = (Segment(Point(0,0), Point(5,5)),
                    )
        self.line_vertex_array1 = GlSegmentVertexArray(segments)
        self.line_vertex_array1.bind_to_shader(self.position_shader_interface.attributes.position)

        segments = (Segment(Point(-5,5), Point(5,-5)),
                    )
        self.line_vertex_array2 = GlSegmentVertexArray(segments)
        self.line_vertex_array2.bind_to_shader(self.position_shader_interface.attributes.position)

        # stipple_pattern = 01111111111111111
        # stipple_pattern = 01100110011001111
        stipple_pattern = 0xFF00
        self.stipple_texture = GlStippleTexture(stipple_pattern)

    ##############################################

    def create_textures(self):

        depth = 16

        if depth == 8:
            data_type = np.uint8
        elif depth == 16:
            data_type = np.uint16
        intensity_max = 2**depth -1
        integer_internal_format = True

        height, width = 10, 10
        number_of_planes = 3
        data = np.zeros((height, width, number_of_planes),
                        data_type)
        for c in range(width):
            data[:,c,:] = int((float(c+1) / width) * intensity_max)
        # data[...] = intensity_max
        # six.print_(data)
        self.image = data

        self.texture_vertex_array1 = GlTextureVertexArray(position=Point(0, 0), dimension=Offset(width, height), image=data,
                                                          integer_internal_format=integer_internal_format)
        self.texture_vertex_array1.bind_to_shader(self.shader_manager.texture_shader_program.interface.attributes)

        # self.texture_vertex_array2 = GlTextureVertexArray(position=Point(-5, -5), dimension=Offset(width, height))
        # self.texture_vertex_array2.set(image=data//2, integer_internal_format=integer_internal_format)
        # self.texture_vertex_array2.bind_to_shader(self.shader_manager.texture_shader_program.interface.attributes)

        from PIL import Image
        image = Image.open('flower.png')
        data = np.asarray(image, dtype=np.uint8)
        self.texture_vertex_array2 = GlTextureVertexArray(position=Point(-10, -10), dimension=Offset(width, height))
        self.texture_vertex_array2.set(image=data, integer_internal_format=integer_internal_format)
        self.texture_vertex_array2.bind_to_shader(self.shader_manager.texture_shader_program.interface.attributes)

        height, width = 50, 50
        data = np.zeros((height, width, number_of_planes),
                        data_type)
        # data[...] = intensity_max
        data[10:20,10:20,0] = 1
        data[30:50,30:50,1] = 2
        self.texture_vertex_array3 = GlTextureVertexArray(position=Point(15, 15), dimension=Offset(width, height))
        self.texture_vertex_array3.set(image=data, integer_internal_format=integer_internal_format)
        self.texture_vertex_array3.bind_to_shader(self.shader_manager.texture_label_shader_program.interface.attributes)
        # self.texture_vertex_array3.bind_to_shader(self.shader_manager.texture_shader_program.interface.attributes)

    ##############################################

    def create_text(self):

        self.font = TextureFont('./Vera.ttf')
        self.font_size = self.font[25]
        self.font_size.load_all_glyphs()
        self.font.atlas.save('atlas.png')
        self.font_atlas_texture = ImageTexture(self.font.atlas.data)

        self.text_vertex_array = TextVertexArray(self.font_atlas_texture)
        self.text_vertex_array.add(text="| A Quick Brown Fox Jumps Over The Lazy Dog fi ffl Va",
                                   font_size=self.font_size,
                                   colour=(1.0, 1.0, .0, 1.0),
                                   x=0, y=0,
                                   anchor_x='left', anchor_y='baseline',
                                   )
        self.text_vertex_array.add(text="| Foo Bar",
                                   font_size=self.font_size,
                                   colour=(.0, 1.0, .0, 1.0),
                                   x=200, y=100,
                                   anchor_x='left', anchor_y='baseline',
                                   )
        self.text_vertex_array.upload()
        self.text_vertex_array.bind_to_shader(self.shader_manager.text_shader_program.interface.attributes)

    ##############################################

    def paint(self):

        self.paint_grid()
        if nvpath is not None:
            self.paint_path()
        self.paint_textures()
        self.paint_lines()
        self.paint_text()

        if LOG_GL_CALL:
            six.print_('\n', '='*100)
            for command in GL.called_commands():
                six.print_('\n', '-'*50)
                # six.print_(str(command))
                six.print_(command._command.prototype())
                six.print_(command.help())

    ##############################################

    def paint_grid(self):

        shader_program = self.shader_manager.fixed_shader_program
        shader_program.bind()

        GL.glLineWidth(1.)
        shader_program.uniforms.colour = (1., 1., 1.)
        self.grid_vertex_array.draw()

        GL.glLineWidth(10.)
        x = 150
        GlFixedPipeline.draw_rectangle(-x, -x, x, x)

        shader_program.unbind()

    ##############################################

    def paint_path(self):

        # Unbind shader /!\

        # GL.glClearStencil(0)
        # GL.glClearColor(0,0,0,0)
        # # GL.glClear(GL.GL_COLOR_BUFFER_BIT)
        # GL.glStencilMask(~0)
        # GL.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_STENCIL_BUFFER_BIT)

        filling = False # /!\ clear framebuffer
        even_odd = True
        stroking = True

        if filling:
            nvpath.glStencilFillPathNV(self.path_object, nvpath.GL_COUNT_UP_NV, 0x1F)
            GL.glEnable(GL.GL_STENCIL_TEST)
            if even_odd:
                GL.glStencilFunc(GL.GL_NOTEQUAL, 0, 0x1)
            else:
                GL.glStencilFunc(GL.GL_NOTEQUAL, 0, 0x1F)
            GL.glStencilOp(GL.GL_KEEP, GL.GL_KEEP, GL.GL_ZERO)
            GL.glColor3f(0,1,0) #  green
            nvpath.glCoverFillPathNV(self.path_object, nvpath.GL_BOUNDING_BOX_NV)

        if stroking:
            nvpath.glStencilStrokePathNV(self.path_object, 0x1, ~0)
            GL.glColor3f(1,1,0) # yellow
            nvpath.glCoverStrokePathNV(self.path_object, nvpath.GL_CONVEX_HULL_NV)

    ##############################################

    def paint_lines(self):

        shader_program = self.shader_manager.fixed_shader_program
        shader_program.bind()

        GL.glLineWidth(1.)
        shader_program.uniforms.colour = (0., 0., 1.)
        self.simple_square_vertex_array.draw()

        # try:
        GL.glLineWidth(5.)
        shader_program.uniforms.colour = (0., 0., 1.)
        self.segment_vertex_array1.draw()
        # del self.segment_vertex_array1
        # except:
        #    pass
        
        GL.glLineWidth(2.)
        shader_program.uniforms.colour = (0., 1., 1.)
        self.segment_vertex_array2.draw()

        GL.glLineWidth(2.)
        shader_program.uniforms.colour = (1., 0., 0.)
        # six.print_('colour', shader_program.uniforms.colour)
        self.segment_vertex_array3.draw()

        shader_program = self.shader_manager.rectangle_shader_program
        shader_program.bind()
        GL.glLineWidth(2.)
        shader_program.uniforms.colour = (1., 0., 1.)
        self.rectangle_vertex_array.draw()

        shader_program = self.shader_manager.centred_rectangle_shader_program
        shader_program.bind()
        GL.glLineWidth(2.)
        shader_program.uniforms.colour = (8., 3., .5)
        self.centred_rectangle_vertex_array.draw()

        shader_program = self.shader_manager.wide_line_shader_program
        shader_program.bind()
        shader_program.uniforms.line_width = 2
        shader_program.uniforms.colour = (1., 1., 1.)
        self.line_vertex_array1.draw()

        shader_program = self.shader_manager.stipple_line_shader_program
        shader_program.bind()
        shader_program.uniforms.line_width = 4
        shader_program.uniforms.stipple_factor = 4
        shader_program.uniforms.colour = (1., .8, .8)
        self.stipple_texture.bind()
        self.line_vertex_array2.draw()
        self.stipple_texture.unbind()

        shader_program.unbind()

    ##############################################

    def paint_textures(self):

        shader_program = self.shader_manager.texture_shader_program
        shader_program.bind()
        shader_program.uniforms.scale = float(2**16 - 1)
        self.texture_vertex_array1.draw()
        shader_program.uniforms.scale = float(2**8 - 1)
        self.texture_vertex_array2.draw()
        shader_program.unbind()

        shader_program = self.shader_manager.texture_label_shader_program
        # shader_program = self.shader_manager.texture_shader_program
        shader_program.bind()
        self.texture_vertex_array3.draw()
        shader_program.unbind()

    ##############################################

    def paint_text(self):

        shader_program = self.shader_manager.text_shader_program
        # shader_program.bind()
        # shader_program.uniforms. ...
        self.text_vertex_array.draw(shader_program)
Exemple #6
0
class GlWidget(GlWidgetBase):

    logger = logging.getLogger(__name__)
 
    ##############################################
    
    def __init__(self, parent):

        self.logger.debug('Initialise GlWidget')

        super(GlWidget, self).__init__(parent)

    ##############################################

    def wheelEvent(self, event):

        self.logger.debug('Wheel Event')

        return self.wheel_zoom(event)

    ##############################################

    def init_glortho2d(self):

        # Set max_area so as to correspond to max_binning zoom centered at the origin
        area_size = 10**3
        max_area = IntervalInt2D([-area_size, area_size], [-area_size, area_size])

        super(GlWidget, self).init_glortho2d(max_area, zoom_manager=None)

    ##############################################

    def initializeGL(self):

        self.logger.debug('Initialise GL')

        super(GlWidget, self).initializeGL()

        GL.glEnable(GL.GL_POINT_SMOOTH)
        GL.glEnable(GL.GL_LINE_SMOOTH)
        
        # self.qglClearColor(QtCore.Qt.black)
        # GL.glPointSize(5.)
        # GL.glLineWidth(3.)

        self._init_shader()
        self.create_vertex_array_objects()

    ##############################################

    def _init_shader(self):

        self.logger.debug('Initialise Shader')

        # try:
        import ShaderProgramesV3 as ShaderProgrames
        # except:
        # #? QtGui.QApplication.instance().quit()
        # import sys
        # sys.exit(1)
        self.shader_manager = ShaderProgrames.shader_manager
        self.position_shader_interface = ShaderProgrames.position_shader_program_interface

        # Fixme: share interface
        self._viewport_uniform_buffer = GlUniformBuffer()
        viewport_uniform_block = self.position_shader_interface.uniform_blocks.viewport
        self._viewport_uniform_buffer.bind_buffer_base(viewport_uniform_block.binding_point)

    ##############################################

    def update_model_view_projection_matrix(self):

        self.logger.debug('Update Model View Projection Matrix'
                         '\n' + str(self.glortho2d))

        # See also DSA http://www.opengl.org/registry/specs/EXT/direct_state_access.txt
        #!# GL3.glMatrixMode(GL3.GL_PROJECTION)
        #!# GL3.glLoadIdentity()
        #!# GLU.gluOrtho2D(* self.glortho2d.ortho2d_bounding_box())

        viewport_uniform_buffer_data = self.glortho2d.viewport_uniform_buffer_data(self.size())
        self.logger.debug('Viewport Uniform Buffer Data '
                          '\n' + str(viewport_uniform_buffer_data))
        self._viewport_uniform_buffer.set(viewport_uniform_buffer_data)

    ##############################################

    def create_vertex_array_objects(self):

        self.create_grid()
        self.create_textures()

    ##############################################

    def create_grid(self):

        step = 10
        x_min, x_max = -100, 100
        y_min, y_max = -100, 100
       
        segments = []
        for x in xrange(x_min, x_max +1, step):
            p1 = Point(x, y_min)
            p2 = Point(x, y_max)
            segments.append(Segment(p1, p2))
        for y in xrange(y_min, y_max +1, step):
            p1 = Point(y_min, y)
            p2 = Point(y_max, y)
            segments.append(Segment(p1, p2))

        self.grid_vertex_array = GlSegmentVertexArray(segments)
        self.grid_vertex_array.bind_to_shader(self.position_shader_interface.attributes.position)

    ##############################################

    def create_textures(self):

        depth = 16

        if depth == 8:
            data_type = np.uint8
        elif depth == 16:
            data_type = np.uint16
        intensity_max = 2**depth -1
        integer_internal_format = True
        
        height, width = 10, 10
        number_of_planes = 3
        data = np.zeros((height, width, number_of_planes),
                        data_type)
        for c in xrange(width):
            data[:,c,:] = int((float(c+1) / width) * intensity_max)
        # data[...] = intensity_max
        # print data
        self.image = data

        self.texture_vertex_array1 = GlTextureVertexArray(position=Point(0, 0), dimension=Offset(width, height), image=data,
                                                          integer_internal_format=integer_internal_format)
        self.texture_vertex_array1.bind_to_shader(self.shader_manager.texture_shader_program.interface.attributes)

        # self.texture_vertex_array2 = GlTextureVertexArray(position=Point(-5, -5), dimension=Offset(width, height))
        # self.texture_vertex_array2.set(image=data//2, integer_internal_format=integer_internal_format)
        # self.texture_vertex_array2.bind_to_shader(self.shader_manager.texture_shader_program.interface.attributes)

        from PIL import Image
        image = Image.open('flower.png')
        data = np.asarray(image, dtype=np.uint8)
        print(data.shape)
        self.texture_vertex_array2 = GlTextureVertexArray(position=Point(-5, -5), dimension=Offset(width, height))
        self.texture_vertex_array2.set(image=data)
        self.texture_vertex_array2.bind_to_shader(self.shader_manager.texture_shader_program.interface.attributes)

    ##############################################

    def paint(self):

        self.paint_grid()
        self.paint_textures()

        if LOG_GL_CALL:
            six.print_('\n', '='*100)
            for command in GL.called_commands():
                six.print_('\n', '-'*50)
                # six.print_(str(command))
                six.print_(command._command.prototype())
                six.print_(command.help())

    ##############################################

    def paint_grid(self):

        shader_program = self.shader_manager.fixed_shader_program
        shader_program.bind()

        GL.glLineWidth(2.)
        shader_program.uniforms.colour = (1., 1., 1.)
        self.grid_vertex_array.draw()

        #!# GL.glLineWidth(3.)
        #!# x = 25
        #!# GlFixedPipeline.draw_rectangle(-x, -x, x, x)

        shader_program.unbind()

    ##############################################

    def paint_textures(self):

        shader_program = self.shader_manager.texture_shader_program
        shader_program.bind()
        self.texture_vertex_array1.draw()
        self.texture_vertex_array2.draw()
        shader_program.unbind()
class GlWidget(GlWidgetBase3D):

    logger = logging.getLogger(__name__)

    ##############################################
    
    def __init__(self, parent):

        self.logger.debug('Initialise GlWidget')
        super(GlWidget, self).__init__(parent)

        self._scale = 1.

    ##############################################

    def initializeGL(self):

        self.logger.debug('Initialise GL')
        super(GlWidget, self).initializeGL()

        # self.qglClearColor(Qt.black)

        self._init_shader()
        self.create_vertex_array_objects()

    ##############################################

    def _init_shader(self):

        self.logger.debug('Initialise Shader')

        import ShaderProgrames3dV4 as ShaderProgrames
        self.shader_manager = ShaderProgrames.shader_manager
        self.basic_shader_interface = ShaderProgrames.basic_shader_program_interface

        # Fixme: share interface
        self._viewport_uniform_buffer = GlUniformBuffer()
        viewport_uniform_block = self.basic_shader_interface.uniform_blocks.viewport
        self._viewport_uniform_buffer.bind_buffer_base(viewport_uniform_block.binding_point)

    ##############################################

    def wheelEvent(self, event):

        self.logger.debug('Wheel Event')

        return self.wheel_zoom(event)
    ##############################################

    def wheel_zoom(self, event):

        # self._logger.debug('Wheel Zoom')
        if IS_PYQT5:
            delta = event.angleDelta().y()
        else:
            delta = int(event.delta())
        if delta == 120:
            self._scale *= 1.1
        else:
            self._scale /= 1.1
        self.update()

    ##############################################

    def update_model_view_projection_matrix(self):

        self.logger.debug('Update Model View Projection Matrix')

        model_matrix = identity()
        scale_factor = self._scale
        scale(model_matrix, scale_factor, scale_factor, scale_factor)
        rotate_x(model_matrix, self.rotation_x)
        rotate_y(model_matrix, self.rotation_y)
        model_view_matrix = look_at(model_matrix, (0, 0, 50), (0, 0, 0), (0, 1, 0))
        # model_view_matrix = model_matrix
        # Fixme: mat3 doesn't work
        normal_matrix = np.zeros((4, 4), dtype=np.float32)
        normal_matrix[:3,:3] = model_view_matrix[:3,:3] # without translation
        w = 100
        projection_matrix = ortho(-w, w, -w, w, -w, w)
        # projection_matrix = frustum(-2, 2, -2, 2, 1, 3)
        # projection_matrix = perspective(60, 16/9., 1, 3)
        model_view_projection_matrix = np.dot(projection_matrix, model_view_matrix)

        data = []
        for item in (
                     model_view_matrix,
                     normal_matrix,
                     model_view_projection_matrix,
                    ):
            data += list(item.transpose().flatten())

        viewport_array = np.array(data, dtype=np.float32)

        self._viewport_uniform_buffer.set(viewport_array)

    ##############################################

    def create_vertex_array_objects(self):

        self.create_object()

    ##############################################

    def create_object(self):

        # self.object_vertex_array = cube(1, 1, 1)
        # self.object_vertex_array = sphere(1)
        # self.object_vertex_array = torus(1)

        # stl_path = 'cube.stl'
        # stl_path = 'cardan.stl'
        # stl_path = 'teapot.stl'
        stl_path = 'cow.stl'
        # stl_path = 'wild-cow.stl'
        stl_parser = StlParser(os.path.join(os.path.dirname(__file__), 'stl', stl_path))
        self.object_vertex_array = stl_parser.to_vertex_array()
        self.object_vertex_array.bind_to_shader(self.basic_shader_interface.attributes)

    ##############################################

    def paint(self):

        self.paint_object()

        # six.print_('\n', '='*100)
        # for command in GL.called_commands():
        #     six.print_('\n', '-'*50)
        #     # six.print_(str(command))
        #     six.print_(command._command.prototype())
        #     six.print_(command.help())

    ##############################################

    def paint_object(self):

        GL.glPolygonMode(GL.GL_FRONT_AND_BACK, GL.GL_FILL)
        GL.glEnable(GL.GL_POLYGON_OFFSET_FILL)
        GL.glPolygonOffset(1., 1.)
        # shader_program = self.shader_manager.basic_shader_program
        shader_program = self.shader_manager.lighting_shader_program
        # shader_program.light.Position = (0, 0, 100, 1)
        shader_program.bind()
        self.object_vertex_array.draw()
        GL.glDisable(GL.GL_POLYGON_OFFSET_FILL)

        GL.glPolygonMode(GL.GL_FRONT_AND_BACK, GL.GL_LINE)
        GL.glLineWidth(1.)
        shader_program = self.shader_manager.fixed_colour_shader_program
        shader_program.bind()
        self.object_vertex_array.draw()

        shader_program.unbind()
class GlWidget(GlWidgetBase):

    _logger = _module_logger.getChild('GlWidget')

    ##############################################

    def __init__(self, parent):

        self._logger.debug('Initialise GlWidget')
        
        super(GlWidget, self).__init__(parent)
        
        self._application = QtWidgets.QApplication.instance()
        
        self._previous_position = None
        self._previous_position_screen = None
        
        self._painter_manager = None
        
        self.x_step = 1000
        self.y_step = 1000
        self.zoom_step = 2
        self.rotation_step = 10
        
        # Fixme
        self._ready = False

    ##############################################

    def init_tools(self):

        pass
        # from .Cropper import Cropper
        # self.cropper = Cropper(self)

    ##############################################

    def init_glortho2d(self):

        # Set max_area so as to correspond to max_binning zoom centered at the origin
        # Fixme: cf. last level
        area_size = 10**12
        max_area = IntervalInt2D([-area_size, area_size], [-area_size, area_size])
        
        self._zoom_manager = ZoomManager()
        self.glortho2d = RotatedOrtho2D(max_area, self._zoom_manager, self, bottom_up_y_axis=False)
        
        self.scene = GraphicScene(self.glortho2d)

    ##############################################

    def initializeGL(self):

        self._logger.debug('Initialise GL')
        super(GlWidget, self).initializeGL()
        self._init_shader()
        self._ready = False

    ##############################################

    def _init_shader(self):

        self._logger.debug('Initialise Shader')

        from PyGeoPortail.GraphicEngine import ShaderProgrames as ShaderProgrames
        self.shader_manager = ShaderProgrames.shader_manager
        self.position_shader_interface = ShaderProgrames.program_interfaces['position_shader_program_interface']

        # Fixme: share interface
        self._viewport_uniform_buffer = GlUniformBuffer()
        viewport_uniform_block = self.position_shader_interface.uniform_blocks.viewport
        self._viewport_uniform_buffer.bind_buffer_base(viewport_uniform_block.binding_point)

    ##############################################

    def update_model_view_projection_matrix(self):

        self._logger.debug(str(self.glortho2d))
        viewport_uniform_buffer_data = self.glortho2d.viewport_uniform_buffer_data(self.size())
        self._viewport_uniform_buffer.set(viewport_uniform_buffer_data)

    ##############################################

    def zoom_one(self):

        self.glortho2d.zoom_at_center(1.)
        self.update_painter_manager()

    ##############################################

    def zoom_at_with_scale(self, x, y, zoom_factor):

        location = Vector(x, y)
        self.glortho2d.zoom_at_with_scale(location, zoom_factor)
        self.update_painter_manager()

    ##############################################

    def zoom_at(self, x, y):

        location = Vector(x, y)
        self.glortho2d.zoom_at(location)
        self.update_painter_manager()

    ##############################################

    def zoom_interval(self, interval):

        self.glortho2d.zoom_interval(interval)
        self.update_painter_manager()

    ##############################################

    def translate_x(self, dx):

        self.glortho2d.translate(dx, XAXIS)
        self.update_painter_manager()

    ##############################################

    def translate_y(self, dy):

        self.glortho2d.translate(dy, YAXIS)
        self.update_painter_manager()

    ##############################################

    def translate_xy(self, dxy):

        self.glortho2d.translate(dxy, XYAXIS)
        self.update_painter_manager()

    ##############################################

    def wheel_zoom(self, event):

        self._logger.debug('Wheel Zoom')
        
        position = self.window_to_gl_coordinate(event)
        zoom_factor = self.glortho2d.zoom_manager.zoom_factor
        
        delta = event.angleDelta().y()
        if delta == 120:
            zoom_factor *= self.zoom_step
        else:
            zoom_factor /= self.zoom_step
        
        self.glortho2d.zoom_at_with_scale(position, zoom_factor)
        self.update_painter_manager()

    ##############################################

    def wheel_rotate(self, event):

        self._logger.debug('Wheel Rotate')
        
        delta = event.angleDelta().y()
        rotation_step = self.rotation_step
        if delta == 120:
            rotation_step *= -1
        self.glortho2d.rotate(rotation_step)
        self.update_painter_manager()

    ##############################################

    def update_painter_manager(self):

        self._logger.debug('')
        if self._ready:
            with GL.error_checker():
                self._painter_manager.update()

    ##############################################

    # @opengl_context
    def update(self):

        self._logger.debug('')
        self.makeCurrent()
        self.update_model_view_projection_matrix()
        QOpenGLWidget.update(self)

        # self.emit(QtCore.SIGNAL('update()'))
        # if self._ready:
        #     self._update_zoom_status()

    ##############################################

    def paint(self):

        if self._ready:
            with GL.error_checker():
                self._painter_manager.paint()

    ##############################################

    def event_position(self, event):

        """ Convert mouse coordinate
        """

        self._logger.info("{} {}".format(event.x(), event.y()))
        return np.array((event.x(), event.y()), dtype=np.int) # int for subtraction

    ##############################################

    def _set_previous_position(self, position, position_screen):

        self._previous_position = position
        self._previous_position_screen = position_screen

    ##############################################

    def mousePressEvent(self, event):

        self._logger.info("")

        if not (event.buttons() & QtCore.Qt.LeftButton):
            return

        tool_bar = self._application.main_window.tool_bar
        current_tool = tool_bar.current_tool()
        if current_tool in (tool_bar.crop_tool_action,):
            scene_match = self.scene.mousePressEvent(event)
            if not scene_match:
                if current_tool is tool_bar.crop_tool_action:
                    self.cropper.begin(event) # Fixme: call mousePressEvent
        else:
            if current_tool is tool_bar.position_tool_action:
                position = self.window_to_gl_coordinate(event, round_to_integer=False)
                self.show_coordinate(position)
                self._set_previous_position(position, self.event_position(event))

    ##############################################

    def mouseReleaseEvent(self, event):

        self._logger.info("")

        button = event.button()
        if button & QtCore.Qt.RightButton:
            self.contextual_menu.exec_(event.globalPos())
        elif button & QtCore.Qt.LeftButton:
            tool_bar = self._application.main_window.tool_bar
            current_tool = tool_bar.current_tool()
            # if current_tool is tool_bar.position_tool_action:
            #     position = self.window_to_gl_coordinate(event, round_to_integer=False)
            #     dxy = self._previous_position - position
            #     self.translate_xy(dxy)
            #     self._set_previous_position(position)
            if current_tool is tool_bar.crop_tool_action:
                self.cropper.end(event) # Fixme: call mouseReleaseEvent
                self._logger.info(str(self.cropper.interval))

    ##############################################

    def wheelEvent(self, event):

        if event.modifiers() == QtCore.Qt.ControlModifier:
            return self.wheel_rotate(event)
        else:
            return self.wheel_zoom(event)

    ##############################################

    def mouseMoveEvent(self, event):

        self._logger.info("")

        if not (event.buttons() & QtCore.Qt.LeftButton):
            return

        tool_bar = self._application.main_window.tool_bar
        current_tool = tool_bar.current_tool()
        if current_tool is tool_bar.position_tool_action:
            position_screen = self.event_position(event)
            dxy_screen = self._previous_position_screen - position_screen
            # Fixme: if out of viewer position = -1exxx
            position = self.window_to_gl_coordinate(event, round_to_integer=False)
            dxy = self._previous_position - position
            # dxy *= [1, -1]
            self._logger.info("{} {} / {} {}".format(dxy_screen[0], dxy_screen[1], int(dxy[0]), int(dxy[0])))
            dxy_screen *= self.glortho2d.parity_display_scale
            self.translate_xy(dxy_screen)
            self._set_previous_position(position, position_screen)
            self.show_coordinate(position)
        elif current_tool is tool_bar.crop_tool_action:
            self.cropper.update(event) # Fixme: call mouseMoveEvent

    ##############################################

    def show_coordinate(self, position):

        x, y = position
        self._application.main_window.status_bar.update_coordinate_status(x, y)
Exemple #9
0
class GlWidget(GlWidgetBase):

    _logger = _module_logger.getChild('GlWidget')

    ##############################################

    def __init__(self, parent, main_window):

        self._logger.debug('Initialise GlWidget')
        super(GlWidget, self).__init__(parent)

        self._application = QtGui.QApplication.instance()
        self._main_window = main_window  # self._application.main_window # not yet initialised

        self.x_step = 5  # mm
        self.y_step = 5  # mm
        self.zoom_step = 1.10  # must be float

    ##############################################

    def init_glortho2d(self):

        # Set max_area so as to correspond to max_binning zoom centered at the origin
        a0_width = 840  # mm
        a0_height = 1189
        max_area = IntervalInt2D([0, a0_height], [0, a0_height])
        max_area.enlarge(a0_height)

        super(GlWidget, self).init_glortho2d(max_area, zoom_manager=None)

    ##############################################

    def initializeGL(self):

        self._logger.debug('Initialise GL')
        super(GlWidget, self).initializeGL()

        GL.glEnable(GL.GL_POINT_SMOOTH)  #compat#
        GL.glEnable(GL.GL_LINE_SMOOTH)  #compat#

        self._init_shader()
        self._paint_page = False

    ##############################################

    def _init_shader(self):

        self._logger.debug('Initialise Shader')

        import ShaderProgramesV4 as ShaderProgrames
        self.shader_manager = ShaderProgrames.shader_manager
        self.position_shader_interface = ShaderProgrames.position_shader_program_interface
        self.rule_shader_interface = ShaderProgrames.rule_shader_program_interface
        self.text_shader_interface = ShaderProgrames.text_shader_program_interface

        # Fixme: share interface
        self._viewport_uniform_buffer = GlUniformBuffer()
        viewport_uniform_block = self.position_shader_interface.uniform_blocks.viewport
        self._viewport_uniform_buffer.bind_buffer_base(
            viewport_uniform_block.binding_point)

    ##############################################

    def update_model_view_projection_matrix(self):

        self._logger.debug('Update Model View Projection Matrix'
                           '\n' + str(self.glortho2d))

        viewport_uniform_buffer_data = self.glortho2d.viewport_uniform_buffer_data(
            self.size())
        self._logger.debug('Viewport Uniform Buffer Data '
                           '\n' + str(viewport_uniform_buffer_data))
        self._viewport_uniform_buffer.set(viewport_uniform_buffer_data)

    ##############################################

    def _create_page_layout(self, width, height):

        self._page_width = width
        self._page_height = height

        # (page_x_min, page_y_min,
        #  text_width, text_height) = map(sp2mm,
        #                                 (page_bounding_box.x.inf,
        #                                  page_bounding_box.y.inf,
        #                                  page_bounding_box.x.length(),
        #                                  page_bounding_box.y.length(),
        #                                  ))

        rectangles = (Rectangle(Point(0, 0), Offset(width, height)), )
        self.rectangle_vertex_array = GlRectangleVertexArray(rectangles)
        self.rectangle_vertex_array.bind_to_shader(
            self.position_shader_interface.attributes.position)

        segments = []

        grid_spacing = 5
        x = grid_spacing
        while x < width:
            p1 = Point(x, 0)
            p2 = Point(x, height)
            segments.append(Segment(p1, p2))
            x += grid_spacing

        y = grid_spacing
        while y < height:
            p1 = Point(0, y)
            p2 = Point(width, y)
            segments.append(Segment(p1, p2))
            y += grid_spacing

        self.grid_vertex_array = GlSegmentVertexArray(segments)
        self.grid_vertex_array.bind_to_shader(
            self.position_shader_interface.attributes.position)

    ##############################################

    def update_dvi(self, dvi_machine):

        self._logger.info('Update DVI')

        self._text_vertex_arrays = []
        for font_id, glyphs in dvi_machine.glyphs.iteritems():
            texture_font = dvi_machine.texture_fonts[font_id]
            # texture_font.atlas.save(texture_font.name + '.png')
            font_atlas_texture = ImageTexture(texture_font.atlas.data)
            positions, bounding_boxes, texture_coordinates, colours = glyphs
            items = (positions, texture_coordinates, colours)
            text_vertex_array = TextVertexArray(font_atlas_texture, items)
            text_vertex_array.bind_to_shader(
                self.text_shader_interface.attributes)
            self._text_vertex_arrays.append(text_vertex_array)

        #     for glyph in glyphs:
        #         glyph_bounding_box, char_bounding_box, glyph_texture_coordinates = glyph
        #         x, y, width, height = char_bounding_box
        #         rectangles.append(Rectangle(Point(x, y), Offset(width, height)))

        # self._char_bounding_box_vertex_array = GlRectangleVertexArray(rectangles)
        # self._char_bounding_box_vertex_array.bind_to_shader(self.position_shader_interface.attributes.position)

        self._rule_vertex_array = RuleVertexArray(
            (dvi_machine.rule_positions, dvi_machine.rule_dimensions,
             dvi_machine.rule_colours))
        self._rule_vertex_array.bind_to_shader(
            self.rule_shader_interface.attributes)

        width = dvi_machine.current_opcode_program.width
        height = dvi_machine.current_opcode_program.height
        if not width or not height:
            first_page = dvi_machine.dvi_program[0]
            width, height = first_page.width, first_page.height
        if not width or not height:
            self._logger.warning('Page size is null')
            width, height = 210, 297  # use A4
        self._create_page_layout(width, height)

        self._logger.info('update DVI done')

        self._paint_page = True

        self.fit_document()

    ##############################################

    def update(self):

        super(GlWidget, self).update()
        if self._paint_page:
            self._update_zoom_status()

    ##############################################

    def resizeGL(self, width, height):

        super(GlWidget, self).resizeGL(width, height)

        dpi = self._application.platform.screens[0].dpi[0]
        self._width_widget_mm = width / float(dpi) * 25.4

    ##############################################

    def _update_zoom_status(self):

        # xdpyinfo:
        #   dimensions:    1600x900 pixels (423x238 millimeters) # Wrong !!!
        #   resolution:    96x96 dots per inch
        # monitor-edid:
        #   Screen size: 30.9 cm x 17.4 cm (13.96 inches, aspect ratio 16/9 = 1.78)
        # 1600/(309./25.4) -> 131 dpi

        # gl_zoom = self.glortho2d.zoom_manager.zoom_factor
        area = self.glortho2d.viewport_area.area
        zoom = self._width_widget_mm / area.x.length()
        self._main_window.status_bar.update_zoom_status(zoom)

    ##############################################

    def paint(self):

        self._logger.info('')
        # Clear the buffer using white colour (white paper)
        GL.glClearColor(1, 1, 1, 1)
        GL.glClear(GL.GL_COLOR_BUFFER_BIT)
        if self._paint_page:
            self._paint_page_layout()
            self._paint_text()

    ##############################################

    def _paint_page_layout(self):

        self._logger.debug('')
        shader_program = self.shader_manager.rectangle_shader_program
        shader_program.bind()
        # GL.glLineWidth(1.)
        shader_program.uniforms.colour = (.0, 0., .0)
        self.rectangle_vertex_array.draw()

        if False:
            shader_program = self.shader_manager.fixed_shader_program
            shader_program.bind()
            # GL.glLineWidth(.1) # Fixme: do in shader ...
            shader_program.uniforms.colour = (.0, .0, .1)
            self.grid_vertex_array.draw()
            shader_program.unbind()

    ##############################################

    def _paint_text(self):

        shader_program = self.shader_manager.text_shader_program
        # shader_program.bind()
        # shader_program.uniforms. ...
        for text_vertex_array in self._text_vertex_arrays:
            self._logger.debug('paint text')
            text_vertex_array.draw(shader_program)
        # shader_program.unbind()

        if False:
            self._logger.debug('Paint char bounding boxes')
            shader_program = self.shader_manager.rectangle_shader_program
            shader_program.bind()
            # GL.glLineWidth(1.)
            shader_program.uniforms.colour = (1., 0., 0.)
            self._char_bounding_box_vertex_array.draw()

        self._logger.debug('Paint rules')
        # Fixme: anti-alias
        shader_program = self.shader_manager.rule_shader_program
        shader_program.bind()
        self._rule_vertex_array.draw()

    ##############################################

    def wheelEvent(self, event):

        self._logger.debug('Wheel Event')
        return self.wheel_zoom(event)

    ##############################################

    def mousePressEvent(self, event):

        if event.buttons() & QtCore.Qt.LeftButton:
            self._show_coordinate(event)

    ##############################################

    def mouseMoveEvent(self, event):

        self._show_coordinate(event)

    ##############################################

    def _show_coordinate(self, event):

        coordinate = self.window_to_gl_coordinate(event)
        x, y = coordinate
        y = self._page_height - y
        self._main_window.status_bar.update_coordinate_status(x, y)

    ##############################################

    def fit_width(self):

        if self._paint_page:
            self.glortho2d.fit_axis(self._page_width, XAXIS)
            self.update()

    ##############################################

    def fit_document(self):

        if self._paint_page:
            interval = IntervalInt2D((0, self._page_width),
                                     (0, self._page_height))
            interval.enlarge(10)  # mm
            self.zoom_interval(interval)

    ##############################################

    def translate_x(self, dx):

        area = self.glortho2d.viewport_area.area
        # Fixme: cf. check_axis_interval
        if ((dx > 0 and area.x.sup + dx <= self._page_width)
                or (dx < 0 and area.x.inf + dx >= 0)):
            self.glortho2d.translate(dx, XAXIS)
            self.update()

    ##############################################

    def translate_y(self, dy):

        area = self.glortho2d.viewport_area.area
        # Fixme: cf. check_axis_interval
        if ((dy > 0 and area.y.sup + dy <= self._page_height)
                or (dy < 0 and area.y.inf + dy >= 0)):
            self.glortho2d.translate(dy, YAXIS)
            self.update()

    ##############################################

    def zoom_in_out(self, direction):

        zoom_factor = self.glortho2d.zoom_manager.zoom_factor
        if direction > 0:
            zoom_factor *= self.zoom_step
        else:
            zoom_factor /= self.zoom_step
        self.glortho2d.zoom_at_center(zoom_factor)
        self.update()