示例#1
0
    def paintGL(self):
        """Paint the scene."""
        # pass if the framebuffer isn't complete yet or if not initialized
        if not (gl.glCheckFramebufferStatus(
                gl.GL_FRAMEBUFFER) == gl.GL_FRAMEBUFFER_COMPLETE
                and self.isVisible() and self.initialized):
            return

        gl.glClearColor(0, 0, 0, 0)
        gl.glClear(gl.GL_COLOR_BUFFER_BIT)
        # Set the viewport and clear the framebuffer

        # --- Draw the ND in its viewport ----
        gl.glViewport(*self.ndviewport)
        self.color_shader.use()
        self.arcs.draw()

        self.ownship.draw()
        self.mask.draw()
        self.edge.draw()

        self.ticks.draw()

        # Select the text shader
        self.text_shader.use()
        self.font.use()
        self.font.set_block_size((0, 0))
        self.globaldata.set_vertex_modifiers(VERTEX_IS_GLXY, True)
        self.ticklbls.draw()

        self.globaldata.set_vertex_modifiers(VERTEX_IS_GLXY, False)
        self.spdlabel_text.draw()
        self.spdlabel_val.draw()

        # --- Draw the MCP in its viewport ---
        gl.glViewport(*self.mcpviewport)
        self.mcp_tex_shader.use()
        gl.glActiveTexture(gl.GL_TEXTURE0 + 0)
        gl.glBindTexture(gl.GL_TEXTURE_2D, self.mcp_texture)
        self.mcp.draw()

        gl.glBindTexture(gl.GL_TEXTURE_2D, self.btn_tex)
        self.btn_leds.draw()

        if self.updownpos is not None:
            self.mcp_col_shader.use()
            gl.glVertexAttrib2f(2, *self.updownpos)
            self.updown.draw()
            gl.glVertexAttrib2f(2, 0.0, 0.0)

        self.mcp_txt_shader.use()
        gl.glActiveTexture(gl.GL_TEXTURE0 + 0)
        gl.glBindTexture(gl.GL_TEXTURE_2D_ARRAY, self.lcd_tex)
        self.mcp_text.draw()

        # Unbind everything
        RenderObject.unbind_all()
        gl.glUseProgram(0)
示例#2
0
    def paintGL(self):
        """Paint the scene."""
        # pass if the framebuffer isn't complete yet or if not initialized
        if not (gl.glCheckFramebufferStatus(gl.GL_FRAMEBUFFER) == gl.GL_FRAMEBUFFER_COMPLETE and self.isVisible() and self.initialized):
            return

        gl.glClearColor(0, 0, 0, 0)
        gl.glClear(gl.GL_COLOR_BUFFER_BIT)
        # Set the viewport and clear the framebuffer

        # --- Draw the ND in its viewport ----
        gl.glViewport(*self.ndviewport)
        self.color_shader.use()
        self.arcs.draw()

        self.ownship.draw()
        self.mask.draw()
        self.edge.draw()

        self.ticks.draw()

        # Select the text shader
        self.text_shader.use()
        self.font.use()
        self.font.set_block_size((0, 0))
        self.globaldata.set_vertex_modifiers(VERTEX_IS_GLXY, True)
        self.ticklbls.draw()

        self.globaldata.set_vertex_modifiers(VERTEX_IS_GLXY, False)
        self.spdlabel_text.draw()
        self.spdlabel_val.draw()

        # --- Draw the MCP in its viewport ---
        gl.glViewport(*self.mcpviewport)
        self.mcp_tex_shader.use()
        gl.glActiveTexture(gl.GL_TEXTURE0 + 0)
        gl.glBindTexture(gl.GL_TEXTURE_2D, self.mcp_texture)
        self.mcp.draw()

        gl.glBindTexture(gl.GL_TEXTURE_2D, self.btn_tex)
        self.btn_leds.draw()

        if self.updownpos is not None:
            self.mcp_col_shader.use()
            gl.glVertexAttrib2f(2, *self.updownpos)
            self.updown.draw()
            gl.glVertexAttrib2f(2, 0.0, 0.0)

        self.mcp_txt_shader.use()
        gl.glActiveTexture(gl.GL_TEXTURE0 + 0)
        gl.glBindTexture(gl.GL_TEXTURE_2D_ARRAY, self.lcd_tex)
        self.mcp_text.draw()

        # Unbind everything
        RenderObject.unbind_all()
        gl.glUseProgram(0)
示例#3
0
    def paintGL(self):
        """Paint the scene."""
        # pass if the framebuffer isn't complete yet or if not initialized
        if not (gl.glCheckFramebufferStatus(gl.GL_FRAMEBUFFER) == gl.GL_FRAMEBUFFER_COMPLETE and self.isVisible()):
            return

        # Set the viewport and clear the framebuffer
        gl.glViewport(*self.viewport)
        gl.glClear(gl.GL_COLOR_BUFFER_BIT)
        gl.glVertexAttrib1f(ATTRIB_OFFSETY, 0.0)

        self.color_shader.use()

        self.fixed.draw()

        gl.glEnable(gl.GL_CLIP_DISTANCE0)
        gl.glEnable(gl.GL_CLIP_DISTANCE1)
        gl.glVertexAttrib1f(ATTRIB_OFFSETY, self.y_offset)
        self.scale.draw()

        self.text_shader.use()
        self.font.use()
        self.font.set_char_size(self.scaletxt.char_size)
        self.font.set_block_size(self.scaletxt.block_size)
        self.scaletxt.draw()

        gl.glDisable(gl.GL_CLIP_DISTANCE1)
        self.font.set_char_size(self.aclbls.char_size)
        self.font.set_block_size(self.aclbls.block_size)
        self.aclbls.draw()
        gl.glDisable(gl.GL_CLIP_DISTANCE0)

        gl.glVertexAttrib1f(ATTRIB_OFFSETY, 0.0)
        self.font.set_char_size(self.rwylbl.char_size)
        self.font.set_block_size(self.rwylbl.block_size)
        self.rwylbl.draw()
        self.timelbl.draw()
        # Unbind everything
        RenderObject.unbind_all()
        gl.glUseProgram(0)
示例#4
0
    def paintGL(self):
        """Paint the scene."""
        # pass if the framebuffer isn't complete yet or if not initialized
        if not (gl.glCheckFramebufferStatus(
                gl.GL_FRAMEBUFFER) == gl.GL_FRAMEBUFFER_COMPLETE
                and self.initialized and self.isVisible()):
            return

        # Set the viewport and clear the framebuffer
        gl.glViewport(*self.viewport)
        gl.glClear(gl.GL_COLOR_BUFFER_BIT)

        # Send the (possibly) updated global uniforms to the buffer
        self.globaldata.set_vertex_scale_type(VERTEX_IS_LATLON)

        # --- DRAW THE MAP AND COASTLINES ---------------------------------------------
        # Map and coastlines: don't wrap around in the shader
        self.globaldata.enable_wrap(False)

        if self.show_map:
            # Select the texture shader
            self.texture_shader.use()

            # Draw map texture
            gl.glActiveTexture(gl.GL_TEXTURE0 + 0)
            gl.glBindTexture(gl.GL_TEXTURE_2D, self.map_texture)
            self.map.draw()

        # Select the non-textured shader
        self.color_shader.use()

        # Draw coastlines
        if self.show_coast:
            if self.wrapdir == 0:
                # Normal case, no wrap around
                self.coastlines.draw(first_vertex=0,
                                     vertex_count=self.vcount_coast)
            else:
                self.coastlines.bind()
                wrapindex = np.uint32(self.coastindices[int(self.wraplon) +
                                                        180])
                if self.wrapdir == 1:
                    gl.glVertexAttrib1f(ATTRIB_LON, 360.0)
                    self.coastlines.draw(first_vertex=0,
                                         vertex_count=wrapindex)
                    gl.glVertexAttrib1f(ATTRIB_LON, 0.0)
                    self.coastlines.draw(first_vertex=wrapindex,
                                         vertex_count=self.vcount_coast -
                                         wrapindex)
                else:
                    gl.glVertexAttrib1f(ATTRIB_LON, -360.0)
                    self.coastlines.draw(first_vertex=wrapindex,
                                         vertex_count=self.vcount_coast -
                                         wrapindex)
                    gl.glVertexAttrib1f(ATTRIB_LON, 0.0)
                    self.coastlines.draw(first_vertex=0,
                                         vertex_count=wrapindex)

        # --- DRAW PREVIEW SHAPE (WHEN AVAILABLE) -----------------------------
        self.polyprev.draw()

        # --- DRAW CUSTOM SHAPES (WHEN AVAILABLE) -----------------------------
        self.allpolys.draw()

        # --- DRAW THE SELECTED AIRCRAFT ROUTE (WHEN AVAILABLE) ---------------
        if self.show_traf:
            self.route.draw()
            self.cpalines.draw()

        # --- DRAW AIRPORT DETAILS (RUNWAYS, TAXIWAYS, PAVEMENTS) -------------
        self.runways.draw()
        self.thresholds.draw()
        if self.zoom >= 1.0:
            for idx in self.apt_inrange:
                self.taxiways.draw(first_vertex=idx[0], vertex_count=idx[1])
                self.pavement.draw(first_vertex=idx[2], vertex_count=idx[3])

        # --- DRAW THE INSTANCED AIRCRAFT SHAPES ------------------------------
        # update wrap longitude and direction for the instanced objects
        self.globaldata.enable_wrap(True)

        # PZ circles only when they are bigger than the A/C symbols
        if self.naircraft > 0 and self.show_traf and self.show_pz and self.zoom >= 0.15:
            self.globaldata.set_vertex_scale_type(VERTEX_IS_METERS)
            self.protectedzone.draw(n_instances=self.naircraft)

        self.globaldata.set_vertex_scale_type(VERTEX_IS_SCREEN)

        # Draw traffic symbols
        if self.naircraft > 0 and self.show_traf:
            self.ac_symbol.draw(n_instances=self.naircraft)

        if self.zoom >= 0.5:
            nairports = self.nairports[2]
        elif self.zoom >= 0.25:
            nairports = self.nairports[1]
        else:
            nairports = self.nairports[0]

        if self.zoom >= 3:
            nwaypoints = self.nwaypoints
        else:
            nwaypoints = self.nnavaids

        # Draw waypoint symbols
        if self.show_wpt:
            self.waypoints.bind()
            gl.glVertexAttrib4Nub(ATTRIB_COLOR, *(lightblue3 + (255, )))
            self.waypoints.draw(n_instances=nwaypoints)

        # Draw airport symbols
        if self.show_apt:
            self.airports.bind()
            gl.glVertexAttrib4Nub(ATTRIB_COLOR, *(lightblue3 + (255, )))
            self.airports.draw(n_instances=nairports)

        if self.do_text:
            self.text_shader.use()
            self.font.use()

            if self.show_apt:
                self.font.set_char_size(self.aptlabels.char_size)
                self.font.set_block_size(self.aptlabels.block_size)
                self.aptlabels.bind()
                gl.glVertexAttrib4Nub(ATTRIB_COLOR, *(lightblue4 + (255, )))
                self.aptlabels.draw(n_instances=nairports)
            if self.show_wpt:
                self.font.set_char_size(self.wptlabels.char_size)
                self.font.set_block_size(self.wptlabels.block_size)
                self.wptlabels.bind()
                gl.glVertexAttrib4Nub(ATTRIB_COLOR, *(lightblue4 + (255, )))
                self.wptlabels.draw(n_instances=nwaypoints)

            if self.show_traf and self.route.vertex_count > 1:
                gl.glVertexAttrib4Nub(ATTRIB_COLOR, *(magenta + (255, )))
                self.font.set_char_size(self.routelbl.char_size)
                self.font.set_block_size(self.routelbl.block_size)
                self.routelbl.draw()

            if self.naircraft > 0 and self.show_traf and self.show_lbl:
                self.font.set_char_size(self.aclabels.char_size)
                self.font.set_block_size(self.aclabels.block_size)
                self.aclabels.draw(n_instances=self.naircraft)

        # SSD
        if self.ssd_all or len(self.ssd_ownship) > 0:
            self.ssd_shader.use()
            gl.glUniform3f(self.ssd_shader.loc_vlimits, 4e4, 25e4, 500.0)
            gl.glUniform1i(self.ssd_shader.loc_nac, self.naircraft)
            if self.ssd_all:
                self.ssd.draw(first_vertex=0,
                              vertex_count=self.naircraft,
                              n_instances=self.naircraft)
            else:
                self.ssd.draw(first_vertex=self.ssd_ownship[-1],
                              vertex_count=1,
                              n_instances=self.naircraft)

        # Unbind everything
        RenderObject.unbind_all()
        gl.glUseProgram(0)
