Home | History | Annotate | Download | only in scenegraph
      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