1 // Copyright (C) 2011-2012 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.scenegraph) 18 19 #include "rs_graphics.rsh" 20 #include "scenegraph_objects.rsh" 21 22 rs_script gTransformScript; 23 rs_script gCameraScript; 24 rs_script gLightScript; 25 rs_script gObjectParamsScript; 26 rs_script gFragmentParamsScript; 27 rs_script gVertexParamsScript; 28 rs_script gCullScript; 29 30 SgTransform *gRootNode; 31 rs_allocation gCameras; 32 rs_allocation gLights; 33 rs_allocation gFragmentShaders; 34 rs_allocation gVertexShaders; 35 rs_allocation gRenderableObjects; 36 37 rs_allocation gRenderPasses; 38 39 // Temporary shaders 40 rs_program_store gPFSBackground; 41 42 uint32_t *gFrontToBack; 43 static uint32_t gFrontToBackCount = 0; 44 uint32_t *gBackToFront; 45 static uint32_t gBackToFrontCount = 0; 46 47 static SgCamera *gActiveCamera = NULL; 48 49 static rs_allocation nullAlloc; 50 51 // #define DEBUG_RENDERABLES 52 static void draw(SgRenderable *obj) { 53 #ifdef DEBUG_RENDERABLES 54 const SgTransform *objTransform = (const SgTransform *)rsGetElementAt(obj->transformMatrix, 0); 55 rsDebug("**** Drawing object with transform", obj); 56 printName(objTransform->name); 57 rsDebug("Model matrix: ", &objTransform->globalMat); 58 printName(obj->name); 59 #endif //DEBUG_RENDERABLES 60 61 const SgRenderState *renderState = (const SgRenderState *)rsGetElementAt(obj->render_state, 0); 62 const SgVertexShader *pv = (const SgVertexShader *)rsGetElementAt(renderState->pv, 0); 63 const SgFragmentShader *pf = (const SgFragmentShader *)rsGetElementAt(renderState->pf, 0); 64 65 if (pv->objectConstIndex != -1) { 66 rsgBindConstant(pv->program, pv->objectConstIndex, obj->pv_const); 67 } 68 if (pf->objectConstIndex != -1) { 69 rsgBindConstant(pf->program, pf->objectConstIndex, obj->pf_const); 70 } 71 72 if (rsIsObject(renderState->ps)) { 73 rsgBindProgramStore(renderState->ps); 74 } else { 75 rsgBindProgramStore(gPFSBackground); 76 } 77 78 if (rsIsObject(renderState->pr)) { 79 rsgBindProgramRaster(renderState->pr); 80 } else { 81 rs_program_raster pr; 82 rsgBindProgramRaster(pr); 83 } 84 85 rsgBindProgramVertex(pv->program); 86 rsgBindProgramFragment(pf->program); 87 88 for (uint32_t i = 0; i < obj->pf_num_textures; i ++) { 89 const SgTexture *tex = rsGetElementAt(obj->pf_textures[i], 0); 90 rsgBindTexture(pf->program, i, tex->texture); 91 } 92 93 rsgDrawMesh(obj->mesh, obj->meshIndex); 94 } 95 96 static void sortToBucket(SgRenderable *obj) { 97 const SgRenderState *renderState = (const SgRenderState *)rsGetElementAt(obj->render_state, 0); 98 if (rsIsObject(renderState->ps)) { 99 bool isOpaque = false; 100 if (isOpaque) { 101 gFrontToBack[gFrontToBackCount++] = (uint32_t)obj; 102 } else { 103 gBackToFront[gBackToFrontCount++] = (uint32_t)obj; 104 } 105 } else { 106 gFrontToBack[gFrontToBackCount++] = (uint32_t)obj; 107 } 108 } 109 110 static void updateActiveCamera(rs_allocation cam) { 111 gActiveCamera = (SgCamera *)rsGetElementAt(cam, 0); 112 } 113 114 static void prepareCameras() { 115 // now compute all the camera matrices 116 if (rsIsObject(gCameras)) { 117 float aspect = (float)rsgGetWidth() / (float)rsgGetHeight(); 118 rsForEach(gCameraScript, gCameras, nullAlloc, &aspect, sizeof(aspect)); 119 } 120 } 121 122 static void prepareLights() { 123 if (rsIsObject(gLights)) { 124 rsForEach(gLightScript, gLights, nullAlloc); 125 } 126 } 127 128 static void drawSorted() { 129 for (int i = 0; i < gFrontToBackCount; i ++) { 130 SgRenderable *current = (SgRenderable*)gFrontToBack[i]; 131 draw(current); 132 } 133 134 for (int i = 0; i < gBackToFrontCount; i ++) { 135 SgRenderable *current = (SgRenderable*)gBackToFront[i]; 136 draw(current); 137 } 138 } 139 140 static void drawAllObjects(rs_allocation allObj) { 141 if (!rsIsObject(allObj)) { 142 return; 143 } 144 145 if (rsIsObject(gVertexShaders)) { 146 rsForEach(gVertexParamsScript, nullAlloc, gVertexShaders, 147 gActiveCamera, sizeof(gActiveCamera)); 148 } 149 if (rsIsObject(gFragmentShaders)) { 150 rsForEach(gFragmentParamsScript, nullAlloc, gFragmentShaders, 151 gActiveCamera, sizeof(gActiveCamera)); 152 } 153 154 // Run the params and cull script 155 rsForEach(gCullScript, nullAlloc, allObj, gActiveCamera, sizeof(gActiveCamera)); 156 rsForEach(gObjectParamsScript, nullAlloc, allObj, gActiveCamera, sizeof(gActiveCamera)); 157 158 int numRenderables = rsAllocationGetDimX(allObj); 159 for (int i = 0; i < numRenderables; i ++) { 160 rs_allocation *drawAlloc = (rs_allocation*)rsGetElementAt(allObj, i); 161 SgRenderable *current = (SgRenderable*)rsGetElementAt(*drawAlloc, 0); 162 if (current->isVisible) { 163 sortToBucket(current); 164 } 165 } 166 drawSorted(); 167 } 168 169 int root(void) { 170 #ifdef DEBUG_RENDERABLES 171 rsDebug("=============================================================================", 0); 172 #endif // DEBUG_RENDERABLES 173 174 // first step is to update the transform hierachy 175 if (gRootNode && rsIsObject(gRootNode->children)) { 176 rsForEach(gTransformScript, gRootNode->children, nullAlloc, 0, 0); 177 } 178 179 prepareCameras(); 180 prepareLights(); 181 182 if (rsIsObject(gRenderPasses)) { 183 rsgClearDepth(1.0f); 184 int numPasses = rsAllocationGetDimX(gRenderPasses); 185 for (uint i = 0; i < numPasses; i ++) { 186 gFrontToBackCount = 0; 187 gBackToFrontCount = 0; 188 SgRenderPass *pass = (SgRenderPass*)rsGetElementAt(gRenderPasses, i); 189 if (rsIsObject(pass->color_target)) { 190 rsgBindColorTarget(pass->color_target, 0); 191 } 192 if (rsIsObject(pass->depth_target)) { 193 rsgBindDepthTarget(pass->depth_target); 194 } 195 if (!rsIsObject(pass->color_target) && 196 !rsIsObject(pass->depth_target)) { 197 rsgClearAllRenderTargets(); 198 } 199 updateActiveCamera(pass->camera); 200 if (pass->should_clear_color) { 201 rsgClearColor(pass->clear_color.x, pass->clear_color.y, 202 pass->clear_color.z, pass->clear_color.w); 203 } 204 if (pass->should_clear_depth) { 205 rsgClearDepth(pass->clear_depth); 206 } 207 drawAllObjects(pass->objects); 208 } 209 } else { 210 gFrontToBackCount = 0; 211 gBackToFrontCount = 0; 212 rsgClearColor(1.0f, 1.0f, 1.0f, 1.0f); 213 rsgClearDepth(1.0f); 214 215 if (rsIsObject(gCameras)) { 216 rs_allocation *camAlloc = (rs_allocation*)rsGetElementAt(gCameras, 0); 217 updateActiveCamera(*camAlloc); 218 } 219 drawAllObjects(gRenderableObjects); 220 } 221 return 10; 222 } 223 224 // Search through sorted and culled objects 225 void pick(int screenX, int screenY) { 226 float3 pnt, vec; 227 getCameraRay(gActiveCamera, screenX, screenY, &pnt, &vec); 228 229 for (int i = 0; i < gFrontToBackCount; i ++) { 230 SgRenderable *current = (SgRenderable*)gFrontToBack[i]; 231 bool isPicked = intersect(current, pnt, vec); 232 if (isPicked) { 233 current->cullType = CULL_ALWAYS; 234 } 235 } 236 237 for (int i = 0; i < gBackToFrontCount; i ++) { 238 SgRenderable *current = (SgRenderable*)gBackToFront[i]; 239 bool isPicked = intersect(current, pnt, vec); 240 if (isPicked) { 241 current->cullType = CULL_ALWAYS; 242 } 243 } 244 } 245