Slow rendering

I’ve finally got my first test program on my new engine running, and I’m encountering some speed issues. I’m only able to draw about 2 frames per second, in a scene that has maybe 600 traingles to render. At the moment, there are two lights, no changes in material settings, and geometry is rendered using VBOs.

I’m suspecting that the main culprit slowing me down is either JOGL’s or Java AWT’s event queue. When I profile, my display() function only takes about 33ms to execute. Also, for the first few seconds after I start my program, it runs fairly quickly - but performance degrades fast after the display has updated 50 frames or so.

At this early stage, my animation is pretty simple. I’ve added a KeyListener to the GLCanvas which decodes the keypress, updates the transform matrix I’m using to position my camera, and then calls display() on my GLCanvas. This causes the screen to refresh and redraw itself from the new camera position. (I implemented it this way because it seemed similar to how Animator works).

Any ideas what could be taking up so much time? Is there a more correct way to update the display in realtime in response to either a keypress or a timer tick?

If your program is slowly slowing down, it may be because you have a memory leak.
I suggest using jb2works reference scanner ; it has a very usefull functionnality that lets you place a reference scanner’s breakpoint inside your rendering loop.

   Vincent

What sort of frame rate ought I expect for a scene this small? Are there any examples of a fast animation loop drawing lots of triangles? With my current performance, I’d have a faster program if I was rendering with Java3D.

Profiling with the NetBeans profiler doesn’t show any memory leaks. The amount of heap allocated doesn’t change once the program gets going.

Hmm. When I change my engine to render everything as wireframes, the speed problem goes away, so it looks like my main rendering loop may be the problem after all. But it seems odd to me that JOGL would start to choke on 600 triangles stored in about 8 VBO buffers.

At the moment, I pretty much allocate my VBOs once at startup. Then, each frame I update my projection matrix for my camera and then for each object I do:

(in initializer)
gl.glEnableClientState(GL.GL_NORMAL_ARRAY);
gl.glEnableClientState(GL.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL.GL_TEXTURE_COORD_ARRAY);

    gl.glCullFace(GL.GL_BACK);
    gl.glEnable(GL.GL_CULL_FACE);