示例#5
0
    def create_objects(self):
        if not self.isValid():
            self.invalid_count += 1
            print 'Radarwidget: Context not valid in create_objects, count=%d' % self.invalid_count
            QTimer.singleShot(100, self.create_objects)
            return

        # Make the radarwidget context current, necessary when create_objects is not called from initializeGL
        self.makeCurrent()

        # Initialize font for radar view with specified settings
        self.font = Font()
        self.font.create_font_array(char_height=text_texture_size,
                                    font_family=font_family,
                                    font_weight=font_weight)
        self.font.init_shader(self.text_shader)

        # Load and bind world texture
        max_texture_size = gl.glGetIntegerv(gl.GL_MAX_TEXTURE_SIZE)
        print 'Maximum supported texture size: %d' % max_texture_size
        for i in [16384, 8192, 4096]:
            if max_texture_size >= i:
                fname = 'data/graphics/world.%dx%d.dds' % (i, i / 2)
                print 'Loading texture ' + fname
                self.map_texture = self.bindTexture(fname)
                break

        # Create initial empty buffers for aircraft position, orientation, label, and color
        self.achdgbuf = create_empty_buffer(MAX_NAIRCRAFT * 4,
                                            usage=gl.GL_STREAM_DRAW)
        self.aclatbuf = create_empty_buffer(MAX_NAIRCRAFT * 4,
                                            usage=gl.GL_STREAM_DRAW)
        self.aclonbuf = create_empty_buffer(MAX_NAIRCRAFT * 4,
                                            usage=gl.GL_STREAM_DRAW)
        self.acaltbuf = create_empty_buffer(MAX_NAIRCRAFT * 4,
                                            usage=gl.GL_STREAM_DRAW)
        self.actasbuf = create_empty_buffer(MAX_NAIRCRAFT * 4,
                                            usage=gl.GL_STREAM_DRAW)
        self.accolorbuf = create_empty_buffer(MAX_NAIRCRAFT * 3,
                                              usage=gl.GL_STREAM_DRAW)
        self.aclblbuf = create_empty_buffer(MAX_NAIRCRAFT * 24,
                                            usage=gl.GL_STREAM_DRAW)
        self.confcpabuf = create_empty_buffer(MAX_NCONFLICTS * 16,
                                              usage=gl.GL_STREAM_DRAW)
        self.polyprevbuf = create_empty_buffer(MAX_POLYPREV_SEGMENTS * 8,
                                               usage=gl.GL_DYNAMIC_DRAW)
        self.allpolysbuf = create_empty_buffer(MAX_ALLPOLYS_SEGMENTS * 16,
                                               usage=gl.GL_DYNAMIC_DRAW)
        self.routebuf = create_empty_buffer(MAX_ROUTE_LENGTH * 8,
                                            usage=gl.GL_DYNAMIC_DRAW)
        self.routewplatbuf = create_empty_buffer(MAX_ROUTE_LENGTH * 4,
                                                 usage=gl.GL_DYNAMIC_DRAW)
        self.routewplonbuf = create_empty_buffer(MAX_ROUTE_LENGTH * 4,
                                                 usage=gl.GL_DYNAMIC_DRAW)
        self.routelblbuf = create_empty_buffer(MAX_ROUTE_LENGTH * 12,
                                               usage=gl.GL_DYNAMIC_DRAW)

        # ------- Map ------------------------------------
        self.map = RenderObject(gl.GL_TRIANGLE_FAN, vertex_count=4)
        mapvertices = np.array([(-90.0, 540.0), (-90.0, -540.0),
                                (90.0, -540.0), (90.0, 540.0)],
                               dtype=np.float32)
        texcoords = np.array([(1, 3), (1, 0), (0, 0), (0, 3)],
                             dtype=np.float32)
        self.map.bind_attrib(ATTRIB_VERTEX, 2, mapvertices)
        self.map.bind_attrib(ATTRIB_TEXCOORDS, 2, texcoords)

        # ------- Coastlines -----------------------------
        self.coastlines = RenderObject(gl.GL_LINES)
        coastvertices, coastindices = load_coastlines()
        self.coastlines.bind_attrib(ATTRIB_VERTEX, 2, coastvertices)
        self.coastlines.bind_attrib(ATTRIB_COLOR,
                                    3,
                                    np.array(lightblue2, dtype=np.uint8),
                                    datatype=gl.GL_UNSIGNED_BYTE,
                                    normalize=True,
                                    instance_divisor=1)
        self.vcount_coast = len(coastvertices)
        self.coastindices = coastindices
        del coastvertices

        # ------- Runways --------------------------------
        self.runways = RenderObject(gl.GL_TRIANGLES)
        self.runways.bind_attrib(ATTRIB_VERTEX, 2, self.vbuf_runways)
        self.runways.bind_attrib(ATTRIB_COLOR,
                                 3,
                                 np.array(grey, dtype=np.uint8),
                                 datatype=gl.GL_UNSIGNED_BYTE,
                                 normalize=True,
                                 instance_divisor=1)
        self.runways.set_vertex_count(len(self.vbuf_runways) / 2)

        #---------Runway Thresholds-----------------------
        self.thresholds = RenderObject(gl.GL_TRIANGLES)
        self.thresholds.bind_attrib(ATTRIB_VERTEX, 2, self.vbuf_rwythr)
        self.thresholds.bind_attrib(ATTRIB_COLOR,
                                    3,
                                    np.array(white, dtype=np.uint8),
                                    datatype=gl.GL_UNSIGNED_BYTE,
                                    normalize=True,
                                    instance_divisor=1)
        self.thresholds.set_vertex_count(len(self.vbuf_rwythr) / 2)

        # ------- Taxiways -------------------------------
        self.taxiways = RenderObject(gl.GL_TRIANGLES)
        self.taxiways.bind_attrib(ATTRIB_VERTEX, 2, self.vbuf_asphalt)
        self.taxiways.bind_attrib(ATTRIB_COLOR,
                                  3,
                                  np.array(grey, dtype=np.uint8),
                                  datatype=gl.GL_UNSIGNED_BYTE,
                                  normalize=True,
                                  instance_divisor=1)
        self.taxiways.set_vertex_count(len(self.vbuf_asphalt) / 2)

        # ------- Pavement -------------------------------
        self.pavement = RenderObject(gl.GL_TRIANGLES)
        self.pavement.bind_attrib(ATTRIB_VERTEX, 2, self.vbuf_concrete)
        self.pavement.bind_attrib(ATTRIB_COLOR,
                                  3,
                                  np.array(lightgrey, dtype=np.uint8),
                                  datatype=gl.GL_UNSIGNED_BYTE,
                                  normalize=True,
                                  instance_divisor=1)
        self.pavement.set_vertex_count(len(self.vbuf_concrete) / 2)

        # Polygon preview object
        self.polyprev = RenderObject(gl.GL_LINE_LOOP)
        self.polyprev.bind_attrib(ATTRIB_VERTEX, 2, self.polyprevbuf)
        self.polyprev.bind_attrib(ATTRIB_COLOR,
                                  3,
                                  np.array(lightblue, dtype=np.uint8),
                                  datatype=gl.GL_UNSIGNED_BYTE,
                                  normalize=True,
                                  instance_divisor=1)

        # Fixed polygons
        self.allpolys = RenderObject(gl.GL_LINES)
        self.allpolys.bind_attrib(ATTRIB_VERTEX, 2, self.allpolysbuf)
        self.allpolys.bind_attrib(ATTRIB_COLOR,
                                  3,
                                  np.array(blue, dtype=np.uint8),
                                  datatype=gl.GL_UNSIGNED_BYTE,
                                  normalize=True,
                                  instance_divisor=1)

        # ------- SSD object -----------------------------
        self.ssd = RenderObject(gl.GL_POINTS)
        self.ssd.bind_attrib(ATTRIB_LAT0, 1, self.aclatbuf, instance_divisor=1)
        self.ssd.bind_attrib(ATTRIB_LON0, 1, self.aclonbuf, instance_divisor=1)
        self.ssd.bind_attrib(ATTRIB_ALT0, 1, self.acaltbuf, instance_divisor=1)
        self.ssd.bind_attrib(ATTRIB_TAS0, 1, self.actasbuf, instance_divisor=1)
        self.ssd.bind_attrib(ATTRIB_TRK0, 1, self.achdgbuf, instance_divisor=1)
        self.ssd.bind_attrib(ATTRIB_LAT1, 1, self.aclatbuf)
        self.ssd.bind_attrib(ATTRIB_LON1, 1, self.aclonbuf)
        self.ssd.bind_attrib(ATTRIB_ALT1, 1, self.acaltbuf)
        self.ssd.bind_attrib(ATTRIB_TAS1, 1, self.actasbuf)
        self.ssd.bind_attrib(ATTRIB_TRK1, 1, self.achdgbuf)

        # ------- Circle ---------------------------------
        # Create a new VAO (Vertex Array Object) and bind it
        self.protectedzone = RenderObject(gl.GL_LINE_LOOP,
                                          vertex_count=self.vcount_circle)
        circlevertices = np.transpose(
            np.array(
                (2.5 * nm *
                 np.cos(np.linspace(0.0, 2.0 * np.pi, self.vcount_circle)),
                 2.5 * nm *
                 np.sin(np.linspace(0.0, 2.0 * np.pi, self.vcount_circle))),
                dtype=np.float32))
        self.protectedzone.bind_attrib(ATTRIB_VERTEX, 2, circlevertices)
        self.protectedzone.bind_attrib(ATTRIB_LAT,
                                       1,
                                       self.aclatbuf,
                                       instance_divisor=1)
        self.protectedzone.bind_attrib(ATTRIB_LON,
                                       1,
                                       self.aclonbuf,
                                       instance_divisor=1)
        self.protectedzone.bind_attrib(ATTRIB_COLOR,
                                       3,
                                       self.accolorbuf,
                                       datatype=gl.GL_UNSIGNED_BYTE,
                                       normalize=True,
                                       instance_divisor=1)

        # ------- A/C symbol -----------------------------
        self.ac_symbol = RenderObject(gl.GL_TRIANGLE_FAN, vertex_count=4)
        acvertices = np.array([(0.0, 0.5 * ac_size),
                               (-0.5 * ac_size, -0.5 * ac_size),
                               (0.0, -0.25 * ac_size),
                               (0.5 * ac_size, -0.5 * ac_size)],
                              dtype=np.float32)
        self.ac_symbol.bind_attrib(ATTRIB_VERTEX, 2, acvertices)
        self.ac_symbol.bind_attrib(ATTRIB_LAT,
                                   1,
                                   self.aclatbuf,
                                   instance_divisor=1)
        self.ac_symbol.bind_attrib(ATTRIB_LON,
                                   1,
                                   self.aclonbuf,
                                   instance_divisor=1)
        self.ac_symbol.bind_attrib(ATTRIB_ORIENTATION,
                                   1,
                                   self.achdgbuf,
                                   instance_divisor=1)
        self.ac_symbol.bind_attrib(ATTRIB_COLOR,
                                   3,
                                   self.accolorbuf,
                                   datatype=gl.GL_UNSIGNED_BYTE,
                                   normalize=True,
                                   instance_divisor=1)
        self.aclabels = self.font.prepare_text_instanced(
            self.aclblbuf, (8, 3),
            self.aclatbuf,
            self.aclonbuf,
            self.accolorbuf,
            char_size=text_size,
            vertex_offset=(ac_size, -0.5 * ac_size))

        # ------- Conflict CPA lines ---------------------
        self.cpalines = RenderObject(gl.GL_LINES)
        self.cpalines.bind_attrib(ATTRIB_VERTEX, 2, self.confcpabuf)
        self.cpalines.bind_attrib(ATTRIB_COLOR,
                                  3,
                                  np.array(amber, dtype=np.uint8),
                                  datatype=gl.GL_UNSIGNED_BYTE,
                                  normalize=True,
                                  instance_divisor=1)

        # ------- Aircraft Route -------------------------
        self.route = RenderObject(gl.GL_LINES)
        self.route.bind_attrib(ATTRIB_VERTEX, 2, self.routebuf)
        self.route.bind_attrib(ATTRIB_COLOR,
                               3,
                               np.array(magenta, dtype=np.uint8),
                               datatype=gl.GL_UNSIGNED_BYTE,
                               normalize=True,
                               instance_divisor=1)
        self.routelbl = self.font.prepare_text_instanced(
            self.routelblbuf, (12, 1),
            self.routewplatbuf,
            self.routewplonbuf,
            char_size=text_size,
            vertex_offset=(wpt_size, 0.5 * wpt_size))

        # ------- Waypoints ------------------------------
        self.nwaypoints = len(self.navdb.wplat)
        self.waypoints = RenderObject(gl.GL_LINE_LOOP,
                                      vertex_count=3,
                                      n_instances=self.nwaypoints)
        wptvertices = np.array([(0.0, 0.5 * wpt_size),
                                (-0.5 * wpt_size, -0.5 * wpt_size),
                                (0.5 * wpt_size, -0.5 * wpt_size)],
                               dtype=np.float32)  # a triangle
        self.waypoints.bind_attrib(ATTRIB_VERTEX, 2, wptvertices)

        # Sort based on id string length
        llid = sorted(zip(self.navdb.wpid, self.navdb.wplat, self.navdb.wplon),
                      key=lambda i: len(i[0]) > 3)
        wplat = [lat for (wpid, lat, lon) in llid]
        wplon = [lon for (wpid, lon, lon) in llid]
        self.wptlatbuf = self.waypoints.bind_attrib(ATTRIB_LAT,
                                                    1,
                                                    np.array(wplat,
                                                             dtype=np.float32),
                                                    instance_divisor=1)
        self.wptlonbuf = self.waypoints.bind_attrib(ATTRIB_LON,
                                                    1,
                                                    np.array(wplon,
                                                             dtype=np.float32),
                                                    instance_divisor=1)
        wptids = ''
        self.nnavaids = 0
        for wptid in llid:
            if len(wptid[0]) <= 3:
                self.nnavaids += 1
            wptids += wptid[0].ljust(5)
        self.wptlabels = self.font.prepare_text_instanced(
            np.array(wptids, dtype=np.string_), (5, 1),
            self.wptlatbuf,
            self.wptlonbuf,
            char_size=text_size,
            vertex_offset=(wpt_size, 0.5 * wpt_size))
        del wptids

        # ------- Airports -------------------------------
        self.nairports = len(self.navdb.aptlat)
        self.airports = RenderObject(gl.GL_LINE_LOOP,
                                     vertex_count=4,
                                     n_instances=self.nairports)
        aptvertices = np.array([(-0.5 * apt_size, -0.5 * apt_size),
                                (0.5 * apt_size, -0.5 * apt_size),
                                (0.5 * apt_size, 0.5 * apt_size),
                                (-0.5 * apt_size, 0.5 * apt_size)],
                               dtype=np.float32)  # a square
        self.airports.bind_attrib(ATTRIB_VERTEX, 2, aptvertices)
        indices = self.navdb.aptype.argsort()
        aplat = np.array(self.navdb.aptlat[indices], dtype=np.float32)
        aplon = np.array(self.navdb.aptlon[indices], dtype=np.float32)
        aptypes = self.navdb.aptype[indices]
        apnames = np.array(self.navdb.aptid)
        apnames = apnames[indices]
        # The number of large, large+med, and large+med+small airports
        self.nairports = [
            aptypes.searchsorted(2),
            aptypes.searchsorted(3), self.nairports
        ]

        self.aptlatbuf = self.airports.bind_attrib(ATTRIB_LAT,
                                                   1,
                                                   aplat,
                                                   instance_divisor=1)
        self.aptlonbuf = self.airports.bind_attrib(ATTRIB_LON,
                                                   1,
                                                   aplon,
                                                   instance_divisor=1)
        aptids = ''
        for aptid in apnames:
            aptids += aptid.ljust(4)
        self.aptlabels = self.font.prepare_text_instanced(
            np.array(aptids, dtype=np.string_), (4, 1),
            self.aptlatbuf,
            self.aptlonbuf,
            char_size=text_size,
            vertex_offset=(apt_size, 0.5 * apt_size))
        del aptids

        # Unbind VAO, VBO
        RenderObject.unbind_all()

        # Set initial values for the global uniforms
        self.globaldata.set_wrap(self.wraplon, self.wrapdir)
        self.globaldata.set_pan_and_zoom(self.panlat, self.panlon, self.zoom)

        # Clean up memory
        del self.vbuf_asphalt, self.vbuf_concrete, self.vbuf_runways, self.vbuf_rwythr

        self.initialized = True
