Loading libs/rs/java/Fall/res/raw/fall.c +207 −2 Original line number Diff line number Diff line // Copyright (C) 2009 The Android Open Source Project // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #pragma version(1) #pragma stateVertex(PVBackground) #pragma stateFragment(PFBackground) #pragma stateFragmentStore(PSBackground) #pragma stateFragmentStore(PFSBackground) #define RSID_STATE 0 #define RSID_FRAME_COUNT 0 #define RSID_WIDTH 1 #define RSID_HEIGHT 2 #define RSID_MESH_WIDTH 3 #define RSID_MESH_HEIGHT 4 #define RSID_RIPPLE_MAP_SIZE 5 #define RSID_RIPPLE_INDEX 6 #define RSID_DROP_X 7 #define RSID_DROP_Y 8 #define RSID_TEXTURES 1 #define RSID_RIPPLE_MAP 2 #define RSID_REFRACTION_MAP 3 #define REFRACTION 1.333f #define DAMP 4 #define DROP_RADIUS 2 // The higher, the smaller the ripple #define RIPPLE_HEIGHT 10.0f int offset(int x, int y, int width) { return x + 1 + (y + 1) * (width + 2); } void drop(int x, int y, int r) { int width = loadI32(RSID_STATE, RSID_MESH_WIDTH); int height = loadI32(RSID_STATE, RSID_MESH_HEIGHT); if (x < r) x = r; if (y < r) y = r; if (x >= width - r) x = width - r - 1; if (y >= height - r) x = height - r - 1; x = width - x; int rippleMapSize = loadI32(RSID_STATE, RSID_RIPPLE_MAP_SIZE); int index = loadI32(RSID_STATE, RSID_RIPPLE_INDEX); int origin = offset(0, 0, width); int* current = loadArrayI32(RSID_RIPPLE_MAP, index * rippleMapSize + origin); int sqr = r * r; int h = 0; for ( ; h < r; h++) { int sqv = h * h; int yn = origin + (y - h) * (width + 2); int yp = origin + (y + h) * (width + 2); int w = 0; for ( ; w < r; w++) { int squ = w * w; if (squ + sqv < sqr) { int v = -sqrtf((sqr - (squ + sqv)) << 16); current[yn + x + w] = v; current[yp + x + w] = v; current[yn + x - w] = v; current[yp + x - w] = v; } } } } void updateRipples() { int rippleMapSize = loadI32(RSID_STATE, RSID_RIPPLE_MAP_SIZE); int width = loadI32(RSID_STATE, RSID_MESH_WIDTH); int height = loadI32(RSID_STATE, RSID_MESH_HEIGHT); int index = loadI32(RSID_STATE, RSID_RIPPLE_INDEX); int origin = offset(0, 0, width); int* current = loadArrayI32(RSID_RIPPLE_MAP, index * rippleMapSize + origin); int* next = loadArrayI32(RSID_RIPPLE_MAP, (1 - index) * rippleMapSize + origin); storeI32(RSID_STATE, RSID_RIPPLE_INDEX, 1 - index); int a = 1; int b = width + 2; int h = height; while (h) { int w = width; while (w) { int droplet = ((current[-b] + current[b] + current[-a] + current[a]) >> 1) - next[0]; droplet -= (droplet >> DAMP); next[0] = droplet; current++; next++; w--; } current += 2; next += 2; h--; } } void generateRipples() { int rippleMapSize = loadI32(RSID_STATE, RSID_RIPPLE_MAP_SIZE); int width = loadI32(RSID_STATE, RSID_MESH_WIDTH); int height = loadI32(RSID_STATE, RSID_MESH_HEIGHT); int index = loadI32(RSID_STATE, RSID_RIPPLE_INDEX); int origin = offset(0, 0, width); int b = width + 2; int* current = loadArrayI32(RSID_RIPPLE_MAP, index * rippleMapSize + origin); float *vertices = loadTriangleMeshVerticesF(NAMED_mesh); int h = height - 1; while (h >= 0) { int w = width - 1; int wave = current[0]; int offset = h * width; while (w >= 0) { int nextWave = current[1]; int dx = nextWave - wave; int dy = current[b] - wave; // Update Z coordinate of the vertex vertices[(offset + w) * 8 + 7] = (dy / 512.0f) / RIPPLE_HEIGHT; w--; current++; wave = nextWave; } h--; current += 2; } // Compute the normals for lighting int y = 0; for ( ; y < height; y++) { int x = 0; int yOffset = y * width; for ( ; x < width; x++) { // V1 float v1x = vertices[(yOffset + x) * 8 + 5]; float v1y = vertices[(yOffset + x) * 8 + 6]; float v1z = vertices[(yOffset + x) * 8 + 7]; // V2 float v2x = vertices[(yOffset + x + 1) * 8 + 5]; float v2y = vertices[(yOffset + x + 1) * 8 + 6]; float v2z = vertices[(yOffset + x + 1) * 8 + 7]; // V3 float v3x = vertices[(yOffset + width + x) * 8 + 5]; float v3y = vertices[(yOffset + width + x) * 8 + 6]; float v3z = vertices[(yOffset + width + x) * 8 + 7]; // N1 float n1x = v2x - v1x; float n1y = v2y - v1y; float n1z = v2z - v1z; // N2 float n2x = v3x - v1x; float n2y = v3y - v1y; float n2z = v3z - v1z; // N1 x N2 float n3x = n1y * n2z - n1z * n2y; float n3y = n1z * n2x - n1x * n2z; float n3z = n1x * n2y - n1y * n2x; // Normalize float len = magf3(n3x, n3y, n3z); n3x /= len; n3y /= len; n3z /= len; vertices[(yOffset + x) * 8 + 0] = -n3x; vertices[(yOffset + x) * 8 + 1] = -n3y; vertices[(yOffset + x) * 8 + 2] = -n3z; } } } int main(int index) { color(1.0f, 0.0f, 0.0f, 1.0f); int dropX = loadI32(RSID_STATE, RSID_DROP_X); if (dropX != -1) { int dropY = loadI32(RSID_STATE, RSID_DROP_Y); drop(dropX, dropY, DROP_RADIUS); storeI32(RSID_STATE, RSID_DROP_X, -1); storeI32(RSID_STATE, RSID_DROP_Y, -1); } updateRipples(); generateRipples(); updateTriangleMesh(NAMED_mesh); ambient(0.0f, 0.1f, 0.9f, 1.0f); diffuse(0.0f, 0.1f, 0.9f, 1.0f); drawTriangleMesh(NAMED_mesh); return 1; Loading libs/rs/java/Fall/src/com/android/fall/rs/FallRS.java +94 −35 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import android.renderscript.ProgramVertex; import android.renderscript.Allocation; import android.renderscript.Sampler; import android.renderscript.Element; import android.renderscript.Light; import static android.renderscript.Sampler.Value.LINEAR; import static android.renderscript.Sampler.Value.CLAMP; import static android.renderscript.ProgramStore.DepthFunc.*; Loading @@ -38,16 +39,26 @@ import android.graphics.Bitmap; import java.util.TimeZone; class FallRS { private static final int MESH_RESOLUTION = 32; private static final int MESH_RESOLUTION = 48; private static final int RSID_STATE = 0; private static final int RSID_STATE_FRAMECOUNT = 0; private static final int RSID_STATE_WIDTH = 1; private static final int RSID_STATE_HEIGHT = 2; private static final int RSID_STATE_MESH_WIDTH = 3; private static final int RSID_STATE_MESH_HEIGHT = 4; private static final int RSID_STATE_RIPPLE_MAP_SIZE = 5; private static final int RSID_STATE_RIPPLE_INDEX = 6; private static final int RSID_STATE_DROP_X = 7; private static final int RSID_STATE_DROP_Y = 8; private static final int RSID_TEXTURES = 1; private static final int TEXTURES_COUNT = 0; private static final int RSID_RIPPLE_MAP = 2; private static final int RSID_REFRACTION_MAP = 3; private Resources mResources; private RenderScript mRS; private final BitmapFactory.Options mBitmapOptions = new BitmapFactory.Options(); Loading @@ -61,6 +72,7 @@ class FallRS { private ProgramStore mPfsBackground; private ProgramVertex mPvBackground; private ProgramVertex.MatrixAllocation mPvOrthoAlloc; private Light mLight; private Allocation mTexturesIDs; private Allocation[] mTextures; Loading @@ -68,6 +80,11 @@ class FallRS { private Allocation mState; private RenderScript.TriangleMesh mMesh; private int mMeshWidth; private int mMeshHeight; private Allocation mRippleMap; private Allocation mRefractionMap; public FallRS(int width, int height) { mWidth = width; Loading Loading @@ -96,6 +113,9 @@ class FallRS { mState.destroy(); mTextureBufferIDs = null; mMesh.destroy(); mLight.destroy(); mRippleMap.destroy(); mRefractionMap.destroy(); } @Override Loading @@ -111,8 +131,9 @@ class FallRS { createProgramVertex(); createProgramFragmentStore(); createProgramFragment(); createScriptStructures(); createMesh(); createScriptStructures(); loadTextures(); ScriptC.Builder sb = new ScriptC.Builder(mRS); sb.setScript(mResources, R.raw.fall); Loading @@ -121,16 +142,17 @@ class FallRS { mScript.setClearColor(0.0f, 0.0f, 0.0f, 1.0f); mScript.setTimeZone(TimeZone.getDefault().getID()); loadSkyTextures(); mScript.bindAllocation(mState, RSID_STATE); mScript.bindAllocation(mTexturesIDs, RSID_TEXTURES); mScript.bindAllocation(mRippleMap, RSID_RIPPLE_MAP); mScript.bindAllocation(mRefractionMap, RSID_REFRACTION_MAP); mRS.contextBindRootScript(mScript); } private void createMesh() { final RenderScript rs = mRS; rs.triangleMeshBegin(Element.XYZ_F32, Element.INDEX_16); rs.triangleMeshBegin(Element.NORM_ST_XYZ_F32, Element.INDEX_16); int wResolution; int hResolution; Loading @@ -146,13 +168,20 @@ class FallRS { hResolution = MESH_RESOLUTION; } final float quadWidth = width / (float) wResolution; final float quadHeight = height / (float) hResolution; final float glHeight = 2.0f * height / (float) width; final float quadWidth = 2.0f / (float) wResolution; final float quadHeight = glHeight / (float) hResolution; wResolution += 2; hResolution += 2; for (int y = 0; y <= hResolution; y++) { final float yOffset = y * quadHeight; final float yOffset = y * quadHeight - glHeight / 2.0f - quadHeight; for (int x = 0; x <= wResolution; x++) { rs.triangleMeshAddVertex_XYZ(x * quadWidth, yOffset, 0.0f); rs.triangleMeshAddVertex_XYZ_ST_NORM( -1.0f + x * quadWidth - quadWidth, yOffset, 0.0f, x / (float) wResolution, y / (float) wResolution, 0.0f, 0.0f, -1.0f); } } Loading @@ -167,18 +196,41 @@ class FallRS { mMesh = rs.triangleMeshCreate(); mMesh.setName("mesh"); mMeshWidth = wResolution + 1; mMeshHeight = hResolution + 1; } private void createScriptStructures() { final int[] data = new int[3]; final int rippleMapSize = (mMeshWidth + 2) * (mMeshHeight + 2); final int[] data = new int[9]; mState = Allocation.createSized(mRS, USER_I32, data.length); data[RSID_STATE_FRAMECOUNT] = 0; data[RSID_STATE_WIDTH] = mWidth; data[RSID_STATE_HEIGHT] = mHeight; data[RSID_STATE_MESH_WIDTH] = mMeshWidth; data[RSID_STATE_MESH_HEIGHT] = mMeshHeight; data[RSID_STATE_RIPPLE_MAP_SIZE] = rippleMapSize; data[RSID_STATE_RIPPLE_INDEX] = 0; data[RSID_STATE_DROP_X] = mMeshWidth / 2; data[RSID_STATE_DROP_Y] = mMeshHeight / 2; mState.data(data); final int[] rippleMap = new int[rippleMapSize * 2]; mRippleMap = Allocation.createSized(mRS, USER_I32, rippleMap.length); final int[] refractionMap = new int[513]; float ir = 1.0f / 1.333f; for (int i = 0; i < refractionMap.length; i++) { float d = (float) Math.tan(Math.asin(Math.sin(Math.atan(i * (1.0f / 256.0f))) * ir)); refractionMap[i] = (int) Math.floor(d * (1 << 16) + 0.5f); } mRefractionMap = Allocation.createSized(mRS, USER_I32, refractionMap.length); mRefractionMap.data(refractionMap); } private void loadSkyTextures() { private void loadTextures() { mTextureBufferIDs = new int[TEXTURES_COUNT]; mTextures = new Allocation[TEXTURES_COUNT]; mTexturesIDs = Allocation.createSized(mRS, USER_FLOAT, TEXTURES_COUNT); Loading Loading @@ -215,42 +267,49 @@ class FallRS { } private void createProgramFragment() { Sampler.Builder bs = new Sampler.Builder(mRS); bs.setMin(LINEAR); bs.setMag(LINEAR); bs.setWrapS(CLAMP); bs.setWrapT(CLAMP); mSampler = bs.create(); ProgramFragment.Builder b; b = new ProgramFragment.Builder(mRS, null, null); b.setTexEnable(true, 0); b.setTexEnvMode(REPLACE, 0); mPfBackground = b.create(); Sampler.Builder sampleBuilder = new Sampler.Builder(mRS); sampleBuilder.setMin(LINEAR); sampleBuilder.setMag(LINEAR); sampleBuilder.setWrapS(CLAMP); sampleBuilder.setWrapT(CLAMP); mSampler = sampleBuilder.create(); ProgramFragment.Builder builder = new ProgramFragment.Builder(mRS, null, null); builder.setTexEnable(true, 0); builder.setTexEnvMode(REPLACE, 0); mPfBackground = builder.create(); mPfBackground.setName("PFBackground"); mPfBackground.bindSampler(mSampler, 0); } private void createProgramFragmentStore() { ProgramStore.Builder b; b = new ProgramStore.Builder(mRS, null, null); b.setDepthFunc(ALWAYS); b.setBlendFunc(BlendSrcFunc.SRC_ALPHA, BlendDstFunc.ONE_MINUS_SRC_ALPHA); b.setDitherEnable(true); b.setDepthMask(false); mPfsBackground = b.create(); ProgramStore.Builder builder = new ProgramStore.Builder(mRS, null, null); builder.setDepthFunc(LESS); builder.setBlendFunc(BlendSrcFunc.SRC_ALPHA, BlendDstFunc.ONE_MINUS_SRC_ALPHA); builder.setDitherEnable(true); builder.setDepthMask(true); mPfsBackground = builder.create(); mPfsBackground.setName("PFSBackground"); } private void createProgramVertex() { mPvOrthoAlloc = new ProgramVertex.MatrixAllocation(mRS); mPvOrthoAlloc.setupOrthoWindow(mWidth, mHeight); mPvOrthoAlloc.setupProjectionNormalized(mWidth, mHeight); ProgramVertex.Builder pvb = new ProgramVertex.Builder(mRS, null, null); pvb.setTextureMatrixEnable(true); mPvBackground = pvb.create(); mLight = new Light.Builder(mRS).create(); mLight.setPosition(0.0f, 0.0f, -1.0f); ProgramVertex.Builder builder = new ProgramVertex.Builder(mRS, null, null); builder.setTextureMatrixEnable(true); builder.addLight(mLight); mPvBackground = builder.create(); mPvBackground.bindAllocation(mPvOrthoAlloc); mPvBackground.setName("PVBackground"); } public void addDrop(float x, float y) { mState.subData1D(RSID_STATE_DROP_X, 2, new int[] { (int) ((x / mWidth) * mMeshWidth), (int) ((y / mHeight) * mMeshHeight) }); } } libs/rs/java/Fall/src/com/android/fall/rs/FallView.java +17 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package com.android.fall.rs; import android.content.Context; import android.view.SurfaceHolder; import android.view.MotionEvent; import android.renderscript.RenderScript; import android.renderscript.RSSurfaceView; Loading @@ -41,4 +42,20 @@ class FallView extends RSSurfaceView { public void surfaceDestroyed(SurfaceHolder holder) { if (mRender != null) mRender.destroy(); } @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: case MotionEvent.ACTION_MOVE: mRender.addDrop(event.getX(), event.getY()); try { Thread.sleep(16); } catch (InterruptedException e) { // Ignore } break; } return true; } } libs/rs/java/Grass/src/com/android/grass/rs/GrassRS.java +2 −2 Original line number Diff line number Diff line Loading @@ -123,7 +123,7 @@ class GrassRS { createProgramFragmentStore(); createProgramFragment(); createScriptStructures(); loadSkyTextures(); loadTextures(); ScriptC.Builder sb = new ScriptC.Builder(mRS); sb.setScript(mResources, R.raw.grass); Loading Loading @@ -172,7 +172,7 @@ class GrassRS { blades[index + BLADE_STRUCT_B] = random(0.65f) + 0.35f; } private void loadSkyTextures() { private void loadTextures() { mTextureBufferIDs = new int[TEXTURES_COUNT]; mTextures = new Allocation[TEXTURES_COUNT]; mTexturesIDs = Allocation.createSized(mRS, USER_FLOAT, TEXTURES_COUNT); Loading libs/rs/rsProgramVertex.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -63,7 +63,7 @@ void ProgramVertex::setupGL(ProgramVertexState *state) glMatrixMode(GL_MODELVIEW); glLoadIdentity(); if (mLightCount) { int v = 1; int v = 0; glEnable(GL_LIGHTING); glLightModelxv(GL_LIGHT_MODEL_TWO_SIDE, &v); for (uint32_t ct = 0; ct < mLightCount; ct++) { Loading Loading
libs/rs/java/Fall/res/raw/fall.c +207 −2 Original line number Diff line number Diff line // Copyright (C) 2009 The Android Open Source Project // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #pragma version(1) #pragma stateVertex(PVBackground) #pragma stateFragment(PFBackground) #pragma stateFragmentStore(PSBackground) #pragma stateFragmentStore(PFSBackground) #define RSID_STATE 0 #define RSID_FRAME_COUNT 0 #define RSID_WIDTH 1 #define RSID_HEIGHT 2 #define RSID_MESH_WIDTH 3 #define RSID_MESH_HEIGHT 4 #define RSID_RIPPLE_MAP_SIZE 5 #define RSID_RIPPLE_INDEX 6 #define RSID_DROP_X 7 #define RSID_DROP_Y 8 #define RSID_TEXTURES 1 #define RSID_RIPPLE_MAP 2 #define RSID_REFRACTION_MAP 3 #define REFRACTION 1.333f #define DAMP 4 #define DROP_RADIUS 2 // The higher, the smaller the ripple #define RIPPLE_HEIGHT 10.0f int offset(int x, int y, int width) { return x + 1 + (y + 1) * (width + 2); } void drop(int x, int y, int r) { int width = loadI32(RSID_STATE, RSID_MESH_WIDTH); int height = loadI32(RSID_STATE, RSID_MESH_HEIGHT); if (x < r) x = r; if (y < r) y = r; if (x >= width - r) x = width - r - 1; if (y >= height - r) x = height - r - 1; x = width - x; int rippleMapSize = loadI32(RSID_STATE, RSID_RIPPLE_MAP_SIZE); int index = loadI32(RSID_STATE, RSID_RIPPLE_INDEX); int origin = offset(0, 0, width); int* current = loadArrayI32(RSID_RIPPLE_MAP, index * rippleMapSize + origin); int sqr = r * r; int h = 0; for ( ; h < r; h++) { int sqv = h * h; int yn = origin + (y - h) * (width + 2); int yp = origin + (y + h) * (width + 2); int w = 0; for ( ; w < r; w++) { int squ = w * w; if (squ + sqv < sqr) { int v = -sqrtf((sqr - (squ + sqv)) << 16); current[yn + x + w] = v; current[yp + x + w] = v; current[yn + x - w] = v; current[yp + x - w] = v; } } } } void updateRipples() { int rippleMapSize = loadI32(RSID_STATE, RSID_RIPPLE_MAP_SIZE); int width = loadI32(RSID_STATE, RSID_MESH_WIDTH); int height = loadI32(RSID_STATE, RSID_MESH_HEIGHT); int index = loadI32(RSID_STATE, RSID_RIPPLE_INDEX); int origin = offset(0, 0, width); int* current = loadArrayI32(RSID_RIPPLE_MAP, index * rippleMapSize + origin); int* next = loadArrayI32(RSID_RIPPLE_MAP, (1 - index) * rippleMapSize + origin); storeI32(RSID_STATE, RSID_RIPPLE_INDEX, 1 - index); int a = 1; int b = width + 2; int h = height; while (h) { int w = width; while (w) { int droplet = ((current[-b] + current[b] + current[-a] + current[a]) >> 1) - next[0]; droplet -= (droplet >> DAMP); next[0] = droplet; current++; next++; w--; } current += 2; next += 2; h--; } } void generateRipples() { int rippleMapSize = loadI32(RSID_STATE, RSID_RIPPLE_MAP_SIZE); int width = loadI32(RSID_STATE, RSID_MESH_WIDTH); int height = loadI32(RSID_STATE, RSID_MESH_HEIGHT); int index = loadI32(RSID_STATE, RSID_RIPPLE_INDEX); int origin = offset(0, 0, width); int b = width + 2; int* current = loadArrayI32(RSID_RIPPLE_MAP, index * rippleMapSize + origin); float *vertices = loadTriangleMeshVerticesF(NAMED_mesh); int h = height - 1; while (h >= 0) { int w = width - 1; int wave = current[0]; int offset = h * width; while (w >= 0) { int nextWave = current[1]; int dx = nextWave - wave; int dy = current[b] - wave; // Update Z coordinate of the vertex vertices[(offset + w) * 8 + 7] = (dy / 512.0f) / RIPPLE_HEIGHT; w--; current++; wave = nextWave; } h--; current += 2; } // Compute the normals for lighting int y = 0; for ( ; y < height; y++) { int x = 0; int yOffset = y * width; for ( ; x < width; x++) { // V1 float v1x = vertices[(yOffset + x) * 8 + 5]; float v1y = vertices[(yOffset + x) * 8 + 6]; float v1z = vertices[(yOffset + x) * 8 + 7]; // V2 float v2x = vertices[(yOffset + x + 1) * 8 + 5]; float v2y = vertices[(yOffset + x + 1) * 8 + 6]; float v2z = vertices[(yOffset + x + 1) * 8 + 7]; // V3 float v3x = vertices[(yOffset + width + x) * 8 + 5]; float v3y = vertices[(yOffset + width + x) * 8 + 6]; float v3z = vertices[(yOffset + width + x) * 8 + 7]; // N1 float n1x = v2x - v1x; float n1y = v2y - v1y; float n1z = v2z - v1z; // N2 float n2x = v3x - v1x; float n2y = v3y - v1y; float n2z = v3z - v1z; // N1 x N2 float n3x = n1y * n2z - n1z * n2y; float n3y = n1z * n2x - n1x * n2z; float n3z = n1x * n2y - n1y * n2x; // Normalize float len = magf3(n3x, n3y, n3z); n3x /= len; n3y /= len; n3z /= len; vertices[(yOffset + x) * 8 + 0] = -n3x; vertices[(yOffset + x) * 8 + 1] = -n3y; vertices[(yOffset + x) * 8 + 2] = -n3z; } } } int main(int index) { color(1.0f, 0.0f, 0.0f, 1.0f); int dropX = loadI32(RSID_STATE, RSID_DROP_X); if (dropX != -1) { int dropY = loadI32(RSID_STATE, RSID_DROP_Y); drop(dropX, dropY, DROP_RADIUS); storeI32(RSID_STATE, RSID_DROP_X, -1); storeI32(RSID_STATE, RSID_DROP_Y, -1); } updateRipples(); generateRipples(); updateTriangleMesh(NAMED_mesh); ambient(0.0f, 0.1f, 0.9f, 1.0f); diffuse(0.0f, 0.1f, 0.9f, 1.0f); drawTriangleMesh(NAMED_mesh); return 1; Loading
libs/rs/java/Fall/src/com/android/fall/rs/FallRS.java +94 −35 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import android.renderscript.ProgramVertex; import android.renderscript.Allocation; import android.renderscript.Sampler; import android.renderscript.Element; import android.renderscript.Light; import static android.renderscript.Sampler.Value.LINEAR; import static android.renderscript.Sampler.Value.CLAMP; import static android.renderscript.ProgramStore.DepthFunc.*; Loading @@ -38,16 +39,26 @@ import android.graphics.Bitmap; import java.util.TimeZone; class FallRS { private static final int MESH_RESOLUTION = 32; private static final int MESH_RESOLUTION = 48; private static final int RSID_STATE = 0; private static final int RSID_STATE_FRAMECOUNT = 0; private static final int RSID_STATE_WIDTH = 1; private static final int RSID_STATE_HEIGHT = 2; private static final int RSID_STATE_MESH_WIDTH = 3; private static final int RSID_STATE_MESH_HEIGHT = 4; private static final int RSID_STATE_RIPPLE_MAP_SIZE = 5; private static final int RSID_STATE_RIPPLE_INDEX = 6; private static final int RSID_STATE_DROP_X = 7; private static final int RSID_STATE_DROP_Y = 8; private static final int RSID_TEXTURES = 1; private static final int TEXTURES_COUNT = 0; private static final int RSID_RIPPLE_MAP = 2; private static final int RSID_REFRACTION_MAP = 3; private Resources mResources; private RenderScript mRS; private final BitmapFactory.Options mBitmapOptions = new BitmapFactory.Options(); Loading @@ -61,6 +72,7 @@ class FallRS { private ProgramStore mPfsBackground; private ProgramVertex mPvBackground; private ProgramVertex.MatrixAllocation mPvOrthoAlloc; private Light mLight; private Allocation mTexturesIDs; private Allocation[] mTextures; Loading @@ -68,6 +80,11 @@ class FallRS { private Allocation mState; private RenderScript.TriangleMesh mMesh; private int mMeshWidth; private int mMeshHeight; private Allocation mRippleMap; private Allocation mRefractionMap; public FallRS(int width, int height) { mWidth = width; Loading Loading @@ -96,6 +113,9 @@ class FallRS { mState.destroy(); mTextureBufferIDs = null; mMesh.destroy(); mLight.destroy(); mRippleMap.destroy(); mRefractionMap.destroy(); } @Override Loading @@ -111,8 +131,9 @@ class FallRS { createProgramVertex(); createProgramFragmentStore(); createProgramFragment(); createScriptStructures(); createMesh(); createScriptStructures(); loadTextures(); ScriptC.Builder sb = new ScriptC.Builder(mRS); sb.setScript(mResources, R.raw.fall); Loading @@ -121,16 +142,17 @@ class FallRS { mScript.setClearColor(0.0f, 0.0f, 0.0f, 1.0f); mScript.setTimeZone(TimeZone.getDefault().getID()); loadSkyTextures(); mScript.bindAllocation(mState, RSID_STATE); mScript.bindAllocation(mTexturesIDs, RSID_TEXTURES); mScript.bindAllocation(mRippleMap, RSID_RIPPLE_MAP); mScript.bindAllocation(mRefractionMap, RSID_REFRACTION_MAP); mRS.contextBindRootScript(mScript); } private void createMesh() { final RenderScript rs = mRS; rs.triangleMeshBegin(Element.XYZ_F32, Element.INDEX_16); rs.triangleMeshBegin(Element.NORM_ST_XYZ_F32, Element.INDEX_16); int wResolution; int hResolution; Loading @@ -146,13 +168,20 @@ class FallRS { hResolution = MESH_RESOLUTION; } final float quadWidth = width / (float) wResolution; final float quadHeight = height / (float) hResolution; final float glHeight = 2.0f * height / (float) width; final float quadWidth = 2.0f / (float) wResolution; final float quadHeight = glHeight / (float) hResolution; wResolution += 2; hResolution += 2; for (int y = 0; y <= hResolution; y++) { final float yOffset = y * quadHeight; final float yOffset = y * quadHeight - glHeight / 2.0f - quadHeight; for (int x = 0; x <= wResolution; x++) { rs.triangleMeshAddVertex_XYZ(x * quadWidth, yOffset, 0.0f); rs.triangleMeshAddVertex_XYZ_ST_NORM( -1.0f + x * quadWidth - quadWidth, yOffset, 0.0f, x / (float) wResolution, y / (float) wResolution, 0.0f, 0.0f, -1.0f); } } Loading @@ -167,18 +196,41 @@ class FallRS { mMesh = rs.triangleMeshCreate(); mMesh.setName("mesh"); mMeshWidth = wResolution + 1; mMeshHeight = hResolution + 1; } private void createScriptStructures() { final int[] data = new int[3]; final int rippleMapSize = (mMeshWidth + 2) * (mMeshHeight + 2); final int[] data = new int[9]; mState = Allocation.createSized(mRS, USER_I32, data.length); data[RSID_STATE_FRAMECOUNT] = 0; data[RSID_STATE_WIDTH] = mWidth; data[RSID_STATE_HEIGHT] = mHeight; data[RSID_STATE_MESH_WIDTH] = mMeshWidth; data[RSID_STATE_MESH_HEIGHT] = mMeshHeight; data[RSID_STATE_RIPPLE_MAP_SIZE] = rippleMapSize; data[RSID_STATE_RIPPLE_INDEX] = 0; data[RSID_STATE_DROP_X] = mMeshWidth / 2; data[RSID_STATE_DROP_Y] = mMeshHeight / 2; mState.data(data); final int[] rippleMap = new int[rippleMapSize * 2]; mRippleMap = Allocation.createSized(mRS, USER_I32, rippleMap.length); final int[] refractionMap = new int[513]; float ir = 1.0f / 1.333f; for (int i = 0; i < refractionMap.length; i++) { float d = (float) Math.tan(Math.asin(Math.sin(Math.atan(i * (1.0f / 256.0f))) * ir)); refractionMap[i] = (int) Math.floor(d * (1 << 16) + 0.5f); } mRefractionMap = Allocation.createSized(mRS, USER_I32, refractionMap.length); mRefractionMap.data(refractionMap); } private void loadSkyTextures() { private void loadTextures() { mTextureBufferIDs = new int[TEXTURES_COUNT]; mTextures = new Allocation[TEXTURES_COUNT]; mTexturesIDs = Allocation.createSized(mRS, USER_FLOAT, TEXTURES_COUNT); Loading Loading @@ -215,42 +267,49 @@ class FallRS { } private void createProgramFragment() { Sampler.Builder bs = new Sampler.Builder(mRS); bs.setMin(LINEAR); bs.setMag(LINEAR); bs.setWrapS(CLAMP); bs.setWrapT(CLAMP); mSampler = bs.create(); ProgramFragment.Builder b; b = new ProgramFragment.Builder(mRS, null, null); b.setTexEnable(true, 0); b.setTexEnvMode(REPLACE, 0); mPfBackground = b.create(); Sampler.Builder sampleBuilder = new Sampler.Builder(mRS); sampleBuilder.setMin(LINEAR); sampleBuilder.setMag(LINEAR); sampleBuilder.setWrapS(CLAMP); sampleBuilder.setWrapT(CLAMP); mSampler = sampleBuilder.create(); ProgramFragment.Builder builder = new ProgramFragment.Builder(mRS, null, null); builder.setTexEnable(true, 0); builder.setTexEnvMode(REPLACE, 0); mPfBackground = builder.create(); mPfBackground.setName("PFBackground"); mPfBackground.bindSampler(mSampler, 0); } private void createProgramFragmentStore() { ProgramStore.Builder b; b = new ProgramStore.Builder(mRS, null, null); b.setDepthFunc(ALWAYS); b.setBlendFunc(BlendSrcFunc.SRC_ALPHA, BlendDstFunc.ONE_MINUS_SRC_ALPHA); b.setDitherEnable(true); b.setDepthMask(false); mPfsBackground = b.create(); ProgramStore.Builder builder = new ProgramStore.Builder(mRS, null, null); builder.setDepthFunc(LESS); builder.setBlendFunc(BlendSrcFunc.SRC_ALPHA, BlendDstFunc.ONE_MINUS_SRC_ALPHA); builder.setDitherEnable(true); builder.setDepthMask(true); mPfsBackground = builder.create(); mPfsBackground.setName("PFSBackground"); } private void createProgramVertex() { mPvOrthoAlloc = new ProgramVertex.MatrixAllocation(mRS); mPvOrthoAlloc.setupOrthoWindow(mWidth, mHeight); mPvOrthoAlloc.setupProjectionNormalized(mWidth, mHeight); ProgramVertex.Builder pvb = new ProgramVertex.Builder(mRS, null, null); pvb.setTextureMatrixEnable(true); mPvBackground = pvb.create(); mLight = new Light.Builder(mRS).create(); mLight.setPosition(0.0f, 0.0f, -1.0f); ProgramVertex.Builder builder = new ProgramVertex.Builder(mRS, null, null); builder.setTextureMatrixEnable(true); builder.addLight(mLight); mPvBackground = builder.create(); mPvBackground.bindAllocation(mPvOrthoAlloc); mPvBackground.setName("PVBackground"); } public void addDrop(float x, float y) { mState.subData1D(RSID_STATE_DROP_X, 2, new int[] { (int) ((x / mWidth) * mMeshWidth), (int) ((y / mHeight) * mMeshHeight) }); } }
libs/rs/java/Fall/src/com/android/fall/rs/FallView.java +17 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package com.android.fall.rs; import android.content.Context; import android.view.SurfaceHolder; import android.view.MotionEvent; import android.renderscript.RenderScript; import android.renderscript.RSSurfaceView; Loading @@ -41,4 +42,20 @@ class FallView extends RSSurfaceView { public void surfaceDestroyed(SurfaceHolder holder) { if (mRender != null) mRender.destroy(); } @Override public boolean onTouchEvent(MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: case MotionEvent.ACTION_MOVE: mRender.addDrop(event.getX(), event.getY()); try { Thread.sleep(16); } catch (InterruptedException e) { // Ignore } break; } return true; } }
libs/rs/java/Grass/src/com/android/grass/rs/GrassRS.java +2 −2 Original line number Diff line number Diff line Loading @@ -123,7 +123,7 @@ class GrassRS { createProgramFragmentStore(); createProgramFragment(); createScriptStructures(); loadSkyTextures(); loadTextures(); ScriptC.Builder sb = new ScriptC.Builder(mRS); sb.setScript(mResources, R.raw.grass); Loading Loading @@ -172,7 +172,7 @@ class GrassRS { blades[index + BLADE_STRUCT_B] = random(0.65f) + 0.35f; } private void loadSkyTextures() { private void loadTextures() { mTextureBufferIDs = new int[TEXTURES_COUNT]; mTextures = new Allocation[TEXTURES_COUNT]; mTexturesIDs = Allocation.createSized(mRS, USER_FLOAT, TEXTURES_COUNT); Loading
libs/rs/rsProgramVertex.cpp +1 −1 Original line number Diff line number Diff line Loading @@ -63,7 +63,7 @@ void ProgramVertex::setupGL(ProgramVertexState *state) glMatrixMode(GL_MODELVIEW); glLoadIdentity(); if (mLightCount) { int v = 1; int v = 0; glEnable(GL_LIGHTING); glLightModelxv(GL_LIGHT_MODEL_TWO_SIDE, &v); for (uint32_t ct = 0; ct < mLightCount; ct++) { Loading