float d = angle * bladeStruct->hardness;
- int triangles = size * 2;
+
+ float si = size * scale;
+ float bottomLeft = bottomX - si;
+ float bottomRight = bottomX + si;
+ float bottom = bottomY + HALF_TESSELATION;
+
+ bladeColor[0] = color; // V1.ABGR
+ bladeBuffer[1] = bottomLeft; // V1.X
+ bladeBuffer[2] = bottom; // V1.Y
+ bladeColor[5] = color; // V2.ABGR
+ bladeBuffer[6] = bottomRight; // V2.X
+ bladeBuffer[7] = bottom; // V2.Y
+ bladeBuffer += 10;
+ bladeColor += 10;
for ( ; size > 0; size -= 1) {
float topX = bottomX - cosf_fast(currentAngle) * bladeStruct->lengthX;
float topY = bottomY - sinf_fast(currentAngle) * bladeStruct->lengthY;
- float si = size * scale;
+ si = (float)size * scale;
float spi = si - scale;
- float bottomLeft = bottomX - si;
- float bottomRight = bottomX + si;
float topLeft = topX - spi;
float topRight = topX + spi;
- float bottom = bottomY + HALF_TESSELATION;
-
- // First triangle
- bladeColor[0] = color; // V1.ABGR
-
- bladeBuffer[1] = bottomLeft; // V1.X
- bladeBuffer[2] = bottom; // V1.Y
-
- bladeColor[5] = color; // V1.ABGR
-
- bladeBuffer[6] = topLeft; // V2.X
- bladeBuffer[7] = topY; // V2.Y
-
- bladeColor[10] = color; // V3.ABGR
-
- bladeBuffer[11] = topRight; // V3.X
- bladeBuffer[12] = topY; // V3.Y
-
- // Second triangle
- bladeBuffer += 15;
- bladeColor += 15;
bladeColor[0] = color; // V1.ABGR
+ bladeBuffer[1] = topLeft; // V2.X
+ bladeBuffer[2] = topY; // V2.Y
- bladeBuffer[1] = bottomLeft; // V1.X
- bladeBuffer[2] = bottom; // V1.Y
-
- bladeColor[5] = color; // V2.ABGR
-
- bladeBuffer[6] = topRight; // V2.X
- bladeBuffer[7] = topY; // V2.Y
-
- bladeColor[10] = color; // V3.ABGR
-
- bladeBuffer[11] = bottomRight; // V3.X
- bladeBuffer[12] = bottom; // V3.Y
+ bladeColor[5] = color; // V3.ABGR
+ bladeBuffer[6] = topRight; // V3.X
+ bladeBuffer[7] = topY; // V3.Y
- bladeBuffer += 15;
- bladeColor += 15;
+ bladeBuffer += 10;
+ bladeColor += 10;
bottomX = topX;
bottomY = topY;
bladeStruct->angle = angle;
- // 3 vertices per triangle, 5 properties per vertex (RGBA, X, Y, S, T)
- return triangles * 15;
+ // 2 vertices per triangle, 5 properties per vertex (RGBA, X, Y, S, T)
+ return bladeStruct->size * 10 + 10;
}
void drawBlades(float brightness, float xOffset) {
bindTexture(NAMED_PFGrass, 0, NAMED_TAa);
int bladesCount = State->bladesCount;
- int trianglesCount = State->trianglesCount;
int i = 0;
struct Blades_s *bladeStruct = Blades;
}
uploadToBufferObject(NAMED_BladesBuffer);
- drawSimpleMeshRange(NAMED_BladesMesh, 0, trianglesCount * 3);
+ drawSimpleMeshRange(NAMED_BladesMesh, 0, State->indexCount);
}
int main(int launchID) {
bindProgramFragment(NAMED_PFGrass);
drawBlades(newB, x);
- return 30;
+ return 50;
}
private Type mBladesType;
private Allocation mBlades;
private Allocation mBladesBuffer;
+ private Allocation mBladesIndicies;
@SuppressWarnings({"FieldCanBeLocal"})
private SimpleMesh mBladesMesh;
- private int mTriangles;
+ private int mVerticies;
+ private int mIndicies;
+ private int[] mBladeSizes;
private final float[] mFloatData5 = new float[5];
private WorldState mWorldState;
static class WorldState {
public int bladesCount;
- public int trianglesCount;
+ public int indexCount;
public int width;
public int height;
public float xOffset;
mWorldState.width = mWidth;
mWorldState.height = mHeight;
mWorldState.bladesCount = BLADES_COUNT;
- mWorldState.trianglesCount = mTriangles;
+ mWorldState.indexCount = mIndicies;
mWorldState.isPreview = isPreview ? 1 : 0;
if (isPreview) {
mWorldState.xOffset = 0.5f;
}
private void createBlades() {
- int triangles = 0;
+ mVerticies = 0;
+ mIndicies = 0;
mBladesType = Type.createFromClass(mRS, BladesStruct.class, BLADES_COUNT, "Blade");
mBlades = Allocation.createTyped(mRS, mBladesType);
BladesStruct bs = new BladesStruct();
+ mBladeSizes = new int[BLADES_COUNT];
for (int i = 0; i < BLADES_COUNT; i++) {
- triangles += createBlade(bs);
+ createBlade(bs);
+ mIndicies += bs.size * 2 * 3;
+ mVerticies += bs.size + 2;
mBlades.subData(i, bs);
+ mBladeSizes[i] = bs.size;
}
- mTriangles = triangles;
- createMesh(triangles);
+ createMesh();
}
- private void createMesh(int triangles) {
+ private void createMesh() {
Builder elementBuilder = new Builder(mRS);
elementBuilder.addUNorm8RGBA();
elementBuilder.addFloatXY();
final Element vertexElement = elementBuilder.create();
final SimpleMesh.Builder meshBuilder = new SimpleMesh.Builder(mRS);
- final int vertexSlot = meshBuilder.addVertexType(vertexElement, triangles * 3);
+ final int vertexSlot = meshBuilder.addVertexType(vertexElement, mVerticies * 2);
+ meshBuilder.setIndexType(Element.INDEX_16(mRS), mIndicies);
meshBuilder.setPrimitive(Primitive.TRIANGLE);
mBladesMesh = meshBuilder.create();
mBladesMesh.setName("BladesMesh");
mBladesBuffer = mBladesMesh.createVertexAllocation(vertexSlot);
mBladesBuffer.setName("BladesBuffer");
mBladesMesh.bindVertexAllocation(mBladesBuffer, 0);
+ mBladesIndicies = mBladesMesh.createIndexAllocation();
+ mBladesMesh.bindIndexAllocation(mBladesIndicies);
// Assign the texture coordinates of each triangle
final float[] floatData = mFloatData5;
final Allocation buffer = mBladesBuffer;
- int bufferIndex = 0;
- for (int i = 0; i < triangles; i += 2) {
- floatData[3] = 0.0f;
- floatData[4] = 1.0f;
- buffer.subData1D(bufferIndex, 1, floatData);
- bufferIndex++;
+ short[] idx = new short[mIndicies];
+ int bufferIndex = 0;
+ int i2 = 0;
+ for (int i = 0; i < mVerticies; i +=2) {
floatData[3] = 0.0f;
floatData[4] = 0.0f;
- buffer.subData1D(bufferIndex, 1, floatData);
- bufferIndex++;
+ buffer.subData1D(bufferIndex++, 1, floatData);
floatData[3] = 1.0f;
floatData[4] = 0.0f;
- buffer.subData1D(bufferIndex, 1, floatData);
- bufferIndex++;
-
- floatData[3] = 0.0f;
- floatData[4] = 0.0f;
- buffer.subData1D(bufferIndex, 1, floatData);
- bufferIndex++;
-
- floatData[3] = 1.0f;
- floatData[4] = 1.0f;
- buffer.subData1D(bufferIndex, 1, floatData);
- bufferIndex++;
+ buffer.subData1D(bufferIndex++, 1, floatData);
+ }
- floatData[3] = 1.0f;
- floatData[4] = 0.0f;
- buffer.subData1D(bufferIndex, 1, floatData);
- bufferIndex++;
+ int idxIdx = 0;
+ int vtxIdx = 0;
+ for (int i = 0; i < mBladeSizes.length; i++) {
+ for (int ct = 0; ct < mBladeSizes[i]; ct ++) {
+ idx[idxIdx + 0] = (short)(vtxIdx + 0);
+ idx[idxIdx + 1] = (short)(vtxIdx + 1);
+ idx[idxIdx + 2] = (short)(vtxIdx + 2);
+ idx[idxIdx + 3] = (short)(vtxIdx + 1);
+ idx[idxIdx + 4] = (short)(vtxIdx + 3);
+ idx[idxIdx + 5] = (short)(vtxIdx + 2);
+ idxIdx += 6;
+ vtxIdx += 2;
+ }
+ vtxIdx += 2;
}
+
+ mBladesIndicies.data(idx);
+ mBladesIndicies.uploadToBufferObject();
}
- private int createBlade(BladesStruct blades) {
+ private void createBlade(BladesStruct blades) {
final float size = random(4.0f) + 4.0f;
final int xpos = random(-mWidth, mWidth);
blades.s = random(0.22f) + 0.78f;
blades.b = random(0.65f) + 0.35f;
blades.turbulencex = xpos * 0.006f;
-
- // Each blade is made of "size" quads, so we double to count the triangles
- return blades.size * 2;
}
private void loadTextures() {
final Type.Builder builder = new Type.Builder(mRS, A_8(mRS));
builder.add(Dimension.X, width);
builder.add(Dimension.Y, height);
+ builder.add(Dimension.LOD, 1);
final Allocation allocation = Allocation.createTyped(mRS, builder.create());
- allocation.data(data);
allocation.setName(name);
+
+ int[] grey1 = new int[] {0x3f3f3f3f};
+ int[] grey2 = new int[] {0x00000000};
+ Allocation.Adapter2D a = allocation.createAdapter2D();
+ a.setConstraint(Dimension.LOD, 0);
+ a.subData(0, 0, 4, 1, data);
+ a.setConstraint(Dimension.LOD, 1);
+ a.subData(0, 0, 2, 1, grey1);
+ a.setConstraint(Dimension.LOD, 2);
+ a.subData(0, 0, 1, 1, grey2);
+
return allocation;
}
private void createProgramFragment() {
Sampler.Builder samplerBuilder = new Sampler.Builder(mRS);
- samplerBuilder.setMin(LINEAR);
+ samplerBuilder.setMin(LINEAR_MIP_LINEAR);
samplerBuilder.setMag(LINEAR);
samplerBuilder.setWrapS(WRAP);
samplerBuilder.setWrapT(WRAP);