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

How can I clear the screen in openGL using Java

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

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

// 测试 GLAutoDrawable 测试 = 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();
    }

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

我不熟悉 Java 的 OpenGL 绑定,但我猜该库在调用 display() 函数后已经为您做了这件事。在 keyTyped().

之后它不会这样做

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

编辑: 自己打电话 display() 是不够的。我找不到如何使 Java 中的 window 无效(在 C 中这会容易得多)。作为肮脏的 hack,您可以尝试在 display 中手动调用 temp.swapBuffers(),设置 setAutoSwapBufferMode(false) 并从 keyTyped().

调用 display

1) 那是 deprecated OpenGL,不要用它

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

中获取它

3) 使用着色器程序进行渲染,并使用顶点缓冲区来保存顶点位置。但首先,我建议您开始学习 OpenGL 的基础教程。或者,如果你想让某些东西尽快工作,请克隆我的这个 hello triangle 并开始在那个

上进行实验