示例#6
0
    def paintGL(self):
        """Paint the scene."""
        # pass if the framebuffer isn't complete yet or if not initialized
        if not (gl.glCheckFramebufferStatus(gl.GL_FRAMEBUFFER) == gl.GL_FRAMEBUFFER_COMPLETE and self.initialized and self.isVisible()):
            return

        # Set the viewport and clear the framebuffer
        gl.glViewport(*self.viewport)
        gl.glClear(gl.GL_COLOR_BUFFER_BIT)

        # Send the (possibly) updated global uniforms to the buffer
        self.globaldata.set_vertex_scale_type(VERTEX_IS_LATLON)

        # --- DRAW THE MAP AND COASTLINES ---------------------------------------------
        # Map and coastlines: don't wrap around in the shader
        self.globaldata.enable_wrap(False)

        if self.show_map:
            # Select the texture shader
            self.texture_shader.use()

            # Draw map texture
            gl.glActiveTexture(gl.GL_TEXTURE0 + 0)
            gl.glBindTexture(gl.GL_TEXTURE_2D, self.map_texture)
            self.map.draw()

        # Select the non-textured shader
        self.color_shader.use()

        # Draw coastlines
        if self.show_coast:
            if self.wrapdir == 0:
                # Normal case, no wrap around
                self.coastlines.draw(first_vertex=0, vertex_count=self.vcount_coast)
            else:
                self.coastlines.bind()
                wrapindex = np.uint32(self.coastindices[int(self.wraplon) + 180])
                if self.wrapdir == 1:
                    gl.glVertexAttrib1f(ATTRIB_LON, 360.0)
                    self.coastlines.draw(first_vertex=0, vertex_count=wrapindex)
                    gl.glVertexAttrib1f(ATTRIB_LON, 0.0)
                    self.coastlines.draw(first_vertex=wrapindex, vertex_count=self.vcount_coast - wrapindex)
                else:
                    gl.glVertexAttrib1f(ATTRIB_LON, -360.0)
                    self.coastlines.draw(first_vertex=wrapindex, vertex_count=self.vcount_coast - wrapindex)
                    gl.glVertexAttrib1f(ATTRIB_LON, 0.0)
                    self.coastlines.draw(first_vertex=0, vertex_count=wrapindex)

        # --- DRAW PREVIEW SHAPE (WHEN AVAILABLE) -----------------------------
        self.polyprev.draw()

        # --- DRAW CUSTOM SHAPES (WHEN AVAILABLE) -----------------------------
        self.allpolys.draw()

        # --- DRAW THE SELECTED AIRCRAFT ROUTE (WHEN AVAILABLE) ---------------
        if self.show_traf:
            self.route.draw()
            self.cpalines.draw()

        # --- DRAW AIRPORT DETAILS (RUNWAYS, TAXIWAYS, PAVEMENTS) -------------
        self.runways.draw()
        self.thresholds.draw()
        if self.zoom >= 1.0:
            for idx in self.apt_inrange:
                self.taxiways.draw(first_vertex=idx[0], vertex_count=idx[1])
                self.pavement.draw(first_vertex=idx[2], vertex_count=idx[3])

        # --- DRAW THE INSTANCED AIRCRAFT SHAPES ------------------------------
        # update wrap longitude and direction for the instanced objects
        self.globaldata.enable_wrap(True)

        # PZ circles only when they are bigger than the A/C symbols
        if self.naircraft > 0 and self.show_traf and self.show_pz and self.zoom >= 0.15:
            self.globaldata.set_vertex_scale_type(VERTEX_IS_METERS)
            self.protectedzone.draw(n_instances=self.naircraft)

        self.globaldata.set_vertex_scale_type(VERTEX_IS_SCREEN)

        # Draw traffic symbols
        if self.naircraft > 0 and self.show_traf:
            self.ac_symbol.draw(n_instances=self.naircraft)

        if self.zoom >= 0.5:
            nairports = self.nairports[2]
        elif self.zoom  >= 0.25:
            nairports = self.nairports[1]
        else:
            nairports = self.nairports[0]

        if self.zoom >= 3:
            nwaypoints = self.nwaypoints
        else:
            nwaypoints = self.nnavaids

        # Draw waypoint symbols
        if self.show_wpt:
            self.waypoints.bind()
            gl.glVertexAttrib4Nub(ATTRIB_COLOR, *(lightblue3 + (255,)))
            self.waypoints.draw(n_instances=nwaypoints)

        # Draw airport symbols
        if self.show_apt:
            self.airports.bind()
            gl.glVertexAttrib4Nub(ATTRIB_COLOR, *(lightblue3 + (255,)))
            self.airports.draw(n_instances=nairports)

        if self.do_text:
            self.text_shader.use()
            self.font.use()

            if self.show_apt:
                self.font.set_char_size(self.aptlabels.char_size)
                self.font.set_block_size(self.aptlabels.block_size)
                self.aptlabels.bind()
                gl.glVertexAttrib4Nub(ATTRIB_COLOR, *(lightblue4 + (255,)))
                self.aptlabels.draw(n_instances=nairports)
            if self.show_wpt:
                self.font.set_char_size(self.wptlabels.char_size)
                self.font.set_block_size(self.wptlabels.block_size)
                self.wptlabels.bind()
                gl.glVertexAttrib4Nub(ATTRIB_COLOR, *(lightblue4 + (255,)))
                self.wptlabels.draw(n_instances=nwaypoints)

            if self.show_traf and self.route.vertex_count > 1:
                gl.glVertexAttrib4Nub(ATTRIB_COLOR, *(magenta + (255,)))
                self.font.set_char_size(self.routelbl.char_size)
                self.font.set_block_size(self.routelbl.block_size)
                self.routelbl.draw()

            if self.naircraft > 0 and self.show_traf and self.show_lbl:
                self.font.set_char_size(self.aclabels.char_size)
                self.font.set_block_size(self.aclabels.block_size)
                self.aclabels.draw(n_instances=self.naircraft)

        # SSD
        if self.ssd_all or len(self.ssd_ownship) > 0:
            self.ssd_shader.use()
            gl.glUniform3f(self.ssd_shader.loc_vlimits, 1e4, 4e4, 200.0)
            if self.ssd_all:
                self.ssd.draw(first_vertex=0, vertex_count=self.naircraft, n_instances=self.naircraft)
            else:
                self.ssd.draw(first_vertex=self.ssd_ownship[-1], vertex_count=1, n_instances=self.naircraft)

        # Unbind everything
        RenderObject.unbind_all()
        gl.glUseProgram(0)
