1 // Copyright (C) 2011 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //      http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #pragma version(1)
16 
17 #pragma rs java_package_name(com.android.shaderstest)
18 
19 #include "rs_graphics.rsh"
20 
21 rs_program_vertex gPVBackground;
22 rs_program_fragment gPFBackground;
23 
24 typedef struct VignetteConstants_s {
25     float size;
26     float feather;
27     float width;
28     float height;
29 } VignetteConstants;
30 VignetteConstants *gFSVignetteConstants;
31 rs_program_fragment gPFVignette;
32 
33 rs_allocation gTMesh;
34 
35 rs_sampler gLinear;
36 rs_sampler gNearest;
37 
38 rs_program_store gPFSBackground;
39 
40 rs_allocation gScreenDepth;
41 rs_allocation gScreen;
42 
43 typedef struct MeshInfo {
44     rs_mesh mMesh;
45     int mNumIndexSets;
46     float3 bBoxMin;
47     float3 bBoxMax;
48 } MeshInfo_t;
49 MeshInfo_t *gMeshes;
50 
51 static float3 gLookAt;
52 
53 static float gRotateX;
54 static float gRotateY;
55 static float gZoom;
56 
57 static float gLastX;
58 static float gLastY;
59 
60 static float3 toFloat3(float x, float y, float z) {
61     float3 f;
62     f.x = x;
63     f.y = y;
64     f.z = z;
65     return f;
66 }
67 
68 void onActionDown(float x, float y) {
69     gLastX = x;
70     gLastY = y;
71 }
72 
73 void onActionScale(float scale) {
74 
75     gZoom *= 1.0f / scale;
76     gZoom = max(0.1f, min(gZoom, 500.0f));
77 }
78 
79 void onActionMove(float x, float y) {
80     float dx = gLastX - x;
81     float dy = gLastY - y;
82 
83     if (fabs(dy) <= 2.0f) {
84         dy = 0.0f;
85     }
86     if (fabs(dx) <= 2.0f) {
87         dx = 0.0f;
88     }
89 
90     gRotateY -= dx;
91     if (gRotateY > 360) {
92         gRotateY -= 360;
93     }
94     if (gRotateY < 0) {
95         gRotateY += 360;
96     }
97 
98     gRotateX -= dy;
99     gRotateX = min(gRotateX, 80.0f);
100     gRotateX = max(gRotateX, -80.0f);
101 
102     gLastX = x;
103     gLastY = y;
104 }
105 
106 void init() {
107     gRotateX = 0.0f;
108     gRotateY = 0.0f;
109     gZoom = 50.0f;
110     gLookAt = 0.0f;
111 }
112 
113 void updateMeshInfo() {
114     rs_allocation allMeshes = rsGetAllocation(gMeshes);
115     int size = rsAllocationGetDimX(allMeshes);
116     gLookAt = 0.0f;
117     float minX, minY, minZ, maxX, maxY, maxZ;
118     for (int i = 0; i < size; i++) {
119         MeshInfo_t *info = (MeshInfo_t*)rsGetElementAt(allMeshes, i);
120         rsgMeshComputeBoundingBox(info->mMesh,
121                                   &minX, &minY, &minZ,
122                                   &maxX, &maxY, &maxZ);
123         info->bBoxMin = toFloat3(minX, minY, minZ);
124         info->bBoxMax = toFloat3(maxX, maxY, maxZ);
125         gLookAt += (info->bBoxMin + info->bBoxMax)*0.5f;
126     }
127     gLookAt = gLookAt / (float)size;
128 }
129 
130 static void renderAllMeshes() {
131     rs_allocation allMeshes = rsGetAllocation(gMeshes);
132     int size = rsAllocationGetDimX(allMeshes);
133     gLookAt = 0.0f;
134     for (int i = 0; i < size; i++) {
135         MeshInfo_t *info = (MeshInfo_t*)rsGetElementAt(allMeshes, i);
136         rsgDrawMesh(info->mMesh);
137     }
138 }
139 
140 static void renderOffscreen() {
141     rsgBindProgramVertex(gPVBackground);
142     rs_matrix4x4 proj;
143     float aspect = (float) rsAllocationGetDimX(gScreen) / (float) rsAllocationGetDimY(gScreen);
144     rsMatrixLoadPerspective(&proj, 30.0f, aspect, 1.0f, 1000.0f);
145     rsgProgramVertexLoadProjectionMatrix(&proj);
146 
147     rsgBindProgramFragment(gPFBackground);
148     rsgBindTexture(gPFBackground, 0, gTMesh);
149 
150     rs_matrix4x4 matrix;
151 
152     rsMatrixLoadIdentity(&matrix);
153     rsMatrixTranslate(&matrix, gLookAt.x, gLookAt.y, gLookAt.z - gZoom);
154     rsMatrixRotate(&matrix, gRotateX, 1.0f, 0.0f, 0.0f);
155     rsMatrixRotate(&matrix, gRotateY, 0.0f, 1.0f, 0.0f);
156     rsgProgramVertexLoadModelMatrix(&matrix);
157 
158     renderAllMeshes();
159 }
160 
161 static void drawOffscreenResult(int posX, int posY, float width, float height) {
162     // display the result d
163     rs_matrix4x4 proj, matrix;
164     rsMatrixLoadOrtho(&proj, 0, width, height, 0, -500, 500);
165     rsgProgramVertexLoadProjectionMatrix(&proj);
166     rsMatrixLoadIdentity(&matrix);
167     rsgProgramVertexLoadModelMatrix(&matrix);
168     float startX = posX, startY = posY;
169     rsgDrawQuadTexCoords(startX, startY, 0, 0, 1,
170                          startX, startY + height, 0, 0, 0,
171                          startX + width, startY + height, 0, 1, 0,
172                          startX + width, startY, 0, 1, 1);
173 }
174 
175 int root(void) {
176     gFSVignetteConstants->size = 0.58f * 0.58f;
177     gFSVignetteConstants->feather = 0.2f;
178     gFSVignetteConstants->width = (float) rsAllocationGetDimX(gScreen);
179     gFSVignetteConstants->height = (float) rsAllocationGetDimY(gScreen);
180 
181     rsgBindProgramStore(gPFSBackground);
182 
183     // Render scene to fullscreenbuffer
184     rsgBindColorTarget(gScreen, 0);
185     rsgBindDepthTarget(gScreenDepth);
186     rsgClearDepth(1.0f);
187     rsgClearColor(1.0f, 1.0f, 1.0f, 0.0f);
188     renderOffscreen();
189 
190     // Render on screen
191     rsgClearAllRenderTargets();
192     rsgClearColor(1.0f, 1.0f, 1.0f, 1.0f);
193     rsgClearDepth(1.0f);
194 
195     rsgBindProgramFragment(gPFVignette);
196     rsgBindTexture(gPFVignette, 0, gScreen);
197     drawOffscreenResult(0, 0, rsgGetWidth(), rsgGetHeight());
198 
199     return 0;
200 }
201