void CompositeRenderable::render(GLenum renderingMode) { for (vector<IRenderable*>::iterator it = components.begin() ; it < components.end() ; it++) { IRenderable* target = *it; target->fullRender(renderingMode); } }
bool LambertShader::OnUpdateShaderParameters(unsigned int pass, IRenderable& renderable, const Camera& camera) { (void)pass; // Texture const TexturePtr texture = renderable.GetTexture(); if (texture) { if (!m_paramTexture->SetValue(*texture)) return false; } // World const Matrix4& worldMat = renderable.GetWorldMatrix(); if (!m_paramWorld->SetValue(worldMat)) return false; // WorldInverseTranspose if (!m_paramWorldInvTrans->SetValue(worldMat.Invert().Transpose())) return false; // WorldViewProjection const Matrix4 wvpMat = worldMat * camera.GetViewMatrix() * camera.GetProjectionMatrix(); if (!m_paramWorldViewProj->SetValue(wvpMat)) return false; return true; }
void IRenderQueue::PrintRenderQueue(const RenderableNodeList& nodes) { HeapString testStr; size_t count = nodes.Count(); FOR_EACH_SIZE(i, count) { IRenderable* node = (IRenderable*)nodes[i]; testStr.AppendFormat("{}:{}:{}\n", node->Id(), node->Material()->Name().c_str(), node->Name().c_str()); }
void BaseBufferRenderBatch::AddNodeToBuffer(uint& refVertexIndex, uint& refIndexIndex, IRenderable& node) { auto mesh = node.Mesh(); const Matrix4& newMatrix = node.WorldMatrix(); mesh->AddToVertexBufferObject(mVertexBufferObject, refVertexIndex, newMatrix); mesh->AddToNormalBufferObject(mNormalBufferObject, refVertexIndex, newMatrix); mesh->AddToTexCoordBufferObject(mTexcoordBufferObject, refVertexIndex); mesh->AddToColorBufferObject(mColorBufferObject, refVertexIndex, node.WorldColor()); mesh->AddToIndexBufferObject(mIndexBufferObject, refVertexIndex, refIndexIndex); uintp vertexCount = mesh->VertexCount(); uintp indexCount = mesh->IndexCount(); node.SetBatch(this, refVertexIndex, (uint)vertexCount, refIndexIndex, (uint)indexCount); refVertexIndex += (uint)vertexCount; refIndexIndex += (uint)indexCount; RenderingStatics::Instance().IncreaseChangedNodeCount(); }
void BaseSingleBatchRenderQueue::Update(RenderableChangedFlags changedFlag) { RETURN_IF_EQUAL(changedFlag, RenderableChangedFlags::None); if (changedFlag.IsBatchChanged()||changedFlag.IsRenderQueueChanged()) { mBatch->Prepare(); if (!mNodes.IsEmpty()) { IRenderable* node = mNodes.First(); mBatch->SetEffect(node->Material()->Effect()); mBatch->SetMaterial(node->Material()); mBatch->SetDrawMode(node->Material()->DrawMode()); mBatch->SetStateTreeNode(node->RenderStateTreeNode()); } FOR_EACH_COLLECTION(i, mNodes) { mBatch->AddNode(*i); }
void Graphics::Render(IRenderable &renderable) { Shader.setModel(renderable.getTransformation()); CheckGlErrors(); GLuint texture = renderable.getTexture(); CheckGlErrors(); if(LastTexture != texture) { glActiveTexture(GL_TEXTURE0); CheckGlErrors(); glBindTexture(GL_TEXTURE_2D, texture); CheckGlErrors(); Shader.setTexture(0); CheckGlErrors(); LastTexture = texture; } glDrawArrays(GL_TRIANGLES, 0, 6); CheckGlErrors(); }
void BaseBufferRenderBatch::UpdateNodeToBuffer(uint& refVertexIndex, uint& refIndexIndex, IRenderable& node, RenderableChangedFlags changedFlags) { auto mesh = node.Mesh(); if (MEDUSA_FLAG_HAS(changedFlags,RenderableChangedFlags::NewVertex)) { const Matrix4& newMatrix = node.WorldMatrix(); mesh->AddToVertexBufferObject(mVertexBufferObject, refVertexIndex, newMatrix); } if (MEDUSA_FLAG_HAS(changedFlags, RenderableChangedFlags::NewNormal)) { const Matrix4& newMatrix = node.WorldMatrix(); mesh->AddToNormalBufferObject(mNormalBufferObject, refVertexIndex, newMatrix); } if (MEDUSA_FLAG_HAS(changedFlags, RenderableChangedFlags::NewTexCoord)) { mesh->AddToTexCoordBufferObject(mTexcoordBufferObject, refVertexIndex); } if (MEDUSA_FLAG_HAS(changedFlags, RenderableChangedFlags::NewColor)) { mesh->AddToColorBufferObject(mColorBufferObject, refVertexIndex, node.WorldColor()); } if (MEDUSA_FLAG_HAS(changedFlags, RenderableChangedFlags::NewIndex)) { mesh->AddToIndexBufferObject(mIndexBufferObject, refVertexIndex, refIndexIndex); } uintp vertexCount = mesh->VertexCount(); uintp indexCount = mesh->IndexCount(); node.SetBatch(this, refVertexIndex, (uint)vertexCount, refIndexIndex, (uint)indexCount); refVertexIndex += (uint)vertexCount; refIndexIndex += (uint)indexCount; RenderingStatics::Instance().IncreaseChangedNodeCount(); }
void renderObject(IRenderable& object, glm::mat4 mvp, uint32_t matrix) { auto mesh = dynamic_cast<MeshComponent*>(&object.ComponentsForTag(MeshComponent::TAG)[0]); auto transform = dynamic_cast<TransformComponent*>(&object.ComponentsForTag(TransformComponent::TAG)[0]); auto vbuffer = dynamic_cast<GLVertexBuffer*>(mesh->vertexBuffer.get()); glEnableVertexAttribArray(0); glBindBuffer(GL_ARRAY_BUFFER, vbuffer->vbo); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0); glEnableVertexAttribArray(1); glBindBuffer(GL_ARRAY_BUFFER, vbuffer->cbo); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, (void*)0); glUniformMatrix4fv(matrix, 1, GL_FALSE, &mvp[0][0]); glDrawArrays(GL_TRIANGLES, 0, 12 * 3); glDisableVertexAttribArray(0); glDisableVertexAttribArray(1); for (IRenderable child : object.children.begin) { renderObject(child, mvp, matrix); } }
void AnimatedObject::Render(void){ IRenderable *currMesh = dynamic_cast<IRenderable *>(GetMember(frameNames[currentFrame])); if (currMesh != 0) currMesh->Render(); }
void Font::createSentenceRenderable(IRenderable &renderable, std::string sentence) { assert(mMaterialName != ""); int aux = sentence.length(); int size = 0; for (int count = 0; count < aux; count++) { // if char exists in the font definition if (mChars.count(sentence[count])) size++; } assert(size); // need to clear previous mesh //Mesh *renderable = (Mesh *)RESOURCEMANAGER->createRenderable("Mesh", sentence, "Sentence"); //renderable->setDrawingPrimitive(curitiba::render::IRenderer::TRIANGLES); std::vector<VertexData::Attr> *vertices = new std::vector<VertexData::Attr>(size*6); std::vector<VertexData::Attr> *texCoords = new std::vector<VertexData::Attr>(size*6); std::vector<VertexData::Attr> *normals = new std::vector<VertexData::Attr>(size*6); int i = 0; float hDisp = 0.0f, vDisp = 0.0f; for (int count = 0; count < aux; count++) { // get char at position count char c = sentence[count]; if (c == ' ') { if (mFixedSize) hDisp += mChars[c].C + mChars[c].A; else hDisp += mChars[c].C; } // if char exists in the font definition else if (mChars.count(c)) { vertices->at(6*i ).set(hDisp, vDisp + mHeight, 0.0f, 1.0f); vertices->at(6*i+1).set(hDisp + mChars[c].width, vDisp, 0.0f, 1.0f); vertices->at(6*i+2).set(hDisp, vDisp, 0.0f, 1.0f); vertices->at(6*i+3).set(hDisp + mChars[c].width, vDisp, 0.0f, 1.0f); vertices->at(6*i+4).set(hDisp, vDisp + mHeight,0.0f, 1.0f); vertices->at(6*i+5).set(hDisp + mChars[c].width, vDisp + mHeight, 0.0f, 1.0f); normals->at(6*i ).set(0,0,1); normals->at(6*i+1 ).set(0,0,1); normals->at(6*i+2 ).set(0,0,1); normals->at(6*i+3 ).set(0,0,1); normals->at(6*i+4 ).set(0,0,1); normals->at(6*i+5 ).set(0,0,1); texCoords->at(6*i ).set(mChars[c].x1, 1-mChars[c].y2, 0.0f, 1.0f); texCoords->at(6*i+1).set(mChars[c].x2, 1-mChars[c].y1, 0.0f, 1.0f); texCoords->at(6*i+2).set(mChars[c].x1, 1-mChars[c].y1, 0.0f, 1.0f); texCoords->at(6*i+3).set(mChars[c].x2, 1-mChars[c].y1, 0.0f, 1.0f); texCoords->at(6*i+4).set(mChars[c].x1, 1-mChars[c].y2, 0.0f, 1.0f); texCoords->at(6*i+5).set(mChars[c].x2, 1-mChars[c].y2, 0.0f, 1.0f); if (mFixedSize) hDisp += mChars[c].C + mChars[c].A; else hDisp += mChars[c].C; i++; } // newline else if (c == '\n') { vDisp += mHeight; hDisp = 0.0f; } } VertexData &vertexData = renderable.getVertexData(); vertexData.setDataFor (VertexData::getAttribIndex("position"), vertices); vertexData.setDataFor (VertexData::getAttribIndex("normal"), normals); vertexData.setDataFor (VertexData::getAttribIndex("texCoord0"), texCoords); std::vector<unsigned int> *indices = new std::vector<unsigned int>(size*6); for (int j = 0; j < size*6 ; j++) indices->push_back(j); MaterialGroup* auxMG; std::vector<IMaterialGroup *> aMatG = renderable.getMaterialGroups(); if (aMatG.size()) { auxMG = (MaterialGroup *)aMatG[0]; auxMG->setIndexList (indices); } else { auxMG = new MaterialGroup(); auxMG->setMaterialName(mMaterialName); auxMG->setParent(&renderable); auxMG->setIndexList (indices); renderable.addMaterialGroup(auxMG); } }
void CRender::Calculate () { #ifdef _GPA_ENABLED TAL_SCOPED_TASK_NAMED( "CRender::Calculate()" ); #endif // _GPA_ENABLED Device.Statistic->RenderCALC.Begin(); // Transfer to global space to avoid deep pointer access IRender_Target* T = getTarget (); float fov_factor = _sqr (90.f / Device.fFOV); g_fSCREEN = float(T->get_width()*T->get_height())*fov_factor*(EPS_S+ps_r__LOD); r_ssaDISCARD = _sqr(ps_r__ssaDISCARD) /g_fSCREEN; r_ssaDONTSORT = _sqr(ps_r__ssaDONTSORT/3) /g_fSCREEN; r_ssaLOD_A = _sqr(ps_r1_ssaLOD_A/3) /g_fSCREEN; r_ssaLOD_B = _sqr(ps_r1_ssaLOD_B/3) /g_fSCREEN; r_ssaGLOD_start = _sqr(ps_r__GLOD_ssa_start/3)/g_fSCREEN; r_ssaGLOD_end = _sqr(ps_r__GLOD_ssa_end/3) /g_fSCREEN; r_ssaHZBvsTEX = _sqr(ps_r__ssaHZBvsTEX/3) /g_fSCREEN; // Frustum & HOM rendering ViewBase.CreateFromMatrix (Device.mFullTransform,FRUSTUM_P_LRTB|FRUSTUM_P_FAR); View = 0; HOM.Enable (); HOM.Render (ViewBase); gm_SetNearer (FALSE); phase = PHASE_NORMAL; // Detect camera-sector if (!vLastCameraPos.similar(Device.vCameraPosition,EPS_S)) { CSector* pSector = (CSector*)detectSector(Device.vCameraPosition); if (pSector && (pSector!=pLastSector)) g_pGamePersistent->OnSectorChanged( translateSector(pSector) ); if (0==pSector) pSector = pLastSector; pLastSector = pSector; vLastCameraPos.set(Device.vCameraPosition); } // Check if camera is too near to some portal - if so force DualRender if (rmPortals) { Fvector box_radius; box_radius.set(EPS_L*2,EPS_L*2,EPS_L*2); Sectors_xrc.box_options (CDB::OPT_FULL_TEST); Sectors_xrc.box_query (rmPortals,Device.vCameraPosition,box_radius); for (int K=0; K<Sectors_xrc.r_count(); K++) { CPortal* pPortal = (CPortal*) Portals[rmPortals->get_tris()[Sectors_xrc.r_begin()[K].id].dummy]; pPortal->bDualRender = TRUE; } } // if (L_DB) L_DB->Update(); // Main process marker ++; if (pLastSector) { // Traverse sector/portal structure PortalTraverser.traverse ( pLastSector, ViewBase, Device.vCameraPosition, Device.mFullTransform, CPortalTraverser::VQ_HOM + CPortalTraverser::VQ_SSA + CPortalTraverser::VQ_FADE ); // Determine visibility for static geometry hierrarhy if (psDeviceFlags.test(rsDrawStatic)) { for (u32 s_it=0; s_it<PortalTraverser.r_sectors.size(); s_it++) { CSector* sector = (CSector*)PortalTraverser.r_sectors[s_it]; dxRender_Visual* root = sector->root(); for (u32 v_it=0; v_it<sector->r_frustums.size(); v_it++) { set_Frustum (&(sector->r_frustums[v_it])); add_Geometry (root); } } } // Traverse object database if (psDeviceFlags.test(rsDrawDynamic)) { g_SpatialSpace->q_frustum ( lstRenderables, ISpatial_DB::O_ORDERED, STYPE_RENDERABLE + STYPE_LIGHTSOURCE, ViewBase ); // Exact sorting order (front-to-back) std::sort (lstRenderables.begin(),lstRenderables.end(),pred_sp_sort); // Determine visibility for dynamic part of scene set_Object (0); g_hud->Render_First ( ); // R1 shadows g_hud->Render_Last ( ); u32 uID_LTRACK = 0xffffffff; if (phase==PHASE_NORMAL) { uLastLTRACK ++; if (lstRenderables.size()) uID_LTRACK = uLastLTRACK%lstRenderables.size(); // update light-vis for current entity / actor CObject* O = g_pGameLevel->CurrentViewEntity(); if (O) { CROS_impl* R = (CROS_impl*) O->ROS(); if (R) R->update (O); } } for (u32 o_it=0; o_it<lstRenderables.size(); o_it++) { ISpatial* spatial = lstRenderables[o_it]; spatial->spatial_updatesector (); CSector* sector = (CSector*)spatial->spatial.sector ; if (0==sector) continue; // disassociated from S/P structure // Filter only not light spatial if (PortalTraverser.i_marker != sector->r_marker && (spatial->spatial.type & STYPE_RENDERABLE) ) continue; // inactive (untouched) sector if (spatial->spatial.type & STYPE_RENDERABLE) { for (u32 v_it=0; v_it<sector->r_frustums.size(); v_it++) { set_Frustum (&(sector->r_frustums[v_it])); if (!View->testSphere_dirty(spatial->spatial.sphere.P,spatial->spatial.sphere.R) /*&& (spatial->spatial.type & STYPE_RENDERABLE)*/) continue; // renderable IRenderable* renderable = spatial->dcast_Renderable (); if (0==renderable) { // It may be an glow CGlow* glow = dynamic_cast<CGlow*>(spatial); VERIFY (glow); L_Glows->add (glow); } else { // Occlusiond vis_data& v_orig = renderable->renderable.visual->getVisData(); vis_data v_copy = v_orig; v_copy.box.xform (renderable->renderable.xform); BOOL bVisible = HOM.visible(v_copy); v_orig.accept_frame = v_copy.accept_frame; v_orig.marker = v_copy.marker; v_orig.hom_frame = v_copy.hom_frame; v_orig.hom_tested = v_copy.hom_tested; if (!bVisible) break; // exit loop on frustums // rendering if (o_it==uID_LTRACK && renderable->renderable_ROS()) { // track lighting environment CROS_impl* T = (CROS_impl*)renderable->renderable_ROS(); T->update (renderable); } set_Object (renderable); renderable->renderable_Render (); set_Object (0); //? is it needed at all } break; // exit loop on frustums } } else { if ( ViewBase.testSphere_dirty(spatial->spatial.sphere.P,spatial->spatial.sphere.R) ) { VERIFY (spatial->spatial.type & STYPE_LIGHTSOURCE); // lightsource light* L = (light*) spatial->dcast_Light (); VERIFY (L); if (L->spatial.sector) { vis_data& vis = L->get_homdata ( ); if (HOM.visible(vis)) L_DB->add_light (L); } } } } } // Calculate miscelaneous stuff L_Shadows->calculate (); L_Projector->calculate (); } else { set_Object (0); /* g_pGameLevel->pHUD->Render_First (); g_pGameLevel->pHUD->Render_Last (); // Calculate miscelaneous stuff L_Shadows->calculate (); L_Projector->calculate (); */ } // End calc Device.Statistic->RenderCALC.End (); }
bool IRenderBatch::IsAvailableFor(const IRenderable& node) const { IMesh* mesh = node.Mesh(); return IsAvailableFor(mesh->VertexCount(), mesh->IndexCount()); }
/** * renderlmpl for edge hight light and blur * @ param IRenderSystem for set render state or texture.., SceneManger for ger render queue and so on * @ return null * @ flow: render target-> render state->setupStream-> setTexture-> setTechnique->begin pass->end pass * @ author Milong.Wu */ void EdgeblurPostEffect::renderImpl( IRenderSystem* pRenderSys, SceneManager* scene ) { if(!postEffect) return; SceneManager * scenemgr = SUBSYSTEMX(SceneManager,ISceneManager); SceneRender * scenerender = scenemgr->getSceneRender(); StagedForwardSceneRender *Stagescenerender=(StagedForwardSceneRender*)scenerender ; const RenderQueue::RenderableList& highItems =(*Stagescenerender).specialRenderQueue.getRenderableList((RenderQueueOrder)StagedForwardSceneRender::RENDER_QUEUE_HIGHLIGHT); if (highItems.size() <= 0) return ; uint blurRTT1 = scene->currentView->getFullRGBRTT1(); uint blurRTT2 = scene->currentView->getFullRGBRTT2(); float viewSizeFactor = 0.5f; if(blurRTT1 == 0 || blurRTT2 == 0) return; int numRendered = 0; uint oldTarget = pRenderSys->getCurrentRenderTarget(); pRenderSys->setCurrentRenderTarget(blurRTT1); // so the unsee part can't be hightlihght pRenderSys->setDepthBufferCheckEnabled(true); pRenderSys->setDepthBufferFunction(CMP_LESSEQUAL); pRenderSys->setDepthBufferWriteEnabled(false); pRenderSys->setCullingMode(CULL_NONE); //setup common rendering state pRenderSys->clearFrameBuffer(ColorValue(0,0,0,0), 1.0f); setupRenderingState(pRenderSys); //get highlight queue int colorID = 0; int idCount = 0; FillMode oldFillMode = pRenderSys->getFillMode(); bool highlight = false; for(size_t qi = 0; qi <highItems.size() && colorID <Stagescenerender->highLights.num(); ++qi) { highlight = true; IRenderable *renderable = highItems[qi]; const Appearance& appear = renderable->getAppearance(); Appearance::Geometry geo = appear.geometry; geo.indexBuffer = appear.geometry.indexBuffer; if(appear.material[eMaterial_0].renderOrder < RENDER_QUEUE_BLEND && geo.indexBuffer) { appear.geometry.setupStream(pRenderSys); //edgeColor and rimback_biggerFactor are uniform values defined in this pass of edgeblur.fx (../date/shader) file postEffect->setupAutoParameters(renderable); postEffect->setVector4("edgeColor", (Vector4*)(&Stagescenerender->highLights(colorID).color)); ColorValue *ed = (ColorValue*)(&Stagescenerender->highLights(colorID).color); setupRenderingState(pRenderSys); if(appear.material[eMaterial_0].numTextureUnit) appear.material[eMaterial_0].setTextureUnit(pRenderSys,0); else pRenderSys->setTexture(0, 0); //postEffect->setupAutoParameters(renderable); uint iPass; //"Rimback" is defined in edgeblur.fx (../date/shader) file int macAcount=0; const EffectMacro *mac = postEffect->getMacros(macAcount); // for the weapon can not be paint, as no maco, so use a special technique if(geo.isSkinning()) { postEffect->setTechnique("Rimback"); } else{ postEffect->setTechnique("RimbackNomaco"); } postEffect->begin(&iPass); postEffect->beginPass(0); pRenderSys->drawRangeIndexedPrimitive(PT_TRIANGLES, geo.indexBuffer->getType(),geo.indexStart,geo.indexCount,geo.vertexStart,geo.vertexEnd); postEffect->endPass(); postEffect->end(); appear.geometry.resetStream(pRenderSys); } idCount++; if(idCount >= Stagescenerender->highLights(colorID).numRenderable) { colorID++; idCount = 0; } } if(highlight) { pRenderSys->setCurrentRenderTarget(blurRTT2); pRenderSys->clearFrameBuffer(ColorValue(0,0,0,0), 1.0f); // use texture in prerender pRenderSys->setTexture(0, (ITexture*)pRenderSys->getRenderTargetTexture(blurRTT1)); //"Edgeblur" is defined in edgeblur.fx (../date/shader) file postEffect->setTechnique("pengzhang"); // set uniform value int l,t, w, h; pRenderSys->getViewport(l, t, w, h); Vector4 viewport_inv_sizeex(1.0f /w, 1.0f /h, 0, 0); postEffect->setVector4("viewport_inv_size", &viewport_inv_sizeex); renderQuad(pRenderSys, postEffect); // for inflation may add a border line around, so reset the color pRenderSys->setTextureBorderColor(0,ColorValue(0,0,0,0)); //set new target pRenderSys->setCurrentRenderTarget(blurRTT1); //be similar to outline color, for scene blend pRenderSys->clearFrameBuffer(ColorValue(0,0,0,0), 1.0f); // use texture in prerender pRenderSys->setTexture(0, (ITexture*)pRenderSys->getRenderTargetTexture(blurRTT2)); //"Edgeblur" is defined in edgeblur.fx (../date/shader) file postEffect->setTechnique("Edgeblur"); pRenderSys->getViewport(l, t, w, h); Vector4 viewport_inv_size(1.0f / w, 1.0f / h, 0, 0); postEffect->setVector4("viewport_inv_size", &viewport_inv_size); renderQuad(pRenderSys, postEffect); } // final pass pRenderSys->setCurrentRenderTarget(oldTarget); pRenderSys->setTexture(0, (ITexture*)pRenderSys->getRenderTargetTexture(blurRTT1)); postEffect->setTechnique("FinalBlend"); //pRenderSys->setSceneBlending(quadSrcFactor, quadDestFactor); renderQuad(pRenderSys, postEffect); //reset //pRenderSys->setDepthBufferFunction(CMP_GREATEREQUAL); }
void RenderManager::RenderObject(IRenderable& renderable) { renderable.Render(al_get_backbuffer(_display_context)); }
// sub-space rendering - main procedure void R_dsgraph_structure::r_dsgraph_render_subspace (IRender_Sector* _sector, CFrustum* _frustum, Fmatrix& mCombined, Fvector& _cop, BOOL _dynamic, BOOL _precise_portals) { VERIFY (_sector); RImplementation.marker ++; // !!! critical here // Save and build new frustum, disable HOM CFrustum ViewSave = ViewBase; ViewBase = *_frustum; View = &ViewBase; if (_precise_portals && RImplementation.rmPortals) { // Check if camera is too near to some portal - if so force DualRender Fvector box_radius; box_radius.set (EPS_L*20,EPS_L*20,EPS_L*20); RImplementation.Sectors_xrc.box_options (CDB::OPT_FULL_TEST); RImplementation.Sectors_xrc.box_query (RImplementation.rmPortals,_cop,box_radius); for (int K=0; K<RImplementation.Sectors_xrc.r_count(); K++) { CPortal* pPortal = (CPortal*) RImplementation.Portals[RImplementation.rmPortals->get_tris()[RImplementation.Sectors_xrc.r_begin()[K].id].dummy]; pPortal->bDualRender = TRUE; } } // Traverse sector/portal structure PortalTraverser.traverse ( _sector, ViewBase, _cop, mCombined, 0 ); // Determine visibility for static geometry hierrarhy for (u32 s_it=0; s_it<PortalTraverser.r_sectors.size(); s_it++) { CSector* sector = (CSector*)PortalTraverser.r_sectors[s_it]; IRender_Visual* root = sector->root(); for (u32 v_it=0; v_it<sector->r_frustums.size(); v_it++) { set_Frustum (&(sector->r_frustums[v_it])); add_Geometry (root); } } if (_dynamic) { set_Object (0); // Traverse object database g_SpatialSpace->q_frustum ( lstRenderables, ISpatial_DB::O_ORDERED, STYPE_RENDERABLE, ViewBase ); // Determine visibility for dynamic part of scene for (u32 o_it=0; o_it<lstRenderables.size(); o_it++) { ISpatial* spatial = lstRenderables[o_it]; CSector* sector = (CSector*)spatial->spatial.sector; if (0==sector) continue; // disassociated from S/P structure if (PortalTraverser.i_marker != sector->r_marker) continue; // inactive (untouched) sector for (u32 v_it=0; v_it<sector->r_frustums.size(); v_it++) { set_Frustum (&(sector->r_frustums[v_it])); if (!View->testSphere_dirty(spatial->spatial.sphere.P,spatial->spatial.sphere.R)) continue; // renderable IRenderable* renderable = spatial->dcast_Renderable (); if (0==renderable) continue; // unknown, but renderable object (r1_glow???) renderable->renderable_Render (); } } } // Restore ViewBase = ViewSave; View = 0; }
void CLightProjector::calculate () { #ifdef _GPA_ENABLED TAL_SCOPED_TASK_NAMED( "CLightProjector::calculate()" ); #endif // _GPA_ENABLED if (receivers.empty()) return; // perform validate / markup for (u32 r_it=0; r_it<receivers.size(); r_it++) { // validate BOOL bValid = TRUE; IRenderable* O = receivers[r_it]; CROS_impl* LT = (CROS_impl*)O->renderable_ROS(); int slot = LT->shadow_recv_slot; if (slot<0 || slot>=P_o_count) bValid = FALSE; // invalid slot else if (cache[slot].O!=O) bValid = FALSE; // not the same object else { // seems to be valid Fbox bb; bb.xform (O->renderable.visual->getVisData().box,O->renderable.xform); if (cache[slot].BB.contains(bb)) { // inside, but maybe timelimit exceeded? if (Device.dwTimeGlobal > cache[slot].dwTimeValid) bValid = FALSE; // timeout } else bValid = FALSE; // out of bounds } // if (bValid) { // Ok, use cached version cache[slot].dwFrame = Device.dwFrame; } else { taskid.push_back (r_it); } } if (taskid.empty()) return; // Begin Device.Statistic->RenderDUMP_Pcalc.Begin (); RCache.set_RT (RT->pRT); RCache.set_ZB (RImplementation.Target->pTempZB); CHK_DX(HW.pDevice->Clear (0,0, D3DCLEAR_ZBUFFER | (HW.Caps.bStencil?D3DCLEAR_STENCIL:0), 0,1,0 )); RCache.set_xform_world (Fidentity); // reallocate/reassociate structures + perform all the work for (u32 c_it=0; c_it<cache.size(); c_it++) { if (taskid.empty()) break; if (Device.dwFrame==cache[c_it].dwFrame) continue; // found not used slot int tid = taskid.back(); taskid.pop_back(); recv& R = cache [c_it]; IRenderable* O = receivers [tid]; const vis_data& vis = O->renderable.visual->getVisData(); CROS_impl* LT = (CROS_impl*)O->renderable_ROS(); VERIFY2 (_valid(O->renderable.xform),"Invalid object transformation"); VERIFY2 (_valid(vis.sphere.P),"Invalid object's visual sphere"); Fvector C; O->renderable.xform.transform_tiny (C,vis.sphere.P); R.O = O; R.C = C; R.C.y += vis.sphere.R*0.1f; //. YURA: 0.1 can be more R.BB.xform (vis.box,O->renderable.xform).scale(0.1f); R.dwTimeValid = Device.dwTimeGlobal + ::Random.randI(time_min,time_max); LT->shadow_recv_slot = c_it; // Msg ("[%f,%f,%f]-%f",C.C.x,C.C.y,C.C.z,C.O->renderable.visual->vis.sphere.R); // calculate projection-matrix Fmatrix mProject; float p_R = R.O->renderable.visual->getVisData().sphere.R * 1.1f; //VERIFY2 (p_R>EPS_L,"Object has no physical size"); VERIFY3 (p_R>EPS_L,"Object has no physical size", R.O->renderable.visual->getDebugName().c_str()); float p_hat = p_R/P_cam_dist; float p_asp = 1.f; float p_near = P_cam_dist-EPS_L; float p_far = P_cam_dist+p_R+P_cam_range; mProject.build_projection_HAT (p_hat,p_asp,p_near,p_far); RCache.set_xform_project (mProject); // calculate view-matrix Fmatrix mView; Fvector v_C, v_Cs, v_N; v_C.set (R.C); v_Cs = v_C; v_C.y += P_cam_dist; v_N.set (0,0,1); VERIFY (_valid(v_C) && _valid(v_Cs) && _valid(v_N)); // validate Fvector v; v.sub (v_Cs,v_C);; #ifdef DEBUG if ((v.x*v.x+v.y*v.y+v.z*v.z)<=flt_zero) { CObject* OO = dynamic_cast<CObject*>(R.O); Msg("Object[%s] Visual[%s] has invalid position. ",*OO->cName(),*OO->cNameVisual()); Fvector cc; OO->Center(cc); Log("center=",cc); Log("visual_center=",OO->Visual()->getVisData().sphere.P); Log("full_matrix=",OO->XFORM()); Log ("v_N",v_N); Log ("v_C",v_C); Log ("v_Cs",v_Cs); Log("all bones transform:--------"); CKinematics* K = dynamic_cast<CKinematics*>(OO->Visual()); for(u16 ii=0; ii<K->LL_BoneCount();++ii){ Fmatrix tr; tr = K->LL_GetTransform(ii); Log("bone ",K->LL_BoneName_dbg(ii)); Log("bone_matrix",tr); } Log("end-------"); } #endif // handle invalid object-bug if ((v.x*v.x+v.y*v.y+v.z*v.z)<=flt_zero) { // invalidate record, so that object will be unshadowed, but doesn't crash R.dwTimeValid = Device.dwTimeGlobal; LT->shadow_recv_frame = Device.dwFrame-1; LT->shadow_recv_slot = -1; continue ; } mView.build_camera (v_C,v_Cs,v_N); RCache.set_xform_view (mView); // Select slot, set viewport int s_x = c_it%P_o_line; int s_y = c_it/P_o_line; D3DVIEWPORT9 VP = {s_x*P_o_size,s_y*P_o_size,P_o_size,P_o_size,0,1 }; CHK_DX (HW.pDevice->SetViewport(&VP)); // Clear color to ambience Fvector& cap = LT->get_approximate(); CHK_DX (HW.pDevice->Clear(0,0, D3DCLEAR_TARGET, color_rgba_f(cap.x,cap.y,cap.z, (cap.x+cap.y+cap.z)/4.f), 1, 0 )); // calculate uv-gen matrix and clamper Fmatrix mCombine; mCombine.mul (mProject,mView); Fmatrix mTemp; float fSlotSize = float(P_o_size)/float(P_rt_size); float fSlotX = float(s_x*P_o_size)/float(P_rt_size); float fSlotY = float(s_y*P_o_size)/float(P_rt_size); float fTexelOffs = (.5f / P_rt_size); Fmatrix m_TexelAdjust = { 0.5f/*x-scale*/, 0.0f, 0.0f, 0.0f, 0.0f, -0.5f/*y-scale*/, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f/*z-range*/, 0.0f, 0.5f/*x-bias*/, 0.5f + fTexelOffs/*y-bias*/, 0.0f/*z-bias*/, 1.0f }; R.UVgen.mul (m_TexelAdjust,mCombine); mTemp.scale (fSlotSize,fSlotSize,1); R.UVgen.mulA_44 (mTemp); mTemp.translate (fSlotX+fTexelOffs,fSlotY+fTexelOffs,0); R.UVgen.mulA_44 (mTemp); // Build bbox and render Fvector min,max; Fbox BB; min.set (R.C.x-p_R, R.C.y-(p_R+P_cam_range), R.C.z-p_R); max.set (R.C.x+p_R, R.C.y+0, R.C.z+p_R); BB.set (min,max); R.UVclamp_min.set (min).add (.05f); // shrink a little R.UVclamp_max.set (max).sub (.05f); // shrink a little ISpatial* spatial = dynamic_cast<ISpatial*> (O); if (spatial) { spatial->spatial_updatesector (); if (spatial->spatial.sector) RImplementation.r_dsgraph_render_R1_box (spatial->spatial.sector,BB,SE_R1_LMODELS); } //if (spatial) RImplementation.r_dsgraph_render_subspace (spatial->spatial.sector,mCombine,v_C,FALSE); } // Blur /* { // Fill vertex buffer u32 Offset; FVF::TL4uv* pv = (FVF::TL4uv*) RCache.Vertex.Lock (4,geom_Blur.stride(),Offset); RImplementation.ApplyBlur4 (pv,P_rt_size,P_rt_size,P_blur_kernel); RCache.Vertex.Unlock (4,geom_Blur.stride()); // Actual rendering (pass0, temp2real) RCache.set_RT (RT->pRT); RCache.set_ZB (NULL); RCache.set_Shader (sh_BlurTR ); RCache.set_Geometry (geom_Blur ); RCache.Render (D3DPT_TRIANGLELIST,Offset,0,4,0,2); } */ // Finita la comedia Device.Statistic->RenderDUMP_Pcalc.End (); RCache.set_xform_project (Device.mProject); RCache.set_xform_view (Device.mView); }
void CRender::render_main (Fmatrix& m_ViewProjection, bool _fportals) { // Msg ("---begin"); marker ++; // Calculate sector(s) and their objects if (pLastSector) { //!!! //!!! BECAUSE OF PARALLEL HOM RENDERING TRY TO DELAY ACCESS TO HOM AS MUCH AS POSSIBLE //!!! { // Traverse object database g_SpatialSpace->q_frustum ( lstRenderables, ISpatial_DB::O_ORDERED, STYPE_RENDERABLE + STYPE_LIGHTSOURCE, ViewBase ); // (almost) Exact sorting order (front-to-back) std::sort (lstRenderables.begin(),lstRenderables.end(),pred_sp_sort); // Determine visibility for dynamic part of scene set_Object (0); u32 uID_LTRACK = 0xffffffff; if (phase==PHASE_NORMAL) { uLastLTRACK ++; if (lstRenderables.size()) uID_LTRACK = uLastLTRACK%lstRenderables.size(); // update light-vis for current entity / actor CObject* O = g_pGameLevel->CurrentViewEntity(); if (O) { CROS_impl* R = (CROS_impl*) O->ROS(); if (R) R->update (O); } // update light-vis for selected entity // track lighting environment if (lstRenderables.size()) { IRenderable* renderable = lstRenderables[uID_LTRACK]->dcast_Renderable (); if (renderable) { CROS_impl* T = (CROS_impl*)renderable->renderable_ROS (); if (T) T->update (renderable); } } } } // Traverse sector/portal structure PortalTraverser.traverse ( pLastSector, ViewBase, Device.vCameraPosition, m_ViewProjection, CPortalTraverser::VQ_HOM + CPortalTraverser::VQ_SSA + CPortalTraverser::VQ_FADE //. disabled scissoring (HW.Caps.bScissor?CPortalTraverser::VQ_SCISSOR:0) // generate scissoring info ); // Determine visibility for static geometry hierrarhy for (u32 s_it=0; s_it<PortalTraverser.r_sectors.size(); s_it++) { CSector* sector = (CSector*)PortalTraverser.r_sectors[s_it]; IRender_Visual* root = sector->root(); for (u32 v_it=0; v_it<sector->r_frustums.size(); v_it++) { set_Frustum (&(sector->r_frustums[v_it])); add_Geometry (root); } } // Traverse frustums for (u32 o_it=0; o_it<lstRenderables.size(); o_it++) { ISpatial* spatial = lstRenderables[o_it]; spatial->spatial_updatesector (); CSector* sector = (CSector*)spatial->spatial.sector; if (0==sector) continue; // disassociated from S/P structure if (spatial->spatial.type & STYPE_LIGHTSOURCE) { // lightsource light* L = (light*) (spatial->dcast_Light()); VERIFY (L); float lod = L->get_LOD (); if (lod>EPS_L) { vis_data& vis = L->get_homdata ( ); if (HOM.visible(vis)) Lights.add_light (L); } continue ; } if (PortalTraverser.i_marker != sector->r_marker) continue; // inactive (untouched) sector for (u32 v_it=0; v_it<sector->r_frustums.size(); v_it++) { CFrustum& view = sector->r_frustums[v_it]; if (!view.testSphere_dirty(spatial->spatial.sphere.P,spatial->spatial.sphere.R)) continue; if (spatial->spatial.type & STYPE_RENDERABLE) { // renderable IRenderable* renderable = spatial->dcast_Renderable (); VERIFY (renderable); // Occlusion vis_data& v_orig = renderable->renderable.visual->vis; vis_data v_copy = v_orig; v_copy.box.xform (renderable->renderable.xform); BOOL bVisible = HOM.visible(v_copy); v_orig.marker = v_copy.marker; v_orig.accept_frame = v_copy.accept_frame; v_orig.hom_frame = v_copy.hom_frame; v_orig.hom_tested = v_copy.hom_tested; if (!bVisible) break; // exit loop on frustums // Rendering set_Object (renderable); renderable->renderable_Render (); set_Object (0); } break; // exit loop on frustums } } if (g_pGameLevel && (phase==PHASE_NORMAL)) g_pGameLevel->pHUD->Render_Last(); // HUD } else { set_Object (0); if (g_pGameLevel && (phase==PHASE_NORMAL)) g_pGameLevel->pHUD->Render_Last(); // HUD } }