示例#7
0
    def create_objects(self):
        if not self.isValid():
            self.invalid_count += 1
            print 'Radarwidget: Context not valid in create_objects, count=%d' % self.invalid_count
            QTimer.singleShot(100, self.create_objects)
            return

        # Make the radarwidget context current, necessary when create_objects is not called from initializeGL
        self.makeCurrent()

        # Initialize font for radar view with specified settings
        self.font = Font()
        self.font.create_font_array(char_height=text_texture_size, font_family=font_family, font_weight=font_weight)
        self.font.init_shader(self.text_shader)

        # Load and bind world texture
        max_texture_size = gl.glGetIntegerv(gl.GL_MAX_TEXTURE_SIZE)
        print 'Maximum supported texture size: %d' % max_texture_size
        for i in [16384, 8192, 4096]:
            if max_texture_size >= i:
                fname = 'data/graphics/world.%dx%d.dds' % (i, i / 2)
                print 'Loading texture ' + fname
                self.map_texture = self.bindTexture(fname)
                break

        # Create initial empty buffers for aircraft position, orientation, label, and color
        self.achdgbuf      = create_empty_buffer(MAX_NAIRCRAFT * 4, usage=gl.GL_STREAM_DRAW)
        self.aclatbuf      = create_empty_buffer(MAX_NAIRCRAFT * 4, usage=gl.GL_STREAM_DRAW)
        self.aclonbuf      = create_empty_buffer(MAX_NAIRCRAFT * 4, usage=gl.GL_STREAM_DRAW)
        self.acaltbuf      = create_empty_buffer(MAX_NAIRCRAFT * 4, usage=gl.GL_STREAM_DRAW)
        self.actasbuf      = create_empty_buffer(MAX_NAIRCRAFT * 4, usage=gl.GL_STREAM_DRAW)
        self.accolorbuf    = create_empty_buffer(MAX_NAIRCRAFT * 3, usage=gl.GL_STREAM_DRAW)
        self.aclblbuf      = create_empty_buffer(MAX_NAIRCRAFT * 24, usage=gl.GL_STREAM_DRAW)
        self.confcpabuf    = create_empty_buffer(MAX_NCONFLICTS * 16, usage=gl.GL_STREAM_DRAW)
        self.polyprevbuf   = create_empty_buffer(MAX_POLYPREV_SEGMENTS * 8, usage=gl.GL_DYNAMIC_DRAW)
        self.allpolysbuf   = create_empty_buffer(MAX_ALLPOLYS_SEGMENTS * 16, usage=gl.GL_DYNAMIC_DRAW)
        self.routebuf      = create_empty_buffer(MAX_ROUTE_LENGTH * 8, usage=gl.GL_DYNAMIC_DRAW)
        self.routewplatbuf = create_empty_buffer(MAX_ROUTE_LENGTH * 4, usage=gl.GL_DYNAMIC_DRAW)
        self.routewplonbuf = create_empty_buffer(MAX_ROUTE_LENGTH * 4, usage=gl.GL_DYNAMIC_DRAW)
        self.routelblbuf   = create_empty_buffer(MAX_ROUTE_LENGTH * 12, usage=gl.GL_DYNAMIC_DRAW)

        # ------- Map ------------------------------------
        self.map = RenderObject(gl.GL_TRIANGLE_FAN, vertex_count=4)
        mapvertices = np.array([(-90.0, 540.0), (-90.0, -540.0), (90.0, -540.0), (90.0, 540.0)], dtype=np.float32)
        texcoords = np.array([(1, 3), (1, 0), (0, 0), (0, 3)], dtype=np.float32)
        self.map.bind_attrib(ATTRIB_VERTEX, 2, mapvertices)
        self.map.bind_attrib(ATTRIB_TEXCOORDS, 2, texcoords)

        # ------- Coastlines -----------------------------
        self.coastlines = RenderObject(gl.GL_LINES)
        coastvertices, coastindices = load_coastlines()
        self.coastlines.bind_attrib(ATTRIB_VERTEX, 2, coastvertices)
        self.coastlines.bind_attrib(ATTRIB_COLOR, 3, np.array(lightblue2, dtype=np.uint8), datatype=gl.GL_UNSIGNED_BYTE, normalize=True, instance_divisor=1)
        self.vcount_coast = len(coastvertices)
        self.coastindices = coastindices
        del coastvertices

        # ------- Runways --------------------------------
        self.runways = RenderObject(gl.GL_TRIANGLES)
        self.runways.bind_attrib(ATTRIB_VERTEX, 2, self.vbuf_runways)
        self.runways.bind_attrib(ATTRIB_COLOR, 3, np.array(grey, dtype=np.uint8), datatype=gl.GL_UNSIGNED_BYTE, normalize=True, instance_divisor=1)
        self.runways.set_vertex_count(len(self.vbuf_runways) / 2)

        #---------Runway Thresholds-----------------------
        self.thresholds = RenderObject(gl.GL_TRIANGLES)
        self.thresholds.bind_attrib(ATTRIB_VERTEX, 2, self.vbuf_rwythr)
        self.thresholds.bind_attrib(ATTRIB_COLOR, 3, np.array(white, dtype=np.uint8), datatype=gl.GL_UNSIGNED_BYTE, normalize=True, instance_divisor=1)
        self.thresholds.set_vertex_count(len(self.vbuf_rwythr) / 2)

        # ------- Taxiways -------------------------------
        self.taxiways = RenderObject(gl.GL_TRIANGLES)
        self.taxiways.bind_attrib(ATTRIB_VERTEX, 2, self.vbuf_asphalt)
        self.taxiways.bind_attrib(ATTRIB_COLOR, 3, np.array(grey, dtype=np.uint8), datatype=gl.GL_UNSIGNED_BYTE, normalize=True, instance_divisor=1)
        self.taxiways.set_vertex_count(len(self.vbuf_asphalt) / 2)

        # ------- Pavement -------------------------------
        self.pavement = RenderObject(gl.GL_TRIANGLES)
        self.pavement.bind_attrib(ATTRIB_VERTEX, 2, self.vbuf_concrete)
        self.pavement.bind_attrib(ATTRIB_COLOR, 3, np.array(lightgrey, dtype=np.uint8), datatype=gl.GL_UNSIGNED_BYTE, normalize=True, instance_divisor=1)
        self.pavement.set_vertex_count(len(self.vbuf_concrete) / 2)

        # Polygon preview object
        self.polyprev = RenderObject(gl.GL_LINE_LOOP)
        self.polyprev.bind_attrib(ATTRIB_VERTEX, 2, self.polyprevbuf)
        self.polyprev.bind_attrib(ATTRIB_COLOR, 3, np.array(lightblue, dtype=np.uint8), datatype=gl.GL_UNSIGNED_BYTE, normalize=True, instance_divisor=1)

        # Fixed polygons
        self.allpolys = RenderObject(gl.GL_LINES)
        self.allpolys.bind_attrib(ATTRIB_VERTEX, 2, self.allpolysbuf)
        self.allpolys.bind_attrib(ATTRIB_COLOR, 3, np.array(blue, dtype=np.uint8), datatype=gl.GL_UNSIGNED_BYTE, normalize=True, instance_divisor=1)

        # ------- SSD object -----------------------------
        self.ssd = RenderObject(gl.GL_POINTS)
        self.ssd.bind_attrib(ATTRIB_LAT0, 1, self.aclatbuf)
        self.ssd.bind_attrib(ATTRIB_LON0, 1, self.aclonbuf)
        self.ssd.bind_attrib(ATTRIB_ALT0, 1, self.acaltbuf)
        self.ssd.bind_attrib(ATTRIB_TAS0, 1, self.actasbuf)
        self.ssd.bind_attrib(ATTRIB_TRK0, 1, self.achdgbuf)
        self.ssd.bind_attrib(ATTRIB_LAT1, 1, self.aclatbuf, instance_divisor=1)
        self.ssd.bind_attrib(ATTRIB_LON1, 1, self.aclonbuf, instance_divisor=1)
        self.ssd.bind_attrib(ATTRIB_ALT1, 1, self.acaltbuf, instance_divisor=1)
        self.ssd.bind_attrib(ATTRIB_TAS1, 1, self.actasbuf, instance_divisor=1)
        self.ssd.bind_attrib(ATTRIB_TRK1, 1, self.achdgbuf, instance_divisor=1)

        # ------- Circle ---------------------------------
        # Create a new VAO (Vertex Array Object) and bind it
        self.protectedzone = RenderObject(gl.GL_LINE_LOOP, vertex_count=self.vcount_circle)
        circlevertices = np.transpose(np.array((5.0 * nm * np.cos(np.linspace(0.0, 2.0 * np.pi, self.vcount_circle)), 5.0 * nm * np.sin(np.linspace(0.0, 2.0 * np.pi, self.vcount_circle))), dtype=np.float32))
        self.protectedzone.bind_attrib(ATTRIB_VERTEX, 2, circlevertices)
        self.protectedzone.bind_attrib(ATTRIB_LAT, 1, self.aclatbuf, instance_divisor=1)
        self.protectedzone.bind_attrib(ATTRIB_LON, 1, self.aclonbuf, instance_divisor=1)
        self.protectedzone.bind_attrib(ATTRIB_COLOR, 3, self.accolorbuf, datatype=gl.GL_UNSIGNED_BYTE, normalize=True, instance_divisor=1)

        # ------- A/C symbol -----------------------------
        self.ac_symbol = RenderObject(gl.GL_TRIANGLE_FAN, vertex_count=4)
        acvertices = np.array([(0.0, 0.5 * ac_size), (-0.5 * ac_size, -0.5 * ac_size), (0.0, -0.25 * ac_size), (0.5 * ac_size, -0.5 * ac_size)], dtype=np.float32)
        self.ac_symbol.bind_attrib(ATTRIB_VERTEX, 2, acvertices)
        self.ac_symbol.bind_attrib(ATTRIB_LAT, 1, self.aclatbuf, instance_divisor=1)
        self.ac_symbol.bind_attrib(ATTRIB_LON, 1, self.aclonbuf, instance_divisor=1)
        self.ac_symbol.bind_attrib(ATTRIB_ORIENTATION, 1, self.achdgbuf, instance_divisor=1)
        self.ac_symbol.bind_attrib(ATTRIB_COLOR, 3, self.accolorbuf, datatype=gl.GL_UNSIGNED_BYTE, normalize=True, instance_divisor=1)
        self.aclabels = self.font.prepare_text_instanced(self.aclblbuf, (8, 3), self.aclatbuf, self.aclonbuf, self.accolorbuf, char_size=text_size, vertex_offset=(ac_size, -0.5 * ac_size))

        # ------- Conflict CPA lines ---------------------
        self.cpalines = RenderObject(gl.GL_LINES)
        self.cpalines.bind_attrib(ATTRIB_VERTEX, 2, self.confcpabuf)
        self.cpalines.bind_attrib(ATTRIB_COLOR, 3, np.array(amber, dtype=np.uint8), datatype=gl.GL_UNSIGNED_BYTE, normalize=True, instance_divisor=1)

        # ------- Aircraft Route -------------------------
        self.route = RenderObject(gl.GL_LINES)
        self.route.bind_attrib(ATTRIB_VERTEX, 2, self.routebuf)
        self.route.bind_attrib(ATTRIB_COLOR, 3, np.array(magenta, dtype=np.uint8), datatype=gl.GL_UNSIGNED_BYTE, normalize=True, instance_divisor=1)
        self.routelbl = self.font.prepare_text_instanced(self.routelblbuf, (12, 1), self.routewplatbuf, self.routewplonbuf, char_size=text_size, vertex_offset=(wpt_size, 0.5 * wpt_size))

        # ------- Waypoints ------------------------------
        self.nwaypoints = len(self.navdb.wplat)
        self.waypoints = RenderObject(gl.GL_LINE_LOOP, vertex_count=3, n_instances=self.nwaypoints)
        wptvertices = np.array([(0.0, 0.5 * wpt_size), (-0.5 * wpt_size, -0.5 * wpt_size), (0.5 * wpt_size, -0.5 * wpt_size)], dtype=np.float32)  # a triangle
        self.waypoints.bind_attrib(ATTRIB_VERTEX, 2, wptvertices)

        # Sort based on id string length
        llid = sorted(zip(self.navdb.wpid, self.navdb.wplat, self.navdb.wplon), key=lambda i: len(i[0]) > 3)
        wplat = [lat for (wpid, lat, lon) in llid]
        wplon = [lon for (wpid, lon, lon) in llid]
        self.wptlatbuf = self.waypoints.bind_attrib(ATTRIB_LAT, 1, np.array(wplat, dtype=np.float32), instance_divisor=1)
        self.wptlonbuf = self.waypoints.bind_attrib(ATTRIB_LON, 1, np.array(wplon, dtype=np.float32), instance_divisor=1)
        wptids = ''
        self.nnavaids = 0
        for wptid in llid:
            if len(wptid[0]) <= 3:
                self.nnavaids += 1
            wptids += wptid[0].ljust(5)
        self.wptlabels = self.font.prepare_text_instanced(np.array(wptids, dtype=np.string_), (5, 1), self.wptlatbuf, self.wptlonbuf, char_size=text_size, vertex_offset=(wpt_size, 0.5 * wpt_size))
        del wptids

        # ------- Airports -------------------------------
        self.nairports = len(self.navdb.aplat)
        self.airports = RenderObject(gl.GL_LINE_LOOP, vertex_count=4, n_instances=self.nairports)
        aptvertices = np.array([(-0.5 * apt_size, -0.5 * apt_size), (0.5 * apt_size, -0.5 * apt_size), (0.5 * apt_size, 0.5 * apt_size), (-0.5 * apt_size, 0.5 * apt_size)], dtype=np.float32)  # a square
        self.airports.bind_attrib(ATTRIB_VERTEX, 2, aptvertices)
        indices = self.navdb.aptype.argsort()
        aplat   = np.array(self.navdb.aplat[indices], dtype=np.float32)
        aplon   = np.array(self.navdb.aplon[indices], dtype=np.float32)
        aptypes = self.navdb.aptype[indices]
        apnames = np.array(self.navdb.apid)
        apnames = apnames[indices]
        # The number of large, large+med, and large+med+small airports
        self.nairports = [aptypes.searchsorted(2), aptypes.searchsorted(3), self.nairports]

        self.aptlatbuf = self.airports.bind_attrib(ATTRIB_LAT, 1, aplat, instance_divisor=1)
        self.aptlonbuf = self.airports.bind_attrib(ATTRIB_LON, 1, aplon, instance_divisor=1)
        aptids = ''
        for aptid in apnames:
            aptids += aptid.ljust(4)
        self.aptlabels = self.font.prepare_text_instanced(np.array(aptids, dtype=np.string_), (4, 1), self.aptlatbuf, self.aptlonbuf, char_size=text_size, vertex_offset=(apt_size, 0.5 * apt_size))
        del aptids

        # Unbind VAO, VBO
        RenderObject.unbind_all()

        # Set initial values for the global uniforms
        self.globaldata.set_wrap(self.wraplon, self.wrapdir)
        self.globaldata.set_pan_and_zoom(self.panlat, self.panlon, self.zoom)

        # Clean up memory
        del self.vbuf_asphalt, self.vbuf_concrete, self.vbuf_runways, self.vbuf_rwythr

        self.initialized = True
