/*! \param flip \param disable_hsr \param update_time \param render_mirrored */ void Storm3D_Scene::RenderSceneWithParams(bool flip,bool disable_hsr, bool update_time, bool render_mirrored, IStorm3D_Texture *target) { storm3d_dip_calls = 0; // Calculate time difference static DWORD last_time=SDL_GetTicks(); DWORD time_now=SDL_GetTicks(); if (flip) { time_dif=time_now-last_time; // added use of timing factor... if (this->Storm3D2->timeFactor != 1.0f) { // FIXME: may have a small error on some values // should work just fine for factor values like 0.5 though. time_dif = (int)(float(time_dif) * this->Storm3D2->timeFactor); last_time+=(int)(float(time_dif) / this->Storm3D2->timeFactor); } else { last_time+=time_dif; } } else { time_dif=time_now-last_time; if (this->Storm3D2->timeFactor != 1.0f) { // FIXME: may have a small error on some values // should work just fine for factor values like 0.5 though. time_dif = (int)(float(time_dif) * this->Storm3D2->timeFactor); } if(!update_time) time_dif = 0; } // Add time float ftime_dif=((float)time_dif)/1000.0f; time+=ftime_dif; // If paused if(scene_paused == true) { ftime_dif = 0.f; time_dif = 0; time_now = last_time; } this->camera.SetTime(time_now); // Reset active material and mesh Storm3D2->active_material=(Storm3D_Material*)1; // NULL is not right! Storm3D2->active_mesh=NULL; // Basic renderstates glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL); glEnable(GL_DITHER); glDisable(GL_NORMALIZE); //enable camera-relative specular highlights? // Clear renderlists for (int i=0;i<renderlist_size;i++) { renderlist_obj[i]=NULL; renderlist_points[i]=-99999999.0f; } // Put each model in set into the list if(terrains.empty()) for (set<IStorm3D_Model*>::iterator mit=models.begin();mit!=models.end();++mit) { // Typecast (to simplify code) Storm3D_Model *mod=(Storm3D_Model*)*mit; // psd: Is the whole model visible (no animation/object stuff) if(!mod->bones.empty()) { Vector &model_position = mod->position; // Calculate range (outside check part1... fastest) float radius = mod->bounding_radius; float nr = camera.vis_range + radius; if (fabsf(camera.position.x-model_position.x)>nr) continue; if (fabsf(camera.position.y-model_position.y)>nr) continue; if (fabsf(camera.position.z-model_position.z)>nr) continue; // Test sphere visibility if (!camera.TestSphereVisibility(model_position, radius)) continue; } float range = camera.GetPosition().GetRangeTo(mod->GetPosition()); mod->lodLevel = int(range / 20.f); if(mod->lodLevel >= IStorm3D_Mesh::LOD_AMOUNT) mod->lodLevel = IStorm3D_Mesh::LOD_AMOUNT - 1; // Animate bone structure mod->AdvanceAnimation(time_dif); if (flip) { // Apply animation to helpers for(set<IStorm3D_Helper*>::iterator ih=mod->helpers.begin();ih!=mod->helpers.end();++ih) { // Typecast (to simplify code) IStorm3D_Helper *hlp=(IStorm3D_Helper*)*ih; switch(hlp->GetHelperType()) { case IStorm3D_Helper::HTYPE_POINT: ((Storm3D_Helper_Point*)hlp)->animation.Apply(this); break; case IStorm3D_Helper::HTYPE_VECTOR: ((Storm3D_Helper_Vector*)hlp)->animation.Apply(this); break; case IStorm3D_Helper::HTYPE_BOX: ((Storm3D_Helper_Box*)hlp)->animation.Apply(this); break; case IStorm3D_Helper::HTYPE_CAMERA: ((Storm3D_Helper_Camera*)hlp)->animation.Apply(this); break; case IStorm3D_Helper::HTYPE_SPHERE: ((Storm3D_Helper_Sphere*)hlp)->animation.Apply(this); break; } } } // Put each object in set into the list for(set<IStorm3D_Model_Object*>::iterator io=mod->objects.begin();io!=mod->objects.end();++io) { // Typecast (to simplify code) Storm3D_Model_Object *obj=(Storm3D_Model_Object*)*io; // Skip if object does not have a mesh if (obj->mesh==NULL) continue; // If object has no_render skip it if (obj->no_render) continue; // Calculate object world position VC3 owp=obj->GetGlobalPosition(); // Calculate range (outside check part1... fastest) float mrad=obj->mesh->GetRadius(); float nr=camera.vis_range+mrad; if (fabsf(camera.position.x-owp.x)>nr) continue; if (fabsf(camera.position.y-owp.y)>nr) continue; if (fabsf(camera.position.z-owp.z)>nr) continue; // Test sphere visibility if (!camera.TestSphereVisibility(owp,mrad)) continue; // Calculate range to camera (LOD needs) // Check if it's outside camera's range float range=camera.position.GetRangeTo(owp); if ((range-mrad)>camera.vis_range) continue; // Calculate object points float points=range; // Add points if alphablending is used: // alpha-object's are always rendered last bool alpha_on=false; if (obj->mesh->GetMaterial()) { if (obj->mesh->GetMaterial()->GetAlphaType()!=Storm3D_Material::ATYPE_NONE) alpha_on=true; } if (alpha_on) { // Draw alpha's always last points-=999999; } else { // Inverse points if opaque (drawn from front to back) // Speeds up raster performance points=-points; } // Calculate list position (optimize) int lp = 0; for (;renderlist_points[lp]>points;lp++); // OK! // Move end of list 1 position backwards for (int i=renderlist_size-1;i>lp;i--) { renderlist_points[i]=renderlist_points[i-1]; renderlist_obj[i]=renderlist_obj[i-1]; } // Put object into the list renderlist_points[lp]=points; renderlist_obj[lp]=obj; // Test if there is enough room in list (v3) if (renderlist_obj[renderlist_size-1]) { // Allocate double size (v3) int new_renderlist_size=renderlist_size*2; PStorm3D_Model_Object *new_renderlist_obj=new PStorm3D_Model_Object[new_renderlist_size]; float *new_renderlist_points=new float[new_renderlist_size]; // Clear new renderlists for (int i=0;i<new_renderlist_size;i++) { new_renderlist_obj[i]=NULL; new_renderlist_points[i]=-99999999.0f; } // Copy data memcpy(new_renderlist_obj,renderlist_obj,sizeof(PStorm3D_Model_Object)*renderlist_size); memcpy(new_renderlist_points,renderlist_points,sizeof(float)*renderlist_size); // Delete old data delete[] renderlist_obj; delete[] renderlist_points; // Set values renderlist_size=new_renderlist_size; renderlist_obj=new_renderlist_obj; renderlist_points=new_renderlist_points; } } } // Start REAL scene rendering #ifdef NVPERFSDK if (flip) { int nCount = 0; NVPMBeginExperiment(&nCount); if (nCount > 0) { igiosWarning("begin experiment, %d cycles\n", nCount); for (int i = 0; i < nCount; i++ ) { NVPMBeginPass(i); renderRealScene(flip, render_mirrored); NVPMEndPass(i); } NVPMEndExperiment(); UINT64 value = 0, cycles = 0; char *bname = new char[50]; NVPMGetCounterValueByName("GPU Bottleneck", 0, &value, &cycles); NVPMGetGPUBottleneckName(value, bname); bottlenecks[value]++; igiosWarning("GPU Bottleneck value: %lu cycles: %lu\n", value, cycles); igiosWarning("Bottleneck : %s\n", bname); delete[] bname; } else { Storm3D_Texture *tgt = static_cast<Storm3D_Texture*>(target); renderRealScene(flip, render_mirrored, tgt); } } else { Storm3D_Texture *tgt = static_cast<Storm3D_Texture*>(target); renderRealScene(flip, render_mirrored, tgt); } #else Storm3D_Texture *tgt = static_cast<Storm3D_Texture*>(target); renderRealScene(flip, render_mirrored, tgt); #endif }
// redraw the window void display(void) { if(glutGetWindow() == mainwinid) { #ifdef OSG_WITH_NVPERFSDK if(nvDataProvider->nCounters()) { nvDataProvider->sample(); OSG::Char8 str[40]; for(int i = 0; nvStatElems[i] != NULL; ++i) { if(collector != NULL) { sprintf(str, "%s: %f", nvStatElems[i]->getDescription().c_str(), nvDataProvider->value(i)); OSG::StatStringElem *e = dynamic_cast<OSG::StatStringElem*>( collector->getElem(*nvStatElems[i])); e->set(str); } } } if(runExperiment) { int nCount; const char *expCounters[] = { "2D Bottleneck", "2D SOL", "IDX Bottleneck", "IDX SOL", "GEOM Bottleneck", "GEOM SOL", "ZCULL Bottleneck", "ZCULL SOL", "TEX Bottleneck", "TEX SOL", "ROP Bottleneck", "ROP SOL", "SHD Bottleneck", "SHD SOL", "FB Bottleneck", "FB SOL", "GPU Bottleneck", // Needs to be last NULL }; for(int i = 0; expCounters[i] != NULL; ++i) { NVPMAddCounterByName(const_cast<char *>(expCounters[i])); } NVPMBeginExperiment(&nCount); FLOG(("NVPerfKitSDK: Running %d passes\n", nCount)); for(int i = 0; i < nCount; i++) { NVPMBeginPass(i); mgr->redraw(); NVPMEndPass(i); } NVPMEndExperiment(); UINT64 value, cycles; for(int i = 0; expCounters[i] != NULL; ++i) { NVPMGetCounterValueByName(const_cast<char *>(expCounters[i]), 0, &value, &cycles); FLOG(("%s: %lld value, %lld cycles (%.4f%%)\n", expCounters[i], value, cycles, value * 100. / cycles)); } char buffer[1000] = ""; NVPMGetGPUBottleneckName(value, buffer); FLOG(("GPU Bottleneck: '%s'\n", buffer)); for(int i = 0; expCounters[i] != NULL; ++i) { //NVPMRemoveCounterByName(expCounters[i]); } runExperiment = false; } #endif mgr->redraw(); } else if(glutGetWindow() == debugwinid) { // Use RenderAction to prevent new occlusion culling on debug output debugwin->render(debugact); } }