GeometryBatchFactory Point Mesh fix(?)

Hey.

I noticed an issue with Point Meshes and GBF.

It seems it never takes into account that, for example, texture buffers can have more elements than the mesh has vertices. To use Point Meshes as point sprites, you have 4 texture coords. So, i think this patch fixes that issue, please review it.



Edit: Another thing struck me. I noticed another problem with it (earlier on). Afterwards i need to clear the index buffer, since it’s also filled up with elements. I think this is due to Mesh.updateCounts() setting elementCount to the vertexCount if the indexbuffer is null. Perhaps unrelated, but it’s a potential hazard?



Edit2: To explain that further: GBF uses getTriangleCount(), which returns the elementCount



[patch]===================================================================

— GeometryBatchFactory.java (revision 9446)

+++ GeometryBatchFactory.java (working copy)

@@ -96,6 +96,7 @@

public static void mergeGeometries(Collection<Geometry> geometries, Mesh outMesh) {

int[] compsForBuf = new int[VertexBuffer.Type.values().length];

Format[] formatForBuf = new Format[compsForBuf.length];

  •    int[] totalElementsForBuf = new int[compsForBuf.length];<br />
    

int totalVerts = 0;
int totalTris = 0;
@@ -133,6 +134,7 @@
for (VertexBuffer vb : geom.getMesh().getBufferList().getArray()) {
compsForBuf[vb.getBufferType().ordinal()] = vb.getNumComponents();
formatForBuf[vb.getBufferType().ordinal()] = vb.getFormat();
+ totalElementsForBuf[vb.getBufferType().ordinal()] += vb.getNumElements();
}

if (mode != null && mode != listMode) {
@@ -161,13 +163,19 @@
Buffer data;
if (i == Type.Index.ordinal()) {
data = VertexBuffer.createBuffer(formatForBuf, compsForBuf, totalTris);
- } else {
- data = VertexBuffer.createBuffer(formatForBuf, compsForBuf, totalVerts);
+ } else {
+ data = VertexBuffer.createBuffer(formatForBuf, compsForBuf, totalElementsForBuf);
}

VertexBuffer vb = new VertexBuffer(Type.values());
vb.setupData(Usage.Static, compsForBuf, formatForBuf, data);
outMesh.setBuffer(vb);
}

int globalVertIndex = 0;
@@ -214,9 +222,17 @@
FloatBuffer outPos = (FloatBuffer) outBuf.getData();
int components = inBuf.getNumComponents();
doTransformTangents(inPos, globalVertIndex, components, outPos, worldMatrix);
- } else {
- inBuf.copyElements(0, outBuf, globalVertIndex, geomVertCount);
+ } else {
+ inBuf.copyElements(0, outBuf, globalVertIndex, inMesh.getBuffer(Type.values()[bufType]).getNumElements());
}
}

globalVertIndex += geomVertCount;
@@ -269,7 +285,7 @@
lods = new VertexBuffer(Type.Index);
lods.setupData(Usage.Dynamic, 1, Format.UnsignedInt, BufferUtils.createIntBuffer(lodData));
}
outMesh.setLodLevels(lods);
}

@@ -358,10 +374,12 @@
ArrayList<Geometry> geoms = new ArrayList<Geometry>();

gatherGeoms(scene, geoms);

public static void printMesh(Mesh mesh) {
for (int bufType = 0; bufType < Type.values().length; bufType++) {
[/patch]
@rickard said:
It seems it never takes into account that, for example, texture buffers can have more elements than the mesh has vertices. To use Point Meshes as point sprites, you have 4 texture coords. So, i think this patch fixes that issue, please review it.

This is false - each point (sprite) is represented by one vertex. The texture coordinate is decided in the shader.

@rickard said:
Edit: Another thing struck me. I noticed another problem with it (earlier on). Afterwards i need to clear the index buffer, since it's also filled up with elements. I think this is due to Mesh.updateCounts() setting elementCount to the vertexCount if the indexbuffer is null. Perhaps unrelated, but it's a potential hazard?

Edit2: To explain that further: GBF uses getTriangleCount(), which returns the elementCount

I don't see this in the patch. What do you mean exactly? ShortBuffer/IntBuffer.clear() call after filling it with data?
Are you referring to issue 504?

Damn, i thought i had followed how the ParticlePointMesh was set up. I see now that i must have confused the 4 components of the texcoord with 4 texcoords.



The “edits” are not in the patch. I had done this much earlier, but after the optimization pass.

i call Mesh.getBuffer(Type.Index).clear() to empty it, otherwise it has vertexAmount elements, and prevents my points from being seen.

I don’t think it’s relatdd to 504.

If you send a mesh with a null index buffer (but have called updateCounts() ), GBF will create an index buffer based on the elementCount, which in that case will be based on the vertexCount.

@rickard said:
i call Mesh.getBuffer(Type.Index).clear() to empty it, otherwise it has vertexAmount elements, and prevents my points from being seen.
I don't think it's relatdd to 504.

Currently the LWJGL renderer calls "rewind" on all buffers before uploading them, this includes the index buffer as well. This means position is always reset to zero before the buffer is uploaded. I don't understand what you mean by vertexAmount elements, do you mean you have more indices than there are vertices in the mesh?
Perhaps you can post a simple test case to show this issue?

@rickard said:
If you send a mesh with a null index buffer (but have called updateCounts() ), GBF will create an index buffer based on the elementCount, which in that case will be based on the vertexCount.

Yes, this is normal behavior. It allows you to combine an indexed mesh with a non indexed mesh.

All right. I’ll see if i can put together a test case