示例#8
0
文件: nd.py 项目: olafur444/bluesky
    def create_objects(self):
        if not (self.isValid() and self.shareWidget.initialized):
            self.invalid_count += 1
            print 'ND: Context not valid in create_objects, or shareWidget not yet initialized'
            QTimer.singleShot(100, self.create_objects)
            return

        # Make the nd widget context current, necessary when create_objects is not called from initializeGL
        self.makeCurrent()

        # Use the same font as the radarwidget
        self.font = self.shareWidget.font.copy()
        self.font.init_shader(self.text_shader)

        self.edge = RenderObject(gl.GL_LINE_STRIP, vertex_count=60)
        edge = np.zeros(120, dtype=np.float32)
        edge[0:120:2] = 1.4 * np.sin(np.radians(np.arange(-60, 60, 2)))
        edge[1:120:2] = 1.4 * np.cos(np.radians(np.arange(-60, 60, 2)))
        self.edge.bind_attrib(ATTRIB_VERTEX, 2, edge)
        self.edge.bind_attrib(ATTRIB_COLOR, 3, np.array(white, dtype=np.uint8), datatype=gl.GL_UNSIGNED_BYTE, normalize=True, instance_divisor=1)
        self.arcs = RenderObject(gl.GL_LINES)
        arcs = []
        for i in range(1, 4):
            for angle in range(-60, 60, max(2, 6 - 2 * i)):
                arcs.append(float(i) * 0.35 * sin(radians(angle)))
                arcs.append(float(i) * 0.35 * cos(radians(angle)))
                if i == 4:
                    arcs.append(float(i) * 0.35 * sin(radians(angle + 2)))
                    arcs.append(float(i) * 0.35 * cos(radians(angle + 2)))

        self.arcs.bind_attrib(ATTRIB_VERTEX, 2, np.array(arcs, dtype=np.float32))
        self.arcs.bind_attrib(ATTRIB_COLOR, 3, np.array(white, dtype=np.uint8), datatype=gl.GL_UNSIGNED_BYTE, normalize=True, instance_divisor=1)
        self.arcs.set_vertex_count(len(arcs))

        self.mask = RenderObject(gl.GL_TRIANGLE_STRIP, vertex_count=120)
        mask = []
        for angle in range(-60, 60, 2):
            mask.append(1.4*sin(radians(angle)))
            mask.append(10.0)
            mask.append(1.4*sin(radians(angle)))
            mask.append(1.4*cos(radians(angle)))
        self.mask.bind_attrib(ATTRIB_VERTEX, 2, np.array(mask, dtype=np.float32))
        self.mask.bind_attrib(ATTRIB_COLOR, 3, np.array(black, dtype=np.uint8), datatype=gl.GL_UNSIGNED_BYTE, normalize=True, instance_divisor=1)

        self.ticks = RenderObject(gl.GL_LINES, vertex_count=144)
        ticks = np.zeros(288, dtype=np.float32)
        for i in range(72):
            ticktop = 1.46 if i % 6 == 0 else (1.44 if i % 2 == 0 else 1.42)
            ticks[4*i  :4*i+2] = (1.4 * sin(radians(i * 5)), 1.4 * cos(radians(i * 5)))
            ticks[4*i+2:4*i+4] = (ticktop * sin(radians(i * 5)), ticktop * cos(radians(i * 5)))
        self.ticks.bind_attrib(ATTRIB_VERTEX, 2, ticks)
        self.ticks.bind_attrib(ATTRIB_COLOR, 3, np.array(white, dtype=np.uint8), datatype=gl.GL_UNSIGNED_BYTE, normalize=True, instance_divisor=1)

        self.ticklbls = RenderObject(gl.GL_TRIANGLES, vertex_count=12 * 36)
        ticklbls = np.zeros(24 * 36, dtype=np.float32)
        texcoords = np.zeros(36 * 36, dtype=np.float32)

        for i in range(36):
            if i % 3 == 0:
                w, h, y = 0.045, 0.09, 1.48
            else:
                w, h, y = 0.035, 0.07, 1.46
            tmp = [(-w, h+y), (-w, y), (0.0, h+y), (0.0, h+y), (-w, y), (0.0, y),
                   (0.0, h+y), (0.0, y), (w, h+y), (w, h+y), (0.0, y), (w, y)]

            # numerics start at ASCII 48
            c1 = i / 10 + 48
            c2 = i % 10 + 48
            texcoords[36*i:36*i+18]    = [0, 0, c1, 0, 1, c1, 1, 0, c1, 1, 0, c1, 0, 1, c1, 1, 1, c1]
            texcoords[36*i+18:36*i+36] = [0, 0, c2, 0, 1, c2, 1, 0, c2, 1, 0, c2, 0, 1, c2, 1, 1, c2]
            angle = radians(10 * (36 - i))
            rot = np.array([[cos(angle), -sin(angle)], [sin(angle), cos(angle)]])
            for j in range(12):
                ticklbls[24*i+2*j:24*i+2*j+2] = rot.dot(tmp[j])

        self.ticklbls.bind_attrib(ATTRIB_VERTEX, 2, ticklbls)
        self.ticklbls.bind_attrib(ATTRIB_TEXCOORDS, 3, texcoords)
        self.ticklbls.bind_attrib(ATTRIB_COLOR, 3, np.array(white, dtype=np.uint8), datatype=gl.GL_UNSIGNED_BYTE, normalize=True, instance_divisor=1)

        self.ownship = RenderObject(gl.GL_LINES, vertex_count=6)
        self.ownship.bind_attrib(ATTRIB_VERTEX, 2, np.array([0.0, 0.0, 0.0, -0.12, 0.065, -0.03, -0.065, -0.03, 0.022, -0.1, -0.022, -0.1], dtype=np.float32))
        self.ownship.bind_attrib(ATTRIB_COLOR, 3, np.array(yellow, dtype=np.uint8), datatype=gl.GL_UNSIGNED_BYTE, normalize=True, instance_divisor=1)

        self.spdlabel_text = self.font.prepare_text_string('GS    TAS', 0.05, white, (-0.98, 1.6))
        self.spdlabel_val  = self.font.prepare_text_string('  000    000', 0.05, green, (-0.97, 1.6))

        self.waypoints = RenderObject.copy(self.shareWidget.waypoints)
        self.wptlabels = RenderObject.copy(self.shareWidget.wptlabels)
        self.airports  = RenderObject.copy(self.shareWidget.airports)
        self.aptlabels = RenderObject.copy(self.shareWidget.aptlabels)
        self.protectedzone = RenderObject.copy(self.shareWidget.protectedzone)
        self.ac_symbol = RenderObject.copy(self.shareWidget.ac_symbol)
        self.aclabels = RenderObject.copy(self.shareWidget.aclabels)

        # Unbind VAO, VBO
        RenderObject.unbind_all()

        # Done initializing
        self.initialized = True
