我第一次使用JOGL(Java OpenGL包装器)而且我有一个我无法弄清楚的问题,我不确定这是否与JOGL或OpenGL有关。
我在JForm内部的JPanel内的GLCanvas上渲染(程序的整个点是混合OpenGL和SWING)。截至目前我正在绘制简单的2D(正交)三角形(它们将是瓷砖),我希望它们根据视口(面板?)的大小进行缩放。 我实现了缩放,但由于某种原因,当我调整窗口大小时,图像被拉伸,就像X组件和Y组件上的缩放比例不同一样。 即他们应保持相同的平方比例,但他们会被拉伸。
正如您在代码中看到的,我对X和Y使用相同的缩放系数。
我不明白错误是在我的OpenGL代码中还是在我的SWING-JOGL代码中。 有人能指出我正确的方向吗?
图像胜过千言万语:
以下是一些代码:
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;
}
}
在JFrame初始化代码
中contentPanel.add(myWorld.myEngine.getCanvas(), BorderLayout.CENTER);
答案 0 :(得分:2)
每次调整窗口大小时都必须设置投影矩阵。我之前没有使用JOGL,但我认为你应该在代码中使用reshape
方法。