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 void onActionDown(float x, float y) { 61 gLastX = x; 62 gLastY = y; 63 } 64 65 void onActionScale(float scale) { 66 67 gZoom *= 1.0f / scale; 68 gZoom = max(0.1f, min(gZoom, 500.0f)); 69 } 70 71 void onActionMove(float x, float y) { 72 float dx = gLastX - x; 73 float dy = gLastY - y; 74 75 if (fabs(dy) <= 2.0f) { 76 dy = 0.0f; 77 } 78 if (fabs(dx) <= 2.0f) { 79 dx = 0.0f; 80 } 81 82 gRotateY -= dx; 83 if (gRotateY > 360) { 84 gRotateY -= 360; 85 } 86 if (gRotateY < 0) { 87 gRotateY += 360; 88 } 89 90 gRotateX -= dy; 91 gRotateX = min(gRotateX, 80.0f); 92 gRotateX = max(gRotateX, -80.0f); 93 94 gLastX = x; 95 gLastY = y; 96 } 97 98 void init() { 99 gRotateX = 0.0f; 100 gRotateY = 0.0f; 101 gZoom = 50.0f; 102 gLookAt = 0.0f; 103 } 104 105 void updateMeshInfo() { 106 rs_allocation allMeshes = rsGetAllocation(gMeshes); 107 int size = rsAllocationGetDimX(allMeshes); 108 gLookAt = 0.0f; 109 float minX, minY, minZ, maxX, maxY, maxZ; 110 for (int i = 0; i < size; i++) { 111 MeshInfo_t *info = (MeshInfo_t*)rsGetElementAt(allMeshes, i); 112 rsgMeshComputeBoundingBox(info->mMesh, 113 &minX, &minY, &minZ, 114 &maxX, &maxY, &maxZ); 115 info->bBoxMin = (minX, minY, minZ); 116 info->bBoxMax = (maxX, maxY, maxZ); 117 gLookAt += (info->bBoxMin + info->bBoxMax)*0.5f; 118 } 119 gLookAt = gLookAt / (float)size; 120 } 121 122 static void renderAllMeshes() { 123 rs_allocation allMeshes = rsGetAllocation(gMeshes); 124 int size = rsAllocationGetDimX(allMeshes); 125 gLookAt = 0.0f; 126 float minX, minY, minZ, maxX, maxY, maxZ; 127 for (int i = 0; i < size; i++) { 128 MeshInfo_t *info = (MeshInfo_t*)rsGetElementAt(allMeshes, i); 129 rsgDrawMesh(info->mMesh); 130 } 131 } 132 133 static void renderOffscreen() { 134 rsgBindProgramVertex(gPVBackground); 135 rs_matrix4x4 proj; 136 float aspect = (float) rsAllocationGetDimX(gScreen) / (float) rsAllocationGetDimY(gScreen); 137 rsMatrixLoadPerspective(&proj, 30.0f, aspect, 1.0f, 1000.0f); 138 rsgProgramVertexLoadProjectionMatrix(&proj); 139 140 rsgBindProgramFragment(gPFBackground); 141 rsgBindTexture(gPFBackground, 0, gTMesh); 142 143 rs_matrix4x4 matrix; 144 145 rsMatrixLoadIdentity(&matrix); 146 rsMatrixTranslate(&matrix, gLookAt.x, gLookAt.y, gLookAt.z - gZoom); 147 rsMatrixRotate(&matrix, gRotateX, 1.0f, 0.0f, 0.0f); 148 rsMatrixRotate(&matrix, gRotateY, 0.0f, 1.0f, 0.0f); 149 rsgProgramVertexLoadModelMatrix(&matrix); 150 151 renderAllMeshes(); 152 } 153 154 static void drawOffscreenResult(int posX, int posY, float width, float height) { 155 // display the result d 156 rs_matrix4x4 proj, matrix; 157 rsMatrixLoadOrtho(&proj, 0, width, height, 0, -500, 500); 158 rsgProgramVertexLoadProjectionMatrix(&proj); 159 rsMatrixLoadIdentity(&matrix); 160 rsgProgramVertexLoadModelMatrix(&matrix); 161 float startX = posX, startY = posY; 162 rsgDrawQuadTexCoords(startX, startY, 0, 0, 1, 163 startX, startY + height, 0, 0, 0, 164 startX + width, startY + height, 0, 1, 0, 165 startX + width, startY, 0, 1, 1); 166 } 167 168 int root(void) { 169 gFSVignetteConstants->size = 0.58f * 0.58f; 170 gFSVignetteConstants->feather = 0.2f; 171 gFSVignetteConstants->width = (float) rsAllocationGetDimX(gScreen); 172 gFSVignetteConstants->height = (float) rsAllocationGetDimY(gScreen); 173 174 rsgBindProgramStore(gPFSBackground); 175 176 // Render scene to fullscreenbuffer 177 rsgBindColorTarget(gScreen, 0); 178 rsgBindDepthTarget(gScreenDepth); 179 rsgClearDepth(1.0f); 180 rsgClearColor(1.0f, 1.0f, 1.0f, 0.0f); 181 renderOffscreen(); 182 183 // Render on screen 184 rsgClearAllRenderTargets(); 185 rsgClearColor(1.0f, 1.0f, 1.0f, 1.0f); 186 rsgClearDepth(1.0f); 187 188 rsgBindProgramFragment(gPFVignette); 189 rsgBindTexture(gPFVignette, 0, gScreen); 190 drawOffscreenResult(0, 0, rsgGetWidth(), rsgGetHeight()); 191 192 return 0; 193 } 194