Я впервые использую JOGL (оболочку Java OpenGL), и у меня есть проблема, которую я не могу понять, я не уверен, связано ли это с JOGL или OpenGL в целом.
Я рендеринг на GLCanvas внутри JPanel внутри JForm (весь смысл программы в том, чтобы смешать OpenGL и SWING).На данный момент я рисую простые 2D (орто) треугольники (они будут плитками), я бы хотел, чтобы они масштабировались в соответствии с размером области просмотра (панели?).Я достиг масштабирования, но по какой-то причине изображение растянуто, как если бы я изменил размер окна, если масштабирование не было одинаковым для компонента X и компонента Y.Т.е. они должны поддерживать одинаковое квадратное соотношение, но вместо этого они растягиваются.
Как вы можете видеть в коде, я использую одинаковый коэффициент масштабирования для X и Y.
Я непонять, есть ли ошибка в моем коде OpenGL или в моем коде SWING-JOGL.Кто-нибудь может указать мне правильное направление?
Изображение лучше, чем тысячи слов:
Вот код:
Код OpenGL
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();
}
}
Код интеграции SWING
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;
}
}
Также
в коде инициализации JFrame
contentPanel.add(myWorld.myEngine.getCanvas(), BorderLayout.CENTER);