Reputation: 1191
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.
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.
As you can see in the code, I use the same zoom factor for X and Y.
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?
An image is better than a thousands words:
Here's some 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 < myEngine.myWorldTiles.maxTileX; ++x)
{
for(int y = 0; y < 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();
}
}
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;
}
}
in the JFrame init code
contentPanel.add(myWorld.myEngine.getCanvas(), BorderLayout.CENTER);
Upvotes: 0
Views: 2331
Reputation: 5423
You have to setup the projection matrix each time the window resizes. I haven't used JOGL before but I think you should do it in that reshape
method in the code.
Upvotes: 2