如何使用Java清除openGL中的屏幕

时间:2016-09-14 14:41:09

标签: java opengl jogl

我不明白在使用OpenGL时如何在Java中清除屏幕。我在互联网上搜索过,没有真正的OpenGL信息资源。基本上我只想清除屏幕并重新画一个圆圈。相反,我的代码决定它不会清除屏幕,它绝对不会绘制任何其他东西..当我按“e”时我希望它清除屏幕,然后绘制一个新的圆圈。我有两个java文件..我只会发布相关代码,以便任何可以帮助我的用户 - 但如果需要,会发布更多代码。

在我的 JOGLEventListener.java 文件的开头,我还声明了一个全局变量

//测试 GLAutoDrawable test = null;

JOGLEventListener.java

    @Override
    public void display(GLAutoDrawable gLDrawable) 
    {
        // Set a global variable to hold the gLDrawable
        // May not need this?
        test = gLDrawable;

         GL2 gl = gLDrawable.getGL().getGL2();

        gl.glClearColor(backrgb[0], 0, 1, 1);
        gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);

        backrgb[0]+=0.0005;
        if (backrgb[0]> 1) backrgb[0] = 0; 


        // =============================================
        // Draw my circle here
        //
        // =============================================
        // =============================================
        System.out.println("Drawing Circle..");
        drawCircle(5.0f, 5.0f, 10.0f);

    }

    // Draw Circle
    void drawCircle(float x, float y, float radius)
    {
        System.out.println("IN DRAWCIRCLE");
        int i;
        GL2 gl = test.getGL().getGL2();
        int lineAmount = 100; //# of triangles used to draw circle
        final 
        //GLfloat radius = 0.8f; //radius
        float twicePi = (float) (2.0f * Math.PI);

        gl.glBegin(gl.GL_LINE_LOOP);
            for(i = 0; i <= lineAmount;i++) { 
                gl.glVertex2f(
                    x + (radius * (float)Math.cos(i *  twicePi / lineAmount)), 
                    y + (radius* (float)Math.sin(i * twicePi / lineAmount))
                );
            }
        gl.glEnd();
    }

@Override
public void keyTyped(KeyEvent e) 
{
    char key= e.getKeyChar();
    System.out.printf("Key typed: %c\n", key); 
    GL2 gl = test.getGL().getGL2();
    if(key == 'e')
    {
        // WHY ISNT THIS WORKING
        // CLEAR THE SCREEN AND DRAW ME A NEW CIRCLE
        gl.glClear( gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT );     
        gl.glLoadIdentity();                    
        //test
        float x = 100.0f;
        float y = 100.0f;
        float twicePi = (float) (2.0f * Math.PI);
        float radius = 100f;

        System.out.println("Draw Another Circle...");
        gl.glBegin(gl.GL_LINE_LOOP);
        for(int i = 0; i <= 360;i++) 
        { 
            gl.glVertex2f(
                x + (radius * (float)Math.cos(i *  twicePi / 360)), 
                y + (radius* (float)Math.sin(i * twicePi / 360))
            );
        }
        gl.glEnd();
    }

2 个答案:

答案 0 :(得分:1)

1)那是deprecated OpenGL,不要使用它

2)不要将gl对象保存为一个全局值,始终从drawableGLContext

获取

3)使用着色器程序进行渲染,使用顶点缓冲区来保持顶点位置。但首先,我建议你开始学习OpenGL的基础知识。或者如果你想尽快得到一些工作,请克隆我的hello triangle并开始尝试

答案 1 :(得分:0)

问题显然是你没有交换前后缓冲区。

我不熟悉Java的OpenGL绑定,但我想在调用display()函数之后,库已经为你做了。它在keyTyped()之后没有这样做。

您应该这样做的方法是始终根据某些内部状态在display()函数内从头开始绘制场景。然后在keyTyped()中,您将修改该内部状态并使窗口无效,这将导致再次调用display()并正确地重绘场景。

编辑:自己致电display()已经不够了。我无法找到如何在Java中使窗口无效(在C中这将更容易)。作为一个肮脏的黑客,您可以尝试在temp.swapBuffers()中手动拨打display,设置setAutoSwapBufferMode(false)并从display拨打keyTyped()