如何使用 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
对象保存为一个全局值,始终从 drawable
或 GLContext
中获取它
3) 使用着色器程序进行渲染,并使用顶点缓冲区来保存顶点位置。但首先,我建议您开始学习 OpenGL 的基础教程。或者,如果你想让某些东西尽快工作,请克隆我的这个 hello triangle 并开始在那个
上进行实验
我不明白如何在使用 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
对象保存为一个全局值,始终从 drawable
或 GLContext
3) 使用着色器程序进行渲染,并使用顶点缓冲区来保存顶点位置。但首先,我建议您开始学习 OpenGL 的基础教程。或者,如果你想让某些东西尽快工作,请克隆我的这个 hello triangle 并开始在那个
上进行实验