arcgissamples\display\ShowCompassCommand.java
/* Copyright 2010 ESRI * * All rights reserved under the copyright laws of the United States * and applicable international laws, treaties, and conventions. * * You may freely redistribute and use this sample code, with or * without modification, provided you include the original copyright * notice and use restrictions. * * See the use restrictions. * */ package arcgissamples.display; import java.io.File; import java.io.IOException; import javax.media.opengl.GL; import javax.media.opengl.GLContext; import javax.media.opengl.GLDrawableFactory; import com.esri.arcgis.carto.Map; import com.esri.arcgis.controls.BaseCommand; import com.esri.arcgis.controls.HookHelper; import com.esri.arcgis.display.DisplayTransformation; import com.esri.arcgis.display.IDisplay; import com.esri.arcgis.display.IDynamicMapEventsAdapter; import com.esri.arcgis.display.IDynamicMapEventsAfterDynamicDrawEvent; import com.esri.arcgis.display.ITransformEventsAdapter; import com.esri.arcgis.display.ITransformEventsDeviceFrameUpdatedEvent; import com.esri.arcgis.display.esriDynamicMapDrawPhase; import com.esri.arcgis.interop.AutomationException; import com.esri.arcgis.system.esriDrawPhase; import com.esri.arcgis.system.tagRECT; class ShowCompassCommand extends BaseCommand { private static final long serialVersionUID = 1L; private HookHelper captainHook; private boolean checked = false; private Map map = null; public boolean isChecked() { return this.checked; } public void onCreate(Object hook) { try { this.captainHook = new HookHelper(); this.captainHook.setHookByRef(hook); } catch (Exception e) { e.printStackTrace(); } this.caption = "Add OpenGL Compass"; this.enabled = true; this.name = "Add OpenGL Compass"; String devKitHome = System.getenv("AGSDEVKITJAVA"); if(devKitHome == null){ System.err.println("The Java ArcObjects SDK has not been installed."); System.err.println("Please install the ArcObjects SDK for Java, then re-run this sample."); System.err.println("Exiting the application..."); System.exit(-1); } this.bitmapPath = devKitHome + "java" + File.separator + "samples" + File.separator + "data" + File.separator + "display" + File.separator + "compass_command.png"; } @Override public void onClick() { this.checked = !this.checked; this.enabled = !this.enabled; try { map = (Map) captainHook.getFocusMap(); //Enable dynamic mode map.setDynamicMapEnabled(true); map.setShowScrollBars(false); } catch (Exception e) { e.printStackTrace(); } try { if (this.checked) { //Add the dynamic map events listener //This is where we draw the compass in the AfterDynamicDraw event. map.addIDynamicMapEventsListener(new IDynamicMapEventsAdapter() { private static final long serialVersionUID = 1L; private GL gl = null; private GLContext context = null; private IDisplay Display; private tagRECT deviceFrame; private DisplayTransformation displayXformation; public void afterDynamicDraw( IDynamicMapEventsAfterDynamicDrawEvent theEvent) throws IOException, AutomationException { //Only react for the dynamic layers draw phase if (theEvent.getDynamicMapDrawPhase() != esriDynamicMapDrawPhase.esriDMDPDynamicLayers) return; try { //Setup OpenGL only once, create the display list for the compass if (context == null) { // Tell JOGL that we are going to use // our own OpenGL Context context = GLDrawableFactory.getFactory().createExternalGLContext(); context.makeCurrent(); gl = context.getGL(); Display = theEvent.getDisplay(); displayXformation = (DisplayTransformation) Display .getDisplayTransformation(); // get the device frame size deviceFrame = displayXformation .getDeviceFrame(); // start listening to display events // This will tell us how much to rotate the compass displayXformation.addITransformEventsListener(new ITransformEventsAdapter() { private static final long serialVersionUID = 1L; @Override public void deviceFrameUpdated( ITransformEventsDeviceFrameUpdatedEvent theEvent) throws IOException, AutomationException { deviceFrame = theEvent .getSender() .getDeviceFrame(); } }); createDisplayList(); } // Draw the compass display list gl.glPushMatrix(); gl.glLoadIdentity(); gl.glPushMatrix(); gl.glTranslatef( (float) deviceFrame.left + 70.0f, (float) deviceFrame.top + 70.0f, 0.0f); gl.glScalef(90.0f, 90.0f, 0.0f); gl.glRotatef((float) displayXformation .getRotation(), 0.0f, 0.0f, 1.0f); gl.glColor4f(1.0f, 1.0f, 1.0f, 1.0f); gl.glCallList(compassList); gl.glPopMatrix(); gl.glPopMatrix(); gl.glFlush(); } catch (Exception e) { e.printStackTrace(); } } private int compassList = 0; private void createDisplayList() { // create the display list for the compass // The quad size is set to 1 unit. Therefore you // will have to scale it // each time before drawing. gl.glEnable(GL.GL_TEXTURE_2D); final int[] tmp = new int[1]; gl.glGenTextures(1, tmp, 0); int textureId = tmp[0]; gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR); gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR); gl.glBindTexture(GL.GL_TEXTURE_2D, textureId); // open the compass bitmap ImageTexturizer.Texture imageTexture = null; String devKitHome = System.getenv("AGSDEVKITJAVA"); if(devKitHome == null){ System.err.println("The Java ArcObjects SDK has not been installed."); System.err.println("Please install the ArcObjects SDK for Java, then re-run this sample."); System.err.println("Exiting the application..."); System.exit(-1); } String compass = devKitHome + "java" + File.separator + "samples" + File.separator + "data" + File.separator + "display" + File.separator + "compass.gif"; try { imageTexture = ImageTexturizer.readTexture( compass, true); } catch (IOException e) { e.printStackTrace(); throw new RuntimeException(e); } gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGBA8, imageTexture.getWidth(), imageTexture.getHeight(), 0, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, imageTexture.getPixels()); compassList = gl.glGenLists(1); gl.glNewList(compassList, GL.GL_COMPILE); gl.glPushMatrix(); // shift the item 1/2 unit to the middle so that // it'll get drawn around the center gl.glTranslatef(-0.5f, -0.5f, 0.0f); // enable texture in order to allow for texture // binding gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, (int) GL.GL_MODULATE); // bind the texture gl.glEnable(GL.GL_TEXTURE_2D); gl.glBindTexture(GL.GL_TEXTURE_2D, (int) textureId); // create the geometry (quad) and specify the // texture coordinates gl.glBegin(GL.GL_QUADS); gl.glTexCoord2f(0.0f, 0.0f); gl.glVertex2f(0.0f, 0.0f); gl.glTexCoord2f(1.0f, 0.0f); gl.glVertex2f(1.0f, 0.0f); gl.glTexCoord2f(1.0f, 1.0f); gl.glVertex2f(1.0f, 1.0f); gl.glTexCoord2f(0.0f, 1.0f); gl.glVertex2f(0.0f, 1.0f); gl.glEnd(); gl.glPopMatrix(); gl.glEndList(); } }); } else { // Disable dynamic mode map.setDynamicMapEnabled(false); } this.captainHook.getActiveView().partialRefresh(esriDrawPhase.esriDPGeography, null, null); } catch (Exception e) { e.printStackTrace(); } } }