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.fbotest) 18 19 #include "rs_graphics.rsh" 20 21 rs_program_vertex gPVBackground; 22 rs_program_fragment gPFBackground; 23 24 rs_allocation gTGrid; 25 26 rs_program_store gPFSBackground; 27 28 rs_font gItalic; 29 rs_allocation gTextAlloc; 30 31 rs_allocation gOffscreen; 32 rs_allocation gOffscreenDepth; 33 34 typedef struct MeshInfo { 35 rs_mesh mMesh; 36 int mNumIndexSets; 37 float3 bBoxMin; 38 float3 bBoxMax; 39 } MeshInfo_t; 40 41 MeshInfo_t *gMeshes; 42 43 static float3 gLookAt; 44 45 static float gRotateX; 46 static float gRotateY; 47 static float gZoom; 48 49 static float gLastX; 50 static float gLastY; 51 52 void onActionDown(float x, float y) { 53 gLastX = x; 54 gLastY = y; 55 } 56 57 void onActionScale(float scale) { 58 59 gZoom *= 1.0f / scale; 60 gZoom = max(0.1f, min(gZoom, 500.0f)); 61 } 62 63 void onActionMove(float x, float y) { 64 float dx = gLastX - x; 65 float dy = gLastY - y; 66 67 if (fabs(dy) <= 2.0f) { 68 dy = 0.0f; 69 } 70 if (fabs(dx) <= 2.0f) { 71 dx = 0.0f; 72 } 73 74 gRotateY -= dx; 75 if (gRotateY > 360) { 76 gRotateY -= 360; 77 } 78 if (gRotateY < 0) { 79 gRotateY += 360; 80 } 81 82 gRotateX -= dy; 83 gRotateX = min(gRotateX, 80.0f); 84 gRotateX = max(gRotateX, -80.0f); 85 86 gLastX = x; 87 gLastY = y; 88 } 89 90 void init() { 91 gRotateX = 0.0f; 92 gRotateY = 0.0f; 93 gZoom = 50.0f; 94 gLookAt = 0.0f; 95 } 96 97 void updateMeshInfo() { 98 rs_allocation allMeshes = rsGetAllocation(gMeshes); 99 int size = rsAllocationGetDimX(allMeshes); 100 gLookAt = 0.0f; 101 float minX, minY, minZ, maxX, maxY, maxZ; 102 for (int i = 0; i < size; i++) { 103 MeshInfo_t *info = (MeshInfo_t*)rsGetElementAt(allMeshes, i); 104 rsgMeshComputeBoundingBox(info->mMesh, 105 &minX, &minY, &minZ, 106 &maxX, &maxY, &maxZ); 107 info->bBoxMin = (minX, minY, minZ); 108 info->bBoxMax = (maxX, maxY, maxZ); 109 gLookAt += (info->bBoxMin + info->bBoxMax)*0.5f; 110 } 111 gLookAt = gLookAt / (float)size; 112 } 113 114 static void renderAllMeshes() { 115 rs_allocation allMeshes = rsGetAllocation(gMeshes); 116 int size = rsAllocationGetDimX(allMeshes); 117 gLookAt = 0.0f; 118 float minX, minY, minZ, maxX, maxY, maxZ; 119 for (int i = 0; i < size; i++) { 120 MeshInfo_t *info = (MeshInfo_t*)rsGetElementAt(allMeshes, i); 121 rsgDrawMesh(info->mMesh); 122 } 123 } 124 125 static void drawDescription() { 126 uint width = rsgGetWidth(); 127 uint height = rsgGetHeight(); 128 int left = 0, right = 0, top = 0, bottom = 0; 129 130 rsgBindFont(gItalic); 131 132 rsgMeasureText(gTextAlloc, &left, &right, &top, &bottom); 133 rsgDrawText(gTextAlloc, 2 -left, height - 2 + bottom); 134 } 135 136 static void renderOffscreen(bool useDepth) { 137 138 rsgBindColorTarget(gOffscreen, 0); 139 if (useDepth) { 140 rsgBindDepthTarget(gOffscreenDepth); 141 rsgClearDepth(1.0f); 142 } else { 143 rsgClearDepthTarget(); 144 } 145 rsgClearColor(0.8f, 0.8f, 0.8f, 1.0f); 146 147 rsgBindProgramVertex(gPVBackground); 148 rs_matrix4x4 proj; 149 float aspect = (float)rsAllocationGetDimX(gOffscreen) / (float)rsAllocationGetDimY(gOffscreen); 150 rsMatrixLoadPerspective(&proj, 30.0f, aspect, 1.0f, 100.0f); 151 rsgProgramVertexLoadProjectionMatrix(&proj); 152 153 rsgBindProgramFragment(gPFBackground); 154 rsgBindProgramStore(gPFSBackground); 155 rsgBindTexture(gPFBackground, 0, gTGrid); 156 157 rs_matrix4x4 matrix; 158 rsMatrixLoadIdentity(&matrix); 159 // Position our models on the screen 160 rsMatrixTranslate(&matrix, gLookAt.x, gLookAt.y, gLookAt.z - gZoom); 161 rsMatrixRotate(&matrix, gRotateX, 1.0f, 0.0f, 0.0f); 162 rsMatrixRotate(&matrix, gRotateY, 0.0f, 1.0f, 0.0f); 163 rsgProgramVertexLoadModelMatrix(&matrix); 164 165 renderAllMeshes(); 166 167 // Render into the frambuffer 168 rsgClearAllRenderTargets(); 169 } 170 171 static void drawOffscreenResult(int posX, int posY) { 172 // display the result 173 rs_matrix4x4 proj, matrix; 174 rsMatrixLoadOrtho(&proj, 0, rsgGetWidth(), rsgGetHeight(), 0, -500, 500); 175 rsgProgramVertexLoadProjectionMatrix(&proj); 176 rsMatrixLoadIdentity(&matrix); 177 rsgProgramVertexLoadModelMatrix(&matrix); 178 rsgBindTexture(gPFBackground, 0, gOffscreen); 179 float startX = posX, startY = posY; 180 float width = 256, height = 256; 181 rsgDrawQuadTexCoords(startX, startY, 0, 0, 1, 182 startX, startY + height, 0, 0, 0, 183 startX + width, startY + height, 0, 1, 0, 184 startX + width, startY, 0, 1, 1); 185 } 186 187 int root(void) { 188 189 rsgClearColor(1.0f, 1.0f, 1.0f, 1.0f); 190 rsgClearDepth(1.0f); 191 192 renderOffscreen(true); 193 drawOffscreenResult(0, 0); 194 195 renderOffscreen(false); 196 drawOffscreenResult(0, 256); 197 198 rsgBindProgramVertex(gPVBackground); 199 rs_matrix4x4 proj; 200 float aspect = (float)rsgGetWidth() / (float)rsgGetHeight(); 201 rsMatrixLoadPerspective(&proj, 30.0f, aspect, 1.0f, 100.0f); 202 rsgProgramVertexLoadProjectionMatrix(&proj); 203 204 rsgBindProgramFragment(gPFBackground); 205 rsgBindProgramStore(gPFSBackground); 206 rsgBindTexture(gPFBackground, 0, gTGrid); 207 208 rs_matrix4x4 matrix; 209 rsMatrixLoadIdentity(&matrix); 210 // Position our models on the screen 211 rsMatrixTranslate(&matrix, gLookAt.x, gLookAt.y, gLookAt.z - gZoom); 212 rsMatrixRotate(&matrix, gRotateX, 1.0f, 0.0f, 0.0f); 213 rsMatrixRotate(&matrix, gRotateY, 0.0f, 1.0f, 0.0f); 214 rsgProgramVertexLoadModelMatrix(&matrix); 215 216 renderAllMeshes(); 217 218 drawDescription(); 219 220 return 0; 221 } 222