OSDN Git Service

Use indicies to reduce grass cpu usage. Fix aliasing of tips of grass.
authorJason Sams <rjsams@android.com>
Wed, 16 Dec 2009 02:38:06 +0000 (18:38 -0800)
committerJason Sams <rjsams@android.com>
Wed, 16 Dec 2009 02:38:06 +0000 (18:38 -0800)
res/raw/grass.rs
src/com/android/wallpaper/grass/GrassRS.java

index 48ed783..563af1c 100644 (file)
@@ -107,58 +107,41 @@ int drawBlade(struct Blades_s *bladeStruct, float *bladeBuffer, int *bladeColor,
 
     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;
@@ -168,8 +151,8 @@ int drawBlade(struct Blades_s *bladeStruct, float *bladeBuffer, int *bladeColor,
 
     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) {
@@ -177,7 +160,6 @@ 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;
@@ -194,7 +176,7 @@ void drawBlades(float brightness, float xOffset) {
     }
 
     uploadToBufferObject(NAMED_BladesBuffer);
-    drawSimpleMeshRange(NAMED_BladesMesh, 0, trianglesCount * 3);
+    drawSimpleMeshRange(NAMED_BladesMesh, 0, State->indexCount);
 }
 
 int main(int launchID) {
@@ -251,5 +233,5 @@ int main(int launchID) {
     bindProgramFragment(NAMED_PFGrass);
     drawBlades(newB, x);
 
-    return 30;
+    return 50;
 }
index dd6e71e..0cdfcc3 100644 (file)
@@ -103,11 +103,14 @@ class GrassRS extends RenderScriptScene {
     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;
@@ -215,7 +218,7 @@ class GrassRS extends RenderScriptScene {
 
     static class WorldState {
         public int bladesCount;
-        public int trianglesCount;
+        public int indexCount;
         public int width;
         public int height;
         public float xOffset;
@@ -233,7 +236,7 @@ class GrassRS extends RenderScriptScene {
         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;
@@ -245,22 +248,26 @@ class GrassRS extends RenderScriptScene {
     }
 
     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();
@@ -268,7 +275,8 @@ class GrassRS extends RenderScriptScene {
         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");
@@ -276,46 +284,48 @@ class GrassRS extends RenderScriptScene {
         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);
 
@@ -333,9 +343,6 @@ class GrassRS extends RenderScriptScene {
         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() {
@@ -358,10 +365,21 @@ class GrassRS extends RenderScriptScene {
         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;
     }
 
@@ -374,7 +392,7 @@ class GrassRS extends RenderScriptScene {
 
     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);