title: Unable to maintain uniform scale when resizing window, OpenGL + Java = JOGL
body: <p>I'm using JOGL (Java OpenGL wrapper) for the first time and I have an issue I can't figure out, I'm not sure if this is related to JOGL or OpenGL in general.</p>
  
  <p>I render on a GLCanvas inside a JPanel inside a JForm (the whole point of the program is to mix OpenGL and SWING). As of now I'm drawing simple 2D (ortho) triangles (they'll be tiles), I would like them to scale according to the size of the viewport (panel?). 
  I achieved scaling but for some reason the image is stretched, as if scale ratio was not the same on the X component and the Y component, when I resize the window.
  I.e. they should maintain the same square ratio, but they get stretched instead.</p>
  
  <p>As you can see in the code, I use the same zoom factor for X and Y.</p>
  
  <p>I don't understand if the error is in my OpenGL code or in my SWING-JOGL code.
  Can anyone point me in the right direction?</p>
  
  <p>An image is better than a thousands words:
  <img src="https://i.stack.imgur.com/EoD7h.png" alt="The streching effect after resizing the window"></p>
  
  <p>Here's some code:</p>
  
  <h2>The OpenGL code</h2>
  
  <pre><code>class Graphics {
  
  /**
   * The default ratio between the screen size and the tile size, before zoom is applied
   */
  final static float DEFAULT_TILE_TO_SCREEN = 0.5f;
  
  /**
   * The parent engine
   */
  protected Engine myEngine; 
  
  Graphics(Engine e)
  {
      myEngine = e;
  }
  
  /**
   * Sets up viewport
   * @param gl2
   * @param width
   * @param height 
   */
  void setup( GL2 gl2, int width, int height ) {
      gl2.glMatrixMode( GL2.GL_PROJECTION );
      gl2.glLoadIdentity();
  
      // coordinate system origin at lower left with width and height same as the window
      GLU glu = new GLU();
      glu.gluOrtho2D( 0.0f, width, 0.0f, height );
  
      gl2.glMatrixMode( GL2.GL_MODELVIEW );
      gl2.glLoadIdentity();
  
      gl2.glViewport( 0, 0, width, height );
  }
  
  /**
   * Renders viewport
   * @param gl2
   * @param width
   * @param height 
   */
  void render( GL2 gl2, int width, int height ) {
      final float zoomFactor = DEFAULT_TILE_TO_SCREEN * myEngine.myZoomLevel;
      final float zoom = Math.max(height *  zoomFactor, width * zoomFactor);
      gl2.glClear( GL.GL_COLOR_BUFFER_BIT );
  
      // draw a triangle filling the window
      gl2.glLoadIdentity();
      gl2.glScalef(zoom, zoom, 1);
      gl2.glBegin( GL.GL_TRIANGLES );
      for(int x = 0; x &lt; myEngine.myWorldTiles.maxTileX; ++x)
      {
          for(int y = 0; y &lt; myEngine.myWorldTiles.maxTileY; ++y)
          {
              gl2.glColor3f( 1, 0, 0 );
              gl2.glVertex2f( x + 0.f, y + 0.f );
              gl2.glVertex2f( x + 1.f, y + 0.f );
              gl2.glVertex2f( x + 1.f, y + 1.f );
  
              gl2.glColor3f( 0, 0, 1 );
              gl2.glVertex2f( x + 0.f, y + 0.f );
              gl2.glVertex2f( x + 1.f, y + 1.f );
              gl2.glVertex2f( x + 0.f, y + 1.f );
          }
      }
       gl2.glEnd();
  }
  
  }
  </code></pre>
  
  <h2>The SWING integration code</h2>
  
  <pre><code>public class Engine {
  
  /**
   * The internal rendering canvas
   */
  private GLCanvas    myCanvas;
  /**
   * The graphics used for rendering
   */
  private Graphics    myGraphics;   
  
  /**
   * The zoom level of the graphics
   */
  float       myZoomLevel = 1;
  /**
   * The world map
   */
  TileList    myWorldTiles;
  
  /**
   * The currently centered tile
   */
  Point       myCenteredTile;
  
  public Engine(TileList worldTile)
  {
      myWorldTiles = worldTile;
      GLProfile glprofile = GLProfile.getDefault();
      GLCapabilities glcapabilities = new GLCapabilities( glprofile );
      myCanvas = new GLCanvas( glcapabilities );
  
      myGraphics = new Graphics(this);
      myCanvas.addGLEventListener( new GLEventListener() {
  
          @Override
          public void reshape( GLAutoDrawable glautodrawable, int x, int y, int width, int height ) {
          }
  
          @Override
          public void init( GLAutoDrawable glautodrawable ) {
              myGraphics.setup( glautodrawable.getGL().getGL2(), glautodrawable.getWidth(), glautodrawable.getHeight() );
          }
  
          @Override
          public void dispose( GLAutoDrawable glautodrawable ) {
          }
  
          @Override
          public void display( GLAutoDrawable glautodrawable ) {
              myGraphics.render( glautodrawable.getGL().getGL2(), glautodrawable.getWidth(), glautodrawable.getHeight() );
          }
      });
  
  }
  
  /**
   * Sets the zoom level for the screen
   * @param zoom 
   */
  public void setZoomLevel(float zoom)
  {
      myZoomLevel = zoom;
  }
  
  /**
   * Gets the 3D canvas, should be placed in user-defined form/window/panel 
   */
  public java.awt.Component getCanvas()
  {
      return myCanvas;
  }
  
  /**
   * Centers the screen on the given tile
   * @param p 
   */
  public void centerOnTile(Point p)
  {
      myCenteredTile = p;
  }
  }
  </code></pre>
  
  <h2>Also</h2>
  
  <p>in the JFrame init code</p>
  
  <pre><code>contentPanel.add(myWorld.myEngine.getCanvas(), BorderLayout.CENTER);
  </code></pre>