【问题标题】:Unable to maintain uniform scale when resizing window, OpenGL + Java = JOGL调整窗口大小时无法保持统一比例,OpenGL + Java = JOGL
【发布时间】:2011-10-02 16:22:39
【问题描述】:

我是第一次使用 JOGL(Java OpenGL 包装器),但有一个我无法弄清楚的问题,我不确定这是否与 JOGL 或 OpenGL 相关。

我在 JForm 内的 JPanel 内的 GLCanvas 上进行渲染(程序的重点是混合 OpenGL 和 SWING)。到目前为止,我正在绘制简单的 2D(正交)三角形(它们将是瓷砖),我希望它们根据视口(面板?)的大小进行缩放。 我实现了缩放,但由于某种原因,当我调整窗口大小时,图像被拉伸,好像 X 分量和 Y 分量的缩放比例不同。 IE。它们应该保持相同的平方比,但它们会被拉伸。

正如您在代码中看到的,我对 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);

【问题讨论】:

标签: opengl 3d jogl


【解决方案1】:

您必须在每次调整窗口大小时设置投影矩阵。我以前没有使用过 JOGL,但我认为您应该在代码中的 reshape 方法中使用它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-05
    • 1970-01-01
    • 1970-01-01
    • 2013-09-01
    • 2015-01-31
    • 1970-01-01
    相关资源
    最近更新 更多