Skip to content

Commit

Permalink
Fix byte stride for vertex attributes. Add tests.
Browse files Browse the repository at this point in the history
  • Loading branch information
javagl committed Sep 27, 2023
1 parent 081ae59 commit 3b83b96
Show file tree
Hide file tree
Showing 2 changed files with 140 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -555,6 +555,10 @@ private void processBufferModel(DefaultBufferModel bufferModel)
if (commonByteStride == null)
{
accessorModel.setByteStride(targetByteStride);
}
else
{
targetByteStride = commonByteStride;
}

// Compute the byte buffer for the accessor data. This
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
package de.javagl.jgltf.model.creation;

import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;

import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.List;

import org.junit.Test;

import de.javagl.jgltf.model.AccessorData;
import de.javagl.jgltf.model.AccessorDatas;
import de.javagl.jgltf.model.AccessorModel;
import de.javagl.jgltf.model.BufferViewModel;
import de.javagl.jgltf.model.impl.DefaultAccessorModel;

@SuppressWarnings("javadoc")
Expand Down Expand Up @@ -179,4 +184,135 @@ public void testByteStrideForMatrixVertexAttributes()
}


@Test
public void testByteStrideForMatrixComponents()
{
byte data[] =
{
1, 2, -1, -1,
3, 4, -1, -1,
11, 22, -1, -1,
33, 44, -1, -1,
};

BufferStructureBuilder b = new BufferStructureBuilder();

b.createAccessorModel("accessor", data, "MAT2");
b.createArrayBufferViewModel("buffer view");
b.createBufferModel("buffer", "data.bin");

// The accessor model will contain only the entries
// 1, 2
// 3, 4
// 11, 22
// 33, 44
// The remaining bytes are padding bytes for the matrix
// columns. In the resulting buffer, these bytes should
// therefore remain 0
BufferStructure bufferStructure = b.build();
ByteBuffer bufferData =
bufferStructure.getBufferModels().get(0).getBufferData();
byte expected[] = new byte[]
{
1, 2, 0, 0,
3, 4, 0, 0,
11, 22, 0, 0,
33, 44, 0, 0,
};
byte actual[] = new byte[16];
bufferData.slice().get(actual);
assertArrayEquals(expected, actual);
}


@Test
public void testByteStrideForAttributes()
{
// Create an accessor with GL_UNSIGNED_SHORT data, as part of
// a buffer view model for GL_ARRAY_BUFFER, meaning that it
// will be a vertex attribute, which requires an alignment
// of 4 for each element
short data[] =
{
1, 2, 3, 4
};
BufferStructureBuilder b = new BufferStructureBuilder();
b.createAccessorModel("accessor", data, "SCALAR");
b.createArrayBufferViewModel("buffer view");
b.createBufferModel("buffer", "data.bin");

BufferStructure bufferStructure = b.build();
BufferViewModel bufferViewModel =
bufferStructure.getBufferViewModels().get(0);

// The byte stride must be 4, because it is
// a vertex attribute
Integer expectedByteStride = 4;
Integer actualByteStride = bufferViewModel.getByteStride();

int expectedByteLength = 16;
int actualByteLength = bufferViewModel.getByteLength();

ByteBuffer bufferData =
bufferStructure.getBufferModels().get(0).getBufferData();
byte expectedBufferData[] = new byte[]
{
1, 0, 0, 0,
2, 0, 0, 0,
3, 0, 0, 0,
4, 0, 0, 0,
};
byte actualBufferData[] = new byte[bufferData.capacity()];
bufferData.slice().get(actualBufferData);

assertEquals(expectedByteStride, actualByteStride);
assertEquals(expectedByteLength, actualByteLength);
assertArrayEquals(expectedBufferData, actualBufferData);
}

@Test
public void testByteStrideForNonAttributes()
{
// Create an accessor with GL_UNSIGNED_SHORT data, as part of
// a buffer view model for GL_ARRAY_ELEMENT_BUFFER, meaning that it
// will NOT be a vertex attribute, and the elements can be
// tightly packed
short data[] =
{
1, 2, 3, 4
};
BufferStructureBuilder b = new BufferStructureBuilder();
b.createAccessorModel("accessor", data, "SCALAR");
b.createArrayElementBufferViewModel("buffer view");
b.createBufferModel("buffer", "data.bin");

BufferStructure bufferStructure = b.build();
BufferViewModel bufferViewModel =
bufferStructure.getBufferViewModels().get(0);

// The byte stride must be null, because the
// elements are tightly packed
Integer expectedByteStride = null;
Integer actualByteStride = bufferViewModel.getByteStride();

int expectedByteLength = 8;
int actualByteLength = bufferViewModel.getByteLength();

ByteBuffer bufferData =
bufferStructure.getBufferModels().get(0).getBufferData();
byte expectedBufferData[] = new byte[]
{
1, 0,
2, 0,
3, 0,
4, 0,
};
byte actualBufferData[] = new byte[bufferData.capacity()];
bufferData.slice().get(actualBufferData);

assertEquals(expectedByteStride, actualByteStride);
assertEquals(expectedByteLength, actualByteLength);
assertArrayEquals(expectedBufferData, actualBufferData);
}

}

0 comments on commit 3b83b96

Please sign in to comment.