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 float minX, minY, minZ, maxX, maxY, maxZ; 135 for (int i = 0; i < size; i++) { 136 MeshInfo_t *info = (MeshInfo_t*)rsGetElementAt(allMeshes, i); 137 rsgDrawMesh(info->mMesh); 138 } 139 } 140 141 static void renderOffscreen() { 142 rsgBindProgramVertex(gPVBackground); 143 rs_matrix4x4 proj; 144 float aspect = (float) rsAllocationGetDimX(gScreen) / (float) rsAllocationGetDimY(gScreen); 145 rsMatrixLoadPerspective(&proj, 30.0f, aspect, 1.0f, 1000.0f); 146 rsgProgramVertexLoadProjectionMatrix(&proj); 147 148 rsgBindProgramFragment(gPFBackground); 149 rsgBindTexture(gPFBackground, 0, gTMesh); 150 151 rs_matrix4x4 matrix; 152 153 rsMatrixLoadIdentity(&matrix); 154 rsMatrixTranslate(&matrix, gLookAt.x, gLookAt.y, gLookAt.z - gZoom); 155 rsMatrixRotate(&matrix, gRotateX, 1.0f, 0.0f, 0.0f); 156 rsMatrixRotate(&matrix, gRotateY, 0.0f, 1.0f, 0.0f); 157 rsgProgramVertexLoadModelMatrix(&matrix); 158 159 renderAllMeshes(); 160 } 161 162 static void drawOffscreenResult(int posX, int posY, float width, float height) { 163 // display the result d 164 rs_matrix4x4 proj, matrix; 165 rsMatrixLoadOrtho(&proj, 0, width, height, 0, -500, 500); 166 rsgProgramVertexLoadProjectionMatrix(&proj); 167 rsMatrixLoadIdentity(&matrix); 168 rsgProgramVertexLoadModelMatrix(&matrix); 169 float startX = posX, startY = posY; 170 rsgDrawQuadTexCoords(startX, startY, 0, 0, 1, 171 startX, startY + height, 0, 0, 0, 172 startX + width, startY + height, 0, 1, 0, 173 startX + width, startY, 0, 1, 1); 174 } 175 176 int root(void) { 177 gFSVignetteConstants->size = 0.58f * 0.58f; 178 gFSVignetteConstants->feather = 0.2f; 179 gFSVignetteConstants->width = (float) rsAllocationGetDimX(gScreen); 180 gFSVignetteConstants->height = (float) rsAllocationGetDimY(gScreen); 181 182 rsgBindProgramStore(gPFSBackground); 183 184 // Render scene to fullscreenbuffer 185 rsgBindColorTarget(gScreen, 0); 186 rsgBindDepthTarget(gScreenDepth); 187 rsgClearDepth(1.0f); 188 rsgClearColor(1.0f, 1.0f, 1.0f, 0.0f); 189 renderOffscreen(); 190 191 // Render on screen 192 rsgClearAllRenderTargets(); 193 rsgClearColor(1.0f, 1.0f, 1.0f, 1.0f); 194 rsgClearDepth(1.0f); 195 196 rsgBindProgramFragment(gPFVignette); 197 rsgBindTexture(gPFVignette, 0, gScreen); 198 drawOffscreenResult(0, 0, rsgGetWidth(), rsgGetHeight()); 199 200 return 0; 201 } 202