示例#9
0
文件: nd.py 项目: olafur444/bluesky
    def paintGL(self):
        """Paint the scene."""
        # pass if the framebuffer isn't complete yet or if not initialized
        if not (gl.glCheckFramebufferStatus(gl.GL_FRAMEBUFFER) == gl.GL_FRAMEBUFFER_COMPLETE and self.initialized and self.isVisible()):
            return

        # Set the viewport and clear the framebuffer
        gl.glViewport(*self.viewport)
        gl.glClear(gl.GL_COLOR_BUFFER_BIT)

        # Select the non-textured shader
        self.color_shader.use()

        self.globaldata.set_vertex_modifiers(VERTEX_IS_GLXY, False)
        self.arcs.draw()

        self.globaldata.set_vertex_modifiers(VERTEX_IS_METERS, False)
        self.protectedzone.draw(n_instances=self.n_aircraft)
        self.globaldata.set_vertex_modifiers(VERTEX_IS_SCREEN, True)
        self.ac_symbol.draw(n_instances=self.n_aircraft)

        self.globaldata.set_vertex_modifiers(VERTEX_IS_SCREEN, False)
        self.waypoints.bind()
        gl.glVertexAttrib4Nub(ATTRIB_COLOR, *(lightblue2 + (255,)))
        self.waypoints.draw()
        self.airports.bind()
        gl.glVertexAttrib4Nub(ATTRIB_COLOR, *(lightblue2 + (255,)))
        self.airports.draw()

        self.text_shader.use()
        self.font.use()
        self.font.set_char_size(self.wptlabels.char_size)
        self.font.set_block_size(self.wptlabels.block_size)
        self.wptlabels.bind()
        gl.glVertexAttrib4Nub(ATTRIB_COLOR, *(lightblue3 + (255,)))
        self.wptlabels.draw(n_instances=self.waypoints.n_instances)

        self.font.set_char_size(self.aptlabels.char_size)
        self.font.set_block_size(self.aptlabels.block_size)
        self.aptlabels.bind()
        gl.glVertexAttrib4Nub(ATTRIB_COLOR, *(lightblue3 + (255,)))
        self.aptlabels.draw(n_instances=self.airports.n_instances)

        self.font.set_char_size(self.aclabels.char_size)
        self.font.set_block_size(self.aclabels.block_size)
        self.aclabels.draw(n_instances=self.n_aircraft)

        self.color_shader.use()
        self.globaldata.set_vertex_modifiers(VERTEX_IS_GLXY, False)
        self.ownship.draw()
        self.mask.draw()
        self.edge.draw()

        self.globaldata.set_vertex_modifiers(VERTEX_IS_GLXY, True)
        self.ticks.draw()

        # Select the text shader
        self.text_shader.use()
        self.font.use()
        self.font.set_block_size((0, 0))
        self.ticklbls.draw()

        self.globaldata.set_vertex_modifiers(VERTEX_IS_GLXY, False)
        self.spdlabel_text.draw()
        self.spdlabel_val.draw()

        # Unbind everything
        RenderObject.unbind_all()
        gl.glUseProgram(0)
示例#10
0
    def create_objects(self):
        self.mcp = RenderObject(gl.GL_TRIANGLES,
                                vertex=np.array(rect(-1, -1, 2, 2),
                                                dtype=np.float32))
        self.mcp_texture = load_texture('mcp737.png')
        self.btn_tex = load_texture('btn_led.png')

        self.lcd_tex = load_lcd_font()

        v_mcp_text = []
        for pos in [
                0.0, 0.03, 0.06, 0.31, 0.34, 0.37, 0.4, 0.43, 0.644, 0.674,
                0.704, 0.955, 0.985, 1.015, 1.045, 1.075, 1.22, 1.25, 1.28,
                1.31, 1.34, 1.69, 1.72, 1.75
        ]:
            v, t = Font.char(-0.886 + pos, 0.45, 0.03, 0.25)
            v_mcp_text += v

        self.mcp_text = RenderObject(gl.GL_TRIANGLES,
                                     vertex=np.array(v_mcp_text,
                                                     dtype=np.float32))
        self.lcd_charcoords = np.zeros(24 * 6, dtype=np.float32)
        self.lcdbuf = self.mcp_text.bind_attrib(1,
                                                1,
                                                self.lcd_charcoords,
                                                datatype=gl.GL_FLOAT)

        btn_leds = []
        for pos in [(-0.74, -0.75), (-0.645, -0.75), (-0.37, -0.75),
                    (-0.232, -0.75), (-0.09, -0.75), (0.105, -0.75),
                    (0.2, -0.75), (-0.37, 0.5), (-0.09, 0.5), (-0.09, -0.125),
                    (0.575, 0.34), (0.575, -0.34), (0.684, 0.34),
                    (0.684, -0.34)]:
            btn_leds += rect(pos[0], pos[1], 0.055, 0.075)
        btn_color = np.zeros(14 * 6 * 4, dtype=np.uint8)
        self.btn_leds = RenderObject(gl.GL_TRIANGLES,
                                     vertex=np.array(btn_leds,
                                                     dtype=np.float32),
                                     color=btn_color)

        # Button up/down indicator
        w, h, offset = 0.04, 0.16, 0.04
        triangles = np.array([
            -w, offset, 0.0, offset + h, w, offset, -w, -offset, 0.0,
            -offset - h, w, -offset
        ],
                             dtype=np.float32)
        col_triangles = np.array(6 * [255, 255, 255, 180], dtype=np.uint8)
        self.updown = RenderObject(gl.GL_TRIANGLES,
                                   vertex=triangles,
                                   color=col_triangles)

        # Use the same font as the radarwidget
        self.font = Font()
        self.font.create_font_array('../../data/graphics/font/')
        self.font.init_shader(self.text_shader)

        edge = np.zeros(120, dtype=np.float32)
        edge[0:120:2] = 1.4 * np.sin(np.radians(np.arange(-60, 60, 2)))
        edge[1:120:2] = 1.4 * np.cos(np.radians(np.arange(-60, 60, 2)))
        self.edge = RenderObject(gl.GL_LINE_STRIP, vertex=edge, color=white)

        arcs = []
        for i in range(1, 4):
            for angle in range(-60, 60, max(2, 6 - 2 * i)):
                arcs.append(float(i) * 0.35 * sin(radians(angle)))
                arcs.append(float(i) * 0.35 * cos(radians(angle)))
                if i == 4:
                    arcs.append(float(i) * 0.35 * sin(radians(angle + 2)))
                    arcs.append(float(i) * 0.35 * cos(radians(angle + 2)))
        arcs = np.array(arcs, dtype=np.float32)
        self.arcs = RenderObject(gl.GL_LINES, vertex=arcs, color=white)

        mask = []
        for angle in range(-60, 60, 2):
            mask.append(1.4 * sin(radians(angle)))
            mask.append(10.0)
            mask.append(1.4 * sin(radians(angle)))
            mask.append(1.4 * cos(radians(angle)))
        mask = np.array(mask, dtype=np.float32)
        self.mask = RenderObject(gl.GL_TRIANGLE_STRIP,
                                 vertex=mask,
                                 color=black)

        ticks = np.zeros(288, dtype=np.float32)
        for i in range(72):
            ticktop = 1.46 if i % 6 == 0 else (1.44 if i % 2 == 0 else 1.42)
            ticks[4 * i:4 * i + 2] = (1.4 * sin(radians(i * 5)),
                                      1.4 * cos(radians(i * 5)))
            ticks[4 * i + 2:4 * i + 4] = (ticktop * sin(radians(i * 5)),
                                          ticktop * cos(radians(i * 5)))
        self.ticks = RenderObject(gl.GL_LINES, vertex=ticks, color=white)

        ticklbls = np.zeros(24 * 36, dtype=np.float32)
        texcoords = np.zeros(36 * 36, dtype=np.float32)

        for i in range(36):
            if i % 3 == 0:
                w, h, y = 0.045, 0.09, 1.48
            else:
                w, h, y = 0.035, 0.07, 1.46
            tmp = [(-w, h + y), (-w, y), (0.0, h + y), (0.0, h + y), (-w, y),
                   (0.0, y), (0.0, h + y), (0.0, y), (w, h + y), (w, h + y),
                   (0.0, y), (w, y)]

            # numerics start at ASCII 48
            c1 = i / 10 + 48
            c2 = i % 10 + 48
            texcoords[36 * i:36 * i + 18] = [
                0, 0, c1, 0, 1, c1, 1, 0, c1, 1, 0, c1, 0, 1, c1, 1, 1, c1
            ]
            texcoords[36 * i + 18:36 * i + 36] = [
                0, 0, c2, 0, 1, c2, 1, 0, c2, 1, 0, c2, 0, 1, c2, 1, 1, c2
            ]
            angle = radians(10 * (36 - i))
            rot = np.array([[cos(angle), -sin(angle)],
                            [sin(angle), cos(angle)]])
            for j in range(12):
                ticklbls[24 * i + 2 * j:24 * i + 2 * j + 2] = rot.dot(tmp[j])

        self.ticklbls = RenderObject(gl.GL_TRIANGLES,
                                     vertex=ticklbls,
                                     color=white,
                                     texcoords=texcoords)

        vown = np.array([
            0.0, 0.0, 0.0, -0.12, 0.065, -0.03, -0.065, -0.03, 0.022, -0.1,
            -0.022, -0.1
        ],
                        dtype=np.float32)
        self.ownship = RenderObject(gl.GL_LINES, vertex=vown, color=yellow)

        self.spdlabel_text = self.font.prepare_text_string(
            'GS    TAS', 0.05, white, (-0.98, 1.6))
        self.spdlabel_val = self.font.prepare_text_string(
            '  000    000', 0.05, green, (-0.97, 1.6))

        self.initialized = True
        # Unbind everything
        RenderObject.unbind_all()
