Uncaught Exception with Instanced mesh

As I discussed in other topics, I am hacking my own instanced meshes. The reason for this is that I need to feed my instances some extra data.

I do this by creating an InstancedData-buffer, slapping it onto a mesh and filling it with the information for the instances.

This works fine for my grass patches, that use a custom mesh created by some code. With my tree models I get a Uncaught Exception somewhere deep in the render engine and I can not figure out what could be different.

It happens when I add a material to it with the UseInstancing option on. It even happens when I add the grass material to the trees that works with exactly the same instancing-system. And with the grass Geometry it works just fine.

So clearly there must be something different with the Tree mesh, but what could it be?

The error message I get looks the same every single time:

SEVERE: Uncaught exception thrown in Thread[jME3 Main,5,main]
java.lang.NullPointerException
	at com.jme3.renderer.opengl.GLRenderer.clearVertexAttribs(GLRenderer.java:2911)
	at com.jme3.renderer.opengl.GLRenderer.renderMeshDefault(GLRenderer.java:3245)
	at com.jme3.renderer.opengl.GLRenderer.renderMesh(GLRenderer.java:3276)
	at com.jme3.material.logic.DefaultTechniqueDefLogic.renderMeshFromGeometry(DefaultTechniqueDefLogic.java:72)
	at com.jme3.material.logic.DefaultTechniqueDefLogic.render(DefaultTechniqueDefLogic.java:97)
	at com.jme3.material.Technique.render(Technique.java:167)
	at com.jme3.material.Material.render(Material.java:1052)
	at com.jme3.renderer.RenderManager.renderGeometry(RenderManager.java:651)
1 Like

Hard to say. Check what buffers are in the mesh.

I started to look into the GLRenderer line number but I don’t know what version of JME that OP is running (didn’t say) and the lines don’t match up with anything that would cause an NPE in the current code.

All we know is that it’s somewhere in this method (which is after the line from the stack trace):

This is what the IDE says about the version in the console:
Running on jMonkeyEngine 3.5.2-stable
 * Branch: HEAD
 * Git Hash: 8ab3d24
 * Build Date: 2022-04-21

The splash screen says it is version 3.4

This is what my bufferdumper says about the buffers:

Index ::  Format:UnsignedShort Instanced:false Elements:2952 Components:3 Stride:0 Base Instance Count:1 Offset:0
Position ::  Format:Float Instanced:false Elements:2634 Components:3 Stride:0 Base Instance Count:1 Offset:0
TexCoord ::  Format:Float Instanced:false Elements:2634 Components:2 Stride:0 Base Instance Count:1 Offset:0
Normal ::  Format:Float Instanced:false Elements:2634 Components:3 Stride:0 Base Instance Count:1 Offset:0
InstanceData ::  Format:Float Instanced:true Elements:100 Components:20 Stride:0 Base Instance Count:100 Offset:0

It is exactly as I would expect. And not realy different from the grass-patches mesh that does work:

Position ::  Format:Float Instanced:false Elements:41 Components:3 Stride:0 Base Instance Count:1 Offset:0
Normal ::  Format:Float Instanced:false Elements:41 Components:3 Stride:0 Base Instance Count:1 Offset:0
TexCoord ::  Format:Float Instanced:false Elements:41 Components:2 Stride:0 Base Instance Count:1 Offset:0
Index ::  Format:UnsignedInt Instanced:false Elements:34 Components:3 Stride:0 Base Instance Count:1 Offset:0
InstanceData ::  Format:Float Instanced:true Elements:200000 Components:20 Stride:0 Base Instance Count:200000 Offset:0

Does the tree mesh render fine without instancing?

Yes it does

Does the same error happen if you use JME’s built-in InstancedNode?

And by the way, if you are on Java 14+ try adding -XX:+ShowCodeDetailsInExceptionMessages for helpful NullPointerExceptions

Edit:

Looks like NPE happens in this line:

It seems context.boundAttribs[idx] is null.

I think it says I am on version 11…:

fedor@PCStudeerkamer:~$ java -version
openjdk version "11.0.17" 2022-10-18
OpenJDK Runtime Environment (build 11.0.17+8-post-Ubuntu-1ubuntu222.04)
OpenJDK 64-Bit Server VM (build 11.0.17+8-post-Ubuntu-1ubuntu222.04, mixed mode, sharing)

What could that mean?

I do not know.

Have you tried this by the way?

Yes, I was using that before with the same model. That was not a problem at all.

The only difference in the mesh seems to ve the index buffer type.

To be honest, if you could prepare a single file testcase and the model in question it would make debugging a lot easier.

They are both indexed…

I’ll have a try, i don’t know if I can isolate the code well enough for a test.

Some new information: I noticed that at least one frame is drawn before it crashes. I see a screen with the globe. I can not see if the trees are drawn.

I also did an experiment building a new mesh with only the data from the old mesh:

            for(VertexBuffer buf:bufs){
                
                VertexBuffer b2=new VertexBuffer(buf.getBufferType());
                switch (buf.getFormat()){
                    case Float: 
                        
                        float[] fb=(float[])b2.getData().array();
                        mesh.setBuffer(buf.getBufferType(),buf.getNumComponents(),fb);
                        break;
                    case UnsignedInt: 
                        short[] sb=(short[])b2.getData().array();
                        mesh.setBuffer(buf.getBufferType(),buf.getNumComponents(),sb);
                        break;
                }

                mesh.setBuffer(b2);
                
            }

That did not help. At all.

Your tree mesh uses unsigned short as index. you don’t catch that in your functions. checking for a unsigned int buffer and then casting to short data smells also fishy

Tnx… missed that. But it stil crashes. And I can not find anything different between its buffers and that of the grass. So it must be something else.

Without beeing able to run it i am out of guesses.

I understand… I was - am stil - working on isolating the relevant code.

the bad news is that I could not recreate the problem…
the good news is that I could not recreate the problem…

I have it working in my test code, but it still is not clear why it won’t work on the other side.

I vever used instancing so i dont know exactly how the geometry/mesh/material is manipulated.

Are you rendereing the same mesh again with the instancing parameters setup, but without the instance data?

No, I set up the InstanceData-buffer and set the material to UseInstancing…

I have also forked Instancing.glsllib to make use of the extra floats I put in InstanceData (it normally takes a Mat4 but I make it take 5 Vec4’s.)

BTW: I noticed that if I have the trees using only 16 floats it works. If I make them use 20 floats each the app crashes. While the grass patches easily use 20 floats without crashing.

In my testing app 20 floats per instance works fine with exactly the same code and the same Material-def. That one still won’t crash.

Out of interest, can you disable grass and only use the trees in your application.