Hello,
I have a program which paints 2 textures (800x600) onto 2D rectangles in 3D space. Each texture is rendered with a TextureRenderer using Chris Cambell’s method from the BezierAnim3D demo. However, sometimes it crashes after using it for a few minutes (I can’t reproduce it reliably) with the following trace:
exception in QueueFlusher:
javax.media.opengl.GLException: glGetError() returned the following error codes after a call to glEnd(): GL_OUT_OF_MEMORY
at javax.media.opengl.DebugGL.checkGLGetError(DebugGL.java:12715)
at javax.media.opengl.DebugGL.glEnd(DebugGL.java:1929)
at prefuse3D.LayoutPlane.displayPrefuseRenderer(LayoutPlane.java:1349)
at prefuse3D.LayoutPlane.display(LayoutPlane.java:1510)
at prefuse3D.Display3D.render(Display3D.java:2114)
at prefuse3D.Display3D.display(Display3D.java:1832)
at com.sun.opengl.impl.GLDrawableHelper.display(GLDrawableHelper.java:78)
at javax.media.opengl.GLJPanel$Updater.display(GLJPanel.java:1046)
at javax.media.opengl.GLJPanel$DisplayAction.run(GLJPanel.java:1203)
at com.sun.opengl.impl.GLDrawableHelper.invokeGL(GLDrawableHelper.java:194)
at javax.media.opengl.GLJPanel$2.run(GLJPanel.java:629)
at sun.java2d.opengl.OGLRenderQueue$QueueFlusher.run(OGLRenderQueue.java:203)
I tried to use texture.getEstimatedMemorySize() and it is 6380660 and constant throughout. The rendering code follows. Any suggestions would be appreciated!
private void displayPrefuseRenderer(GL gl) {
// Draw to the animRenderer's texture using Java 2D
gl.glBlendFunc( GL.GL_ONE, GL.GL_ONE_MINUS_SRC_ALPHA);
// Draw from the animRenderer's texture using JOGL
if (repaint) {
updateAnimRenderer();
tex = prefuseRenderer.getTexture();
repaint = false;
}
// constant getTexture() doesn't slow it down, redraw (update) texture does
TextureCoords tc = tex.getImageTexCoords();
float tx1 = tc.left();
float ty1 = tc.top();
float tx2 = tc.right();
float ty2 = tc.bottom();
// Use the GL_MODULATE texture function to effectively multiply
// each pixel in the texture by the current alpha value
gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, GL.GL_MODULATE);
double x = -bounds.getWidth()/2;
double y = -bounds.getHeight()/2;
double w = bounds.getWidth();
double h = bounds.getHeight();
tex.bind();
tex.enable();
// draw at an offset equivalent to the plane's fill offset
gl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL.GL_FILL);
gl.glEnable(GL.GL_POLYGON_OFFSET_FILL);
gl.glPolygonOffset(2f, 2f);
gl.glBegin(GL.GL_QUADS);
// Render image
float a = 255;
gl.glColor4f(a, a, a, a);
gl.glTexCoord2f(tx1, ty1); gl.glVertex3d(x , y+h, 0f);
gl.glTexCoord2f(tx2, ty1); gl.glVertex3d(x+w, y+h, 0f);
gl.glTexCoord2f(tx2, ty2); gl.glVertex3d(x+w, y , 0f);
gl.glTexCoord2f(tx1, ty2); gl.glVertex3d(x , y , 0f);
gl.glEnd(); [b]<- this is line 1349 from the stack trace[/b]
tex.disable();
gl.glBlendFunc( GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA );
}
private void initPrefuseRenderer() {
// Create the BezierAnim renderer
prefuseRenderer = new TextureRenderer((int)getWidth(),(int)getHeight(), true);
}
private void updateAnimRenderer() {
Graphics2D g2d = prefuseRenderer.createGraphics();
paintDisplay(g2d, getBounds().getSize());
g2d.dispose();
prefuseRenderer.markDirty(0, 0, (int)getWidth(), (int)getHeight());
}