(in main render loop)

    Matrix4f modelWorld = page.getModelWorld();
    float[] columnMajor = MatrixOps.columnMajor(modelWorld, null);
    gl.glLoadMatrixf(columnMajor);

    
    gl.glBindBufferARB(GL.GL_ARRAY_BUFFER_ARB, mesh.getUvBufId());
    gl.glTexCoordPointer(2, GL.GL_FLOAT, 0, null);
    
    gl.glBindBufferARB(GL.GL_ARRAY_BUFFER_ARB, mesh.getNormBufId());
    gl.glNormalPointer(GL.GL_FLOAT, 0, null;
    
    gl.glBindBufferARB(GL.GL_ARRAY_BUFFER_ARB, mesh.getVertexBufId());
    gl.glVertexPointer(3, GL.GL_FLOAT, 0, null);

    GeometryGLMeshSection section = mesh.getSection(faceSet);
    if (section.isDirty())
    {
        section.updateVBOBuffers(gl);
    }
    
    gl.glBindBufferARB(GL.GL_ELEMENT_ARRAY_BUFFER_ARB, section.getBufferId());
    gl.glDrawElements(GL.GL_TRIANGLES, section.size(), GL.GL_UNSIGNED_SHORT, null);

Does your scene change as you see the drop in FPS? Do you for example start rendering additional sprites/objects with different textures that aren’t there originally? I’m guessing that you’ve got a non-power-of-two texture(s?) in there which is causing the slowdown.

At the moment, I’m only rendering a very simple test scene. No objects are being created or removed, and everything has the same greenish material with no textures. No animation, nothing fancy. Just updating the camera’s X and Y in response to keypresses.

The scene does speed up when the camera is moved such that only a few objects are visible. The more of the screen left as the background color, the faster it goes.

The one unusual thing I am doing is setting the projection matrix to the combination of the frustum and world/view transform rather than just the frustum transform and leaving the world/view to be part of the model/view matrix.

I"m pretty sure something’s going wrong, since a much simpler 100 polygon scene is chugging in my JOGL engine while the same scene opens and runs quickly in my older Java3D equivilant.

Okay - my scene now consists of a single quad, so two trianlges total,.and performance still sucks. The speed problem seems to be related to the area of the screen being drawn to. When the quad is very far away or mostly offscreen, the scene renders quickly. When the quad is in the foreground, it renders very slowly. I’m not sure why, because there is very little acual rendering my program is doing.

Has anyone successfully got animation running in JOGL at a decent speed?

Your probably getting software rendering.

How do I get hardware rendering? My graphics card supports the GL_ARB_vertex_buffer_object extension, and as far as I can tell, I’ve set up VBOs correctly.

On the other hand, finding good documentation on VBOs is as hard as looking for a needle in a haystack. So far, I’ve ahd to cobble it together from many incomplete tutorials. Are there any good examples of proper VBO rendering in Java (other than the one demo with the wavy yellow square in the JOGL demos)?

Check out this thread for code that checks your OpenGL vendor and version:
supported video cards

If the vendor is microsoft then you get software rendering because you don’t have OpenGL drivers installed. I’m guessing this because SW rendering is very fillrate limited. If it is not I suggest you post all of the code to the single quad example you mentioned. It might be something trivial that you’ve missed. Like rendering the quad 1000 times per frame :slight_smile: You might aswell forget about VBOs until you’ve found the problem. Will simplify the example.

What kind of graphics card do you have? What is the output of java -Djogl.verbose demos.printext.PrintExt?

What happens if you launch the Gears demo and make the window large? Is it fast or slow?

If the Gears demo is fast but your app is slow then most likely the GLCapabilities you’re using are forcing software rendering to be used. Try using just a default one if you aren’t already.

My program is currently a bit too large to post here, but I’ll see if I can get a test case put together. Using the code from the supported video card thread, I’m getting the following results from my display() method:

String vendor = gl.glGetString(GL.GL_VENDOR); System.out.println("Vendor: " + vendor); String renderer = gl.glGetString(GL.GL_RENDERER); System.out.println("Renderer: " + renderer);

Vendor: NVIDIA Corporation
Renderer: Quadro FX 500/FX 600/AGP/SSE2

My GLCapabilities are the defaults:

GLCapabilities [
DoubleBuffered: true,
Stereo: false,
HardwareAccelerated: true,
DepthBits: 24,
StencilBits: 0,
Red: 8,
Green: 8,
Blue: 8,
Alpha: 0,
Red Accum: 0,
Green Accum: 0,
Blue Accum: 0,
Alpha Accum: 0 ]

Taking a second look at this, if I want to use alpha blending, should I set Alpha to 8 when I create my canvas? If I later want to use the accumulation buffer, do I need to set Red Accum, etc? Could I get a 32 bit depth buffer by setting DepthBits = 32?

Running java -Djogl.verbose demos.printext.PrintExt gives me the below:

GL vendor: NVIDIA Corporation
GL version: 2.0.0
GL renderer: Quadro FX 500/FX 600/AGP/SSE2
GL extensions:
GL_ARB_depth_texture GL_ARB_fragment_program
GL_ARB_fragment_program_shadow GL_ARB_fragment_shader
GL_ARB_half_float_pixel GL_ARB_imaging
GL_ARB_multisample GL_ARB_multitexture
GL_ARB_occlusion_query GL_ARB_point_parameters
GL_ARB_point_sprite GL_ARB_shadow
GL_ARB_shader_objects GL_ARB_shading_language_100
GL_ARB_texture_border_clamp GL_ARB_texture_compression
GL_ARB_texture_cube_map GL_ARB_texture_env_add
GL_ARB_texture_env_combine GL_ARB_texture_env_dot3
GL_ARB_texture_mirrored_repeat GL_ARB_texture_rectangle
GL_ARB_transpose_matrix GL_ARB_vertex_buffer_object
GL_ARB_vertex_program GL_ARB_vertex_shader
GL_ARB_window_pos GL_S3_s3tc
GL_EXT_texture_env_add GL_EXT_abgr
GL_EXT_bgra GL_EXT_blend_color
GL_EXT_blend_func_separate GL_EXT_blend_minmax
GL_EXT_blend_subtract GL_EXT_compiled_vertex_array
GL_EXT_Cg_shader GL_EXT_draw_range_elements
GL_EXT_fog_coord GL_EXT_framebuffer_object
GL_EXT_multi_draw_arrays GL_EXT_packed_pixels
GL_EXT_paletted_texture GL_EXT_pixel_buffer_object
GL_EXT_point_parameters GL_EXT_rescale_normal
GL_EXT_secondary_color GL_EXT_separate_specular_color
GL_EXT_shadow_funcs GL_EXT_shared_texture_palette
GL_EXT_stencil_two_side GL_EXT_stencil_wrap
GL_EXT_texture3D GL_EXT_texture_compression_s3tc
GL_EXT_texture_cube_map GL_EXT_texture_edge_clamp
GL_EXT_texture_env_combine GL_EXT_texture_env_dot3
GL_EXT_texture_filter_anisotropic GL_EXT_texture_lod
GL_EXT_texture_lod_bias GL_EXT_texture_object
GL_EXT_vertex_array GL_HP_occlusion_test
GL_IBM_rasterpos_clip GL_IBM_texture_mirrored_repeat
GL_KTX_buffer_region GL_NV_blend_square
GL_NV_copy_depth_to_color GL_NV_depth_clamp
GL_NV_fence GL_NV_float_buffer
GL_NV_fog_distance GL_NV_fragment_program
GL_NV_fragment_program_option GL_NV_half_float
GL_NV_light_max_exponent GL_NV_multisample_filter_hint
GL_NV_occlusion_query GL_NV_packed_depth_stencil
GL_NV_pixel_data_range GL_NV_point_sprite
GL_NV_primitive_restart GL_NV_register_combiners
GL_NV_register_combiners2 GL_NV_texgen_reflection
GL_NV_texture_compression_vtc GL_NV_texture_env_combine4
GL_NV_texture_expand_normal GL_NV_texture_rectangle
GL_NV_texture_shader GL_NV_texture_shader2
GL_NV_texture_shader3 GL_NV_vertex_array_range
GL_NV_vertex_array_range2 GL_NV_vertex_program
GL_NV_vertex_program1_1 GL_NV_vertex_program2
GL_NV_vertex_program2_option GL_SGIS_generate_mipmap
GL_SGIS_texture_lod GL_SGIX_depth_texture
GL_SGIX_shadow GL_SUN_slice_accum
GL_WIN_swap_hint WGL_EXT_swap_control
GL_Autodesk_valid_back_buffer_hint
JOGL version 1.1.1
Using single-threaded workaround of dispatching display() on event thread

When I run JGears or the VBO example in a large window, it does run quickly, so I’m suspecting I’ve set up something incorrectly.

Mark McKay

Try installing the DebugGL pipeline in your init() method. See the Gears source code for how to do this; the appropriate line is commented out. Errors in your OpenGL usage may be showing up as slowdowns.

A very good tool to develop OpenGL application too is GLIntercept http://glintercept.nutty.org/.
Perhaps it could help you a bit (it generates easier to read call traces with frame buffer delta).

     Vincent