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)
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)
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)
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)
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
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)
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
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
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)
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()
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()
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()