示例#11
0
    def create_objects(self):
        self.mcp         = RenderObject(gl.GL_TRIANGLES, vertex=np.array(rect(-1, -1, 2, 2), dtype=np.float32))
        self.mcp_texture = load_texture('mcp737.png')
        self.btn_tex     = load_texture('btn_led.png')

        self.lcd_tex     = load_lcd_font()

        v_mcp_text = []
        for pos in [0.0, 0.03, 0.06,
                    0.31, 0.34, 0.37, 0.4, 0.43,
                    0.644, 0.674, 0.704,
                    0.955, 0.985, 1.015, 1.045, 1.075,
                    1.22, 1.25, 1.28, 1.31, 1.34,
                    1.69, 1.72, 1.75]:
            v, t = Font.char(-0.886 + pos, 0.45, 0.03, 0.25)
            v_mcp_text += v

        self.mcp_text       = RenderObject(gl.GL_TRIANGLES, vertex=np.array(v_mcp_text, dtype=np.float32))
        self.lcd_charcoords = np.zeros(24 * 6, dtype=np.float32)
        self.lcdbuf         = self.mcp_text.bind_attrib(1, 1, self.lcd_charcoords, datatype=gl.GL_FLOAT)

        btn_leds = []
        for pos in [(-0.74, -0.75), (-0.645, -0.75), (-0.37, -0.75), (-0.232, -0.75),
                    (-0.09, -0.75), (0.105, -0.75), (0.2, -0.75),
                    (-0.37, 0.5), (-0.09, 0.5), (-0.09, -0.125),
                     (0.575, 0.34), (0.575, -0.34),
                     (0.684, 0.34), (0.684, -0.34)]:
            btn_leds += rect(pos[0], pos[1], 0.055, 0.075)
        btn_color = np.zeros(14 * 6 * 4, dtype=np.uint8)
        self.btn_leds = RenderObject(gl.GL_TRIANGLES, vertex=np.array(btn_leds, dtype=np.float32), color=btn_color)

        # Button up/down indicator
        w, h, offset = 0.04, 0.16, 0.04
        triangles = np.array([-w, offset,  0.0, offset + h, w, offset,
                     -w, -offset, 0.0, -offset - h, w, -offset], dtype=np.float32)
        col_triangles = np.array(6 * [255, 255, 255, 180], dtype=np.uint8)
        self.updown = RenderObject(gl.GL_TRIANGLES, vertex=triangles, color=col_triangles)

        # Use the same font as the radarwidget
        self.font = Font()
        self.font.create_font_array('../../data/graphics/font/')
        self.font.init_shader(self.text_shader)

        edge = np.zeros(120, dtype=np.float32)
        edge[0:120:2] = 1.4 * np.sin(np.radians(np.arange(-60, 60, 2)))
        edge[1:120:2] = 1.4 * np.cos(np.radians(np.arange(-60, 60, 2)))
        self.edge = RenderObject(gl.GL_LINE_STRIP, vertex=edge, color=white)

        arcs = []
        for i in range(1, 4):
            for angle in range(-60, 60, max(2, 6 - 2 * i)):
                arcs.append(float(i) * 0.35 * sin(radians(angle)))
                arcs.append(float(i) * 0.35 * cos(radians(angle)))
                if i == 4:
                    arcs.append(float(i) * 0.35 * sin(radians(angle + 2)))
                    arcs.append(float(i) * 0.35 * cos(radians(angle + 2)))
        arcs = np.array(arcs, dtype=np.float32)
        self.arcs = RenderObject(gl.GL_LINES, vertex=arcs, color=white)

        mask = []
        for angle in range(-60, 60, 2):
            mask.append(1.4 * sin(radians(angle)))
            mask.append(10.0)
            mask.append(1.4 * sin(radians(angle)))
            mask.append(1.4 * cos(radians(angle)))
        mask = np.array(mask, dtype=np.float32)
        self.mask = RenderObject(gl.GL_TRIANGLE_STRIP, vertex=mask, color=black)

        ticks = np.zeros(288, dtype=np.float32)
        for i in range(72):
            ticktop = 1.46 if i % 6 == 0 else (1.44 if i % 2 == 0 else 1.42)
            ticks[4*i  :4*i+2] = (1.4 * sin(radians(i * 5)), 1.4 * cos(radians(i * 5)))
            ticks[4*i+2:4*i+4] = (ticktop * sin(radians(i * 5)), ticktop * cos(radians(i * 5)))
        self.ticks = RenderObject(gl.GL_LINES, vertex=ticks, color=white)

        ticklbls = np.zeros(24 * 36, dtype=np.float32)
        texcoords = np.zeros(36 * 36, dtype=np.float32)

        for i in range(36):
            if i % 3 == 0:
                w, h, y = 0.045, 0.09, 1.48
            else:
                w, h, y = 0.035, 0.07, 1.46
            tmp = [(-w, h+y), (-w, y), (0.0, h+y), (0.0, h+y), (-w, y), (0.0, y),
                   (0.0, h+y), (0.0, y), (w, h+y), (w, h+y), (0.0, y), (w, y)]

            # numerics start at ASCII 48
            c1 = i / 10 + 48
            c2 = i % 10 + 48
            texcoords[36*i:36*i+18]    = [0, 0, c1, 0, 1, c1, 1, 0, c1, 1, 0, c1, 0, 1, c1, 1, 1, c1]
            texcoords[36*i+18:36*i+36] = [0, 0, c2, 0, 1, c2, 1, 0, c2, 1, 0, c2, 0, 1, c2, 1, 1, c2]
            angle = radians(10 * (36 - i))
            rot = np.array([[cos(angle), -sin(angle)], [sin(angle), cos(angle)]])
            for j in range(12):
                ticklbls[24*i+2*j:24*i+2*j+2] = rot.dot(tmp[j])

        self.ticklbls = RenderObject(gl.GL_TRIANGLES, vertex=ticklbls, color=white, texcoords=texcoords)

        vown = np.array([0.0, 0.0, 0.0, -0.12, 0.065, -0.03, -0.065, -0.03, 0.022, -0.1, -0.022, -0.1], dtype=np.float32)
        self.ownship = RenderObject(gl.GL_LINES, vertex=vown, color=yellow)

        self.spdlabel_text = self.font.prepare_text_string('GS    TAS', 0.05, white, (-0.98, 1.6))
        self.spdlabel_val  = self.font.prepare_text_string('  000    000', 0.05, green, (-0.97, 1.6))

        self.initialized = True
        # Unbind everything
        RenderObject.unbind_all()
示例#12
0
    def initializeGL(self):
        """Initialize OpenGL, VBOs, upload data on the GPU, etc."""

        # First check for supported GL version
        gl_version = float(gl.glGetString(gl.GL_VERSION)[:3])
        if gl_version < 3.3:
            return

        # background color
        gl.glClearColor(0.15, 0.29, 0.55, 1.0)
        gl.glEnable(gl.GL_BLEND)
        gl.glBlendFunc(gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA)

        self.color_shader = BlueSkyProgram('data/graphics/shaders/aman-normal.vert', 'data/graphics/shaders/aman-color.frag')
        self.text_shader = BlueSkyProgram('data/graphics/shaders/aman-text.vert', 'data/graphics/shaders/aman-text.frag')

        # Use the same font as the radarwidget
        self.font = self.shareWidget.font.copy()
        self.font.init_shader(self.text_shader)

        fixed_lines = np.array([
            -1.0,  1.1, 1.0,  1.1,
            -0.12, -1.2,  -0.12, 1.2,
            0.12, -1.2,  0.12, 1.2,
            -0.12, -1.1, 0.12, -1.1], dtype=np.float32)

        self.fixed = RenderObject(gl.GL_LINES, vertex_count=8)
        self.fixed.bind_attrib(ATTRIB_VERTEX, 2, fixed_lines)
        self.fixed.bind_attrib(ATTRIB_COLOR, 3, np.array(white, dtype=np.uint8), datatype=gl.GL_UNSIGNED_BYTE, normalize=True, instance_divisor=1)

        ticks = np.zeros(400, dtype=np.float32)
        for i in range(50):
            y = -1.1 + 0.055 * i
            w = 0.025
            if i % 5 == 0:
                w = 0.05

            ticks[i*8:(i+1)*8] = [-0.12, y, w-0.12, y, 0.12, y, 0.12-w, y]

        self.scale = RenderObject(gl.GL_LINES, vertex_count=200)
        self.scale.bind_attrib(ATTRIB_VERTEX, 2, ticks)
        self.scale.bind_attrib(ATTRIB_COLOR, 3, np.array(white, dtype=np.uint8), datatype=gl.GL_UNSIGNED_BYTE, normalize=True, instance_divisor=1)

        scaletxt_vert = np.zeros(240, dtype=np.float32)
        self.scaletxt_texc = np.zeros(360, dtype=np.float32)
        for i in range(10):
            y = -1.1 - 0.025 + 0.275 * i
            scaletxt_vert[24*i:24*i+12],    self.scaletxt_texc[36*i:36*i+18] = Font.char(-0.025, y, 0.025, 0.05, 48 + (5*i)/10)
            scaletxt_vert[24*i+12:24*i+24], self.scaletxt_texc[36*i+18:36*i+36] = Font.char(0.0, y, 0.025, 0.05, 48 + (5*i)%10)

        self.scaletxt = RenderObject(gl.GL_TRIANGLES, vertex_count=120)
        self.scaletxt.bind_attrib(ATTRIB_VERTEX, 2, scaletxt_vert)
        self.scaletxt_buf = self.scaletxt.bind_attrib(ATTRIB_TEXCOORDS, 3, self.scaletxt_texc)
        self.scaletxt.bind_attrib(ATTRIB_COLOR, 3, np.array(white, dtype=np.uint8), datatype=gl.GL_UNSIGNED_BYTE, normalize=True, instance_divisor=1)
        self.scaletxt.char_size = 0.025
        self.scaletxt.block_size = (0, 0)
        self.aclblbuf = create_empty_buffer(MAX_NAIRCRAFT * 32, usage=gl.GL_STREAM_DRAW)
        self.accolorbuf = create_empty_buffer(MAX_NAIRCRAFT * 3, usage=gl.GL_STREAM_DRAW)
        self.acposybuf = create_empty_buffer(MAX_NAIRCRAFT * 4, usage=gl.GL_STREAM_DRAW)
        v, t = Font.char(-0.98, 0.0, 0.025, 0.05, 48)
        self.aclbls = RenderObject(gl.GL_TRIANGLES, vertex_count=32*6)
        self.aclbls.bind_attrib(ATTRIB_VERTEX, 2, np.array(v, dtype=np.float32))
        self.aclbls.bind_attrib(ATTRIB_COLOR, 3, self.accolorbuf, datatype=gl.GL_UNSIGNED_BYTE, normalize=True, instance_divisor=32)
        self.aclbls.bind_attrib(ATTRIB_TEXDEPTH, 1, self.aclblbuf, datatype=gl.GL_UNSIGNED_BYTE, instance_divisor=1)
        self.aclbls.bind_attrib(ATTRIB_OFFSETY, 1, self.acposybuf, instance_divisor=32)
        self.aclbls.char_size = 0.025
        self.aclbls.block_size = (32, 1)

        self.rwylbl = self.font.prepare_text_string('18R', 0.05, (1.0, 1.0, 1.0), (-0.98, 1.11))
        self.timelbl = self.font.prepare_text_string('00:00', 0.035, (1.0, 1.0, 1.0), (-0.0875, -1.19))
        # Unbind everything
        RenderObject.unbind_all()