1// Fountain test script
2#pragma version(1)
3
4#pragma rs java_package_name(com.example.android.rs.fountainfbo)
5
6#pragma stateFragment(parent)
7
8#include "rs_graphics.rsh"
9
10static int newPart = 0;
11rs_mesh partMesh;
12rs_program_vertex gProgramVertex;
13
14//allocation for color buffer
15rs_allocation gColorBuffer;
16//fragment shader for rendering without a texture (used for rendering to framebuffer object)
17rs_program_fragment gProgramFragment;
18//fragment shader for rendering with a texture (used for rendering to default framebuffer)
19rs_program_fragment gTextureProgramFragment;
20
21typedef struct __attribute__((packed, aligned(4))) Point {
22    float2 delta;
23    float2 position;
24    uchar4 color;
25} Point_t;
26Point_t *point;
27
28int root() {
29    float dt = min(rsGetDt(), 0.1f);
30    rsgClearColor(0.f, 0.f, 0.f, 1.f);
31    const float height = rsgGetHeight();
32    const int size = rsAllocationGetDimX(rsGetAllocation(point));
33    float dy2 = dt * (10.f);
34    Point_t * p = point;
35    for (int ct=0; ct < size; ct++) {
36        p->delta.y += dy2;
37        p->position += p->delta;
38        if ((p->position.y > height) && (p->delta.y > 0)) {
39            p->delta.y *= -0.3f;
40        }
41        p++;
42    }
43    //Tell Renderscript runtime to render to the frame buffer object
44    rsgBindColorTarget(gColorBuffer, 0);
45
46    //Begin rendering on a white background
47    rsgClearColor(1.f, 1.f, 1.f, 1.f);
48    rsgDrawMesh(partMesh);
49
50    //When done, tell Renderscript runtime to stop rendering to framebuffer object
51    rsgClearAllRenderTargets();
52
53    //Bind a new fragment shader that declares the framebuffer object to be used as a texture
54    rsgBindProgramFragment(gTextureProgramFragment);
55
56    //Bind the framebuffer object to the fragment shader at slot 0 as a texture
57    rsgBindTexture(gTextureProgramFragment, 0, gColorBuffer);
58
59    //Draw a quad using the framebuffer object as the texture
60    float startX = 10, startY = 10;
61    float s = 256;
62    rsgDrawQuadTexCoords(startX, startY, 0, 0, 1,
63                         startX, startY + s, 0, 0, 0,
64                         startX + s, startY + s, 0, 1, 0,
65                         startX + s, startY, 0, 1, 1);
66
67    //Rebind the original fragment shader to render as normal
68    rsgBindProgramFragment(gProgramFragment);
69
70    //Render the main scene
71    rsgDrawMesh(partMesh);
72
73    return 1;
74}
75
76static float4 partColor[10];
77void addParticles(int rate, float x, float y, int index, bool newColor)
78{
79    if (newColor) {
80        partColor[index].x = rsRand(0.5f, 1.0f);
81        partColor[index].y = rsRand(1.0f);
82        partColor[index].z = rsRand(1.0f);
83    }
84    float rMax = ((float)rate) * 0.02f;
85    int size = rsAllocationGetDimX(rsGetAllocation(point));
86    uchar4 c = rsPackColorTo8888(partColor[index]);
87
88    Point_t * np = &point[newPart];
89    float2 p = {x, y};
90    while (rate--) {
91        float angle = rsRand(3.14f * 2.f);
92        float len = rsRand(rMax);
93        np->delta.x = len * sin(angle);
94        np->delta.y = len * cos(angle);
95        np->position = p;
96        np->color = c;
97        newPart++;
98        np++;
99        if (newPart >= size) {
100            newPart = 0;
101            np = &point[newPart];
102        }
103    }
104}
105
106
107