Serious problems with JOGL backend
Serious problems with JOGL backend
I have got a serious problem with the JOGL backend when using medium sized geometry. I've got a 512x512 QuadMesh grid in a SceneComponentGraph node. So far everything works fine.
But when I remove that scene node, regenerate the node, add the node again (and I repeat that process maybe once more) my geometry suddenly doesn't show up after the add at all anymore. And it never comes back even when I continue removing and adding.
It just renders a blank scene.
However no error messages comes up onto the console.
Strangely enough when I reduce the grid to 256^2 it never seems to happen.
Also it only seems to happen with filled triangles when I render points it doesn't seem to happen.
But when I remove that scene node, regenerate the node, add the node again (and I repeat that process maybe once more) my geometry suddenly doesn't show up after the add at all anymore. And it never comes back even when I continue removing and adding.
It just renders a blank scene.
However no error messages comes up onto the console.
Strangely enough when I reduce the grid to 256^2 it never seems to happen.
Also it only seems to happen with filled triangles when I render points it doesn't seem to happen.
This is indeed mysterious. Here's one thing you can do to try to debug it.
Sometimes display lists in the JOGL backend cause problems.
Another thing you can try is not to remove the SceneGraphComponent, but use the sgc.setVisible(false) method to deactivate the rendering. Then change the geometry, and set the scene graph component to be visible again. Does that show the same problem?
Finally, if it's possible to wrap up the offending code in a small example, you're welcome to post it here, then I can run it and see what's happening, hopefully.
Code: Select all
ap.setAttribute(CommonAttributes.ANY_DISPLAY_LISTS, false);
Another thing you can try is not to remove the SceneGraphComponent, but use the sgc.setVisible(false) method to deactivate the rendering. Then change the geometry, and set the scene graph component to be visible again. Does that show the same problem?
Finally, if it's possible to wrap up the offending code in a small example, you're welcome to post it here, then I can run it and see what's happening, hopefully.
jReality core developer
Yeah that removes the problem but sure slows down the performance. I am surprised that JOGL is using display lists they are known as being not any longer recommended to use by most IHVs and are considered to be outdated for modern graphics hardware.gunn wrote:This is indeed mysterious. Here's one thing you can do to try to debug it.
Sometimes display lists in the JOGL backend cause problems.Code: Select all
ap.setAttribute(CommonAttributes.ANY_DISPLAY_LISTS, false);
I will try this as well but unfortunately that will not work in all of my cases since sometimes the grid size might change over the course of runtime.Another thing you can try is not to remove the SceneGraphComponent, but use the sgc.setVisible(false) method to deactivate the rendering. Then change the geometry, and set the scene graph component to be visible again. Does that show the same problem?
Okay that shouldn't be a problem I am sure I can modify one of the tutorial examples to do the same thing.Finally, if it's possible to wrap up the offending code in a small example, you're welcome to post it here, then I can run it and see what's happening, hopefully.
I don't think that will cause problems. You can simply overwrite the geometry of the scene graph component using the setGeometry() method on SceneGraphComponent. In fact, you should be able to do this without calling setVisible(false) beforehand. If you try this, let me know if you still have to turn off display lists.I will try this as well but unfortunately that will not work in all of my cases since sometimes the grid size might change over the course of runtime.
A final hint regarding OpenGL problems: try running the application with the VM option -Djava.jreality.debugGL=true set. This will catch some OpenGL exceptions that normally go unreported.
Yes that's something I've heard. But until we get vertex arrays working 100%, (and with some of the jReality shading options it's somewhat tricky) they still provide a significant speed-up, as you've found out.Yeah that removes the problem but sure slows down the performance. I am surprised that JOGL is using display lists they are known as being not any longer recommended to use by most IHVs and are considered to be outdated for modern graphics hardware.
jReality core developer
I will do this but my feeling is that the display list is maybe getting too big I am not sure but I think remembering in the old OpenGL days there was a problem with that.gunn wrote:I don't think that will cause problems. You can simply overwrite the geometry of the scene graph component using the setGeometry() method on SceneGraphComponent. In fact, you should be able to do this without calling setVisible(false) beforehand. If you try this, let me know if you still have to turn off display lists.I will try this as well but unfortunately that will not work in all of my cases since sometimes the grid size might change over the course of runtime.
Thanks I will try this that will definitely help to narrow it.A final hint regarding OpenGL problems: try running the application with the VM option -Djava.jreality.debugGL=true set. This will catch some OpenGL exceptions that normally go unreported.
Hmm yes I had a short glimpse at the JOGL backend code. Rewriting it to use VBOs looks to be like quite a massive task not sure if it is worth for the user group jReality is targeting.Yes that's something I've heard. But until we get vertex arrays working 100%, (and with some of the jReality shading options it's somewhat tricky) they still provide a significant speed-up, as you've found out.
But looking at how it is at the moment as a rough personal estimate you're probably get a tenth of the actual possible OpenGL throughput performance. Not sure how much JOGL eats up of that though.
Thanks gunn that works :D without using setVisible and without deactivating DisplayList. Okay that will hopefully do the trick for now I think I can restructure my code to work around this problem for the time being.gunn wrote: I don't think that will cause problems. You can simply overwrite the geometry of the scene graph component using the setGeometry() method on SceneGraphComponent. In fact, you should be able to do this without calling setVisible(false) beforehand. If you try this, let me know if you still have to turn off display lists.
Btw activating OpenGL debug didn't come up with anything useful :(.
If you are still interested I can post some code that levitates the problem.
Sure gunn no problem
And
Just press 1 and 0 a couple of times and probably after the third time it disappears (on my machine). Or suprisingly enough when you change the 512 in createSurface to lets say 768 it doesn't even render the first time.
Code: Select all
import javax.swing.JFrame;
import java.awt.event.KeyListener;
import java.awt.*;
import de.jreality.geometry.QuadMeshFactory;
import de.jreality.scene.*;
import de.jreality.shader.CommonAttributes;
import de.jreality.shader.DefaultGeometryShader;
import de.jreality.shader.DefaultLineShader;
import de.jreality.ui.viewerapp.ViewerApp;
import de.jreality.util.SceneGraphUtility;
import de.jreality.shader.ShaderUtility;
import de.jreality.util.CameraUtility;
public class MeshFrame implements KeyListener {
private SceneGraphComponent dispGraph = null;
private SceneGraphComponent root;
private IndexedFaceSet createSurface( int N, int mode ) {
double [][][] coords = new double [N][N][3];
double [][][] colors = new double [N][N][3];
for( int i=0; i<N; i++) {
double v = -.4 + .8*(i/(N-1.0));
for (int j = 0; j<N; ++j) {
double u = -.3 + .6*(j/(N-1.0));
coords[i][j][0] = 10.0f - (20.0f/(float)N) * (float)(i);
coords[i][j][1]= 10.0f - (20.0f/(float)N) * (float)(j);
if (mode == 0)
coords[i][j][2]= Math.sin((i+j)*0.1);
else
coords[i][j][2]= Math.cos((i+j)*0.01);
colors[i][j][2]= Math.max(0.5 + 0.5 * coords[i][j][2],0.0);
}
}
QuadMeshFactory factory = new QuadMeshFactory();
factory.setVLineCount(N);
factory.setULineCount(N);
factory.setClosedInUDirection(false);
factory.setClosedInVDirection(false);
factory.setVertexCoordinates(coords);
factory.setVertexColors(colors);
factory.setGenerateFaceNormals(true);
factory.setGenerateTextureCoordinates(true);
factory.setGenerateEdgesFromFaces(true);
factory.setEdgeFromQuadMesh(true);
factory.update();
return factory.getIndexedFaceSet();
}
private SceneGraphComponent buildNewGraph(int mode,
char renderMode)
{
SceneGraphComponent graph =
SceneGraphUtility.createFullSceneGraphComponent("graph");
graph.setGeometry(createSurface(512,mode));
Appearance ap = graph.getAppearance();
ap.setAttribute(CommonAttributes.LIGHTING_ENABLED,false);
//ap.setAttribute(CommonAttributes.ANY_DISPLAY_LISTS, false);
DefaultGeometryShader dgs = ShaderUtility.createDefaultGeometryShader(ap, true);
if (renderMode == 'f' ||
renderMode == 'F')
{
dgs.setShowFaces(true);
dgs.setShowLines(false);
dgs.setShowPoints(false);
} else {
dgs.setShowFaces(false);
dgs.setShowLines(true);
dgs.setShowPoints(false);
}
DefaultLineShader dls = (DefaultLineShader) dgs.createLineShader("default");
dls.setLineLighting(false);
dls.setTubeDraw(false);
dls.setLineWidth(1.0);
dls.setVertexColors(true);
return graph;
}
public MeshFrame()
{
root = SceneGraphUtility.createFullSceneGraphComponent("world");
JFrame f = new JFrame();
ViewerApp va = new ViewerApp(root);
dispGraph = buildNewGraph(0,'F');
root.addChild(dispGraph);
Camera sceneCamera =
CameraUtility.getCamera( va.getCurrentViewer());
sceneCamera.setFieldOfView(60);
sceneCamera.setNear(1.0);
sceneCamera.setFar(100);
CameraUtility.encompass( va.getCurrentViewer());
Component comp = (Component)va.getViewingComponent();
comp.addKeyListener(this);
f.getContentPane().add(comp);
f.setSize(512, 512);
f.validate();
f.setVisible(true);
}
public void keyPressed(java.awt.event.KeyEvent e)
{
}
public void keyReleased(java.awt.event.KeyEvent e)
{
}
public void keyTyped(java.awt.event.KeyEvent e)
{
if (e.getKeyChar() == '0' ||
e.getKeyChar() == '1')
{
root.removeChild(dispGraph);
dispGraph = null;
System.gc();
if (e.getKeyChar() == '0')
dispGraph = buildNewGraph(0,'F');
else
dispGraph = buildNewGraph(1,'F');
root.addChild(dispGraph);
}
}
}
Code: Select all
public class MeshFrameExample {
public static void main(String[] args) {
MeshFrame f = new MeshFrame();
}
}
Thanks for the code. I ran it as suggested. On my machine, using the parameter 512, it runs slow but I can toggle between '0' and '1' without any problems. When I set the parameter to 768, on the second iteration I ran out of memory. When I set the memory up from 1G to 3G, I was also able to toggle this a couple times -- more I didn't have time for.
So it seems to depend on the configuration of the system you're running. Of course, if you don't need to set vertex colors, vertex normals, edges, etc, you'll have that much more free space. Also, to see how much memory you're using you can use the InfoOverlay class. Add following code to MeshFrame() method: (see this tutorial for another example).
[/url]
So it seems to depend on the configuration of the system you're running. Of course, if you don't need to set vertex colors, vertex normals, edges, etc, you'll have that much more free space. Also, to see how much memory you're using you can use the InfoOverlay class. Add following code to MeshFrame() method: (see this tutorial for another example).
Code: Select all
import de.jreality.jogl.plugin.InfoOverlay
...
if (va.getCurrentViewer() instanceof de.jreality.jogl.Viewer) {
InfoOverlay io =InfoOverlay.perfInfoOverlayFor((de.jreality.jogl.Viewer)va.getCurrentViewer());
io.setVisible(true);
}
jReality core developer
Hmm so it could be platform related either it is a problem in the Windows 32bit JOGL implementation or it's the OpenGL NVidia driver. I can try updating it. I haven't checked this particular program on a Linux machine. Btw 512^2 runs at acceptable speed when using VertexArrays for me.gunn wrote:Thanks for the code. I ran it as suggested. On my machine, using the parameter 512, it runs slow but I can toggle between '0' and '1' without any problems.
Strange again I can run 768 with 1G of Java heapgunn wrote: When I set the parameter to 768, on the second iteration I ran out of memory. When I set the memory up from 1G to 3G, I was also able to toggle this a couple times -- more I didn't have time for.
Thanks I will have a look at thatgunn wrote: Also, to see how much memory you're using you can use the InfoOverlay class. Add following code to MeshFrame() method: