void Model::Draw(Shader& shader, mat4 view, mat4 projection, GLenum mode) { mat4 rotation = mat4_cast(orientation); mat4 trans = translation(position); mat4 model_view = view * trans * rotation * scale(size); mat4 MVP = projection * model_view; mat3 normal_matrix = mat3(inverse(transpose(view * trans * rotation))); glBindVertexArray(vertex_array); shader.Begin(); glUniformMatrix4fv(shader("MVP"), 1, GL_FALSE, &MVP[0][0]); if (shader("model_view")!=-1) glUniformMatrix4fv(shader("model_view"), 1, GL_FALSE, &model_view[0][0]); if (shader("normal_matrix")!=-1) glUniformMatrix3fv(shader("normal_matrix"), 1, GL_FALSE, &normal_matrix[0][0]); if (shader.UniformBlockIndex("Material") !=-1 ) { glBindBuffer(GL_UNIFORM_BUFFER, materialID); glBufferData(GL_UNIFORM_BUFFER, sizeof(Material), &material, GL_STATIC_DRAW); glBindBufferBase(GL_UNIFORM_BUFFER, shader.UniformBlockIndex("Material"), materialID); } glDrawElements(mode, indices.size(), GL_UNSIGNED_INT, 0); shader.End(); glBindVertexArray(0); }
void StencilEffects::RenderConstructionEffect() { if(m_aStencilMeshes.empty()) return; GraphicsDriver::Instance()->SetRenderState(GraphicsDriver::RS_StencilWriting, 0xff); // Fill stencil with 1s GraphicsDriver::Instance()->SetStencilFunc(GraphicsDriver::CF_Never, 1 << 1, 0xff); GraphicsDriver::Instance()->SetStencilOps(GraphicsDriver::SO_Replace, GraphicsDriver::SO_Keep, GraphicsDriver::SO_Keep); GraphicsDriver::Instance()->SetRenderState(GraphicsDriver::RS_ColorWriting, false); // Render stencil meshes m_DefaultMaterial->Begin(); m_DefaultMaterial->GetShader()->Begin(); std::vector<Matrix44> worldTransforms, textureTransforms; worldTransforms.resize(1); textureTransforms.resize(1); for(std::vector< Handle<MeshEntity> >::iterator it = m_aStencilMeshes.begin(); it != m_aStencilMeshes.end(); ) { if(!(*it).IsValid()) { it = m_aStencilMeshes.erase(it); continue; } for(auto submesh : (*it)->GetSubMeshes()) { GraphicComponent* gc = submesh->GetComponent<GraphicComponent>(); gc->GetVertexBuffer()->Begin(m_DefaultMaterial->GetShader()); worldTransforms[0] = submesh->GetWorldTransform(); gc->GetVertexBuffer()->Draw(worldTransforms, std::vector<Matrix44>()); } ++it; } GraphicsDriver::Instance()->SetRenderState(GraphicsDriver::RS_DepthTesting, false); GraphicsDriver::Instance()->SetRenderState(GraphicsDriver::RS_ColorWriting, true); GraphicsDriver::Instance()->SetRenderState(GraphicsDriver::RS_StencilWriting, 0); // no more writing into the stencil buffer GraphicsDriver::Instance()->SetStencilFunc(GraphicsDriver::CF_Equal, 1 << 1, 0xff); // Render only where stencil is 1 // render billboards m_BillBoardEntity->GetComponent<TextureAnimationVisitor>()->Update(); GraphicComponent* pGC = m_BillBoardEntity->GetComponent<GraphicComponent>(); VertexBuffer* pVB = pGC->GetVertexBuffer(); Material* pMat = pGC->GetMaterial(); Shader* pShader = pMat->GetShader(); pMat->Begin(); pShader->GetConstant("uAmbientColor")->Set(&pMat->GetColor(), 1); pShader->Begin(); pVB->Begin(pShader); const Matrix44& billboardMatrix = EntityRenderer::Instance()->Get3DCamera()->GetViewMatrixInverse(); textureTransforms[0] = pGC->GetTextureTransform(); for(auto &stencilMesh : m_aStencilMeshes) { worldTransforms[0] = billboardMatrix; worldTransforms[0].SetTranslation(stencilMesh->GetAbsolutePosition()); pVB->Draw(worldTransforms, textureTransforms); } GraphicsDriver::Instance()->SetRenderState(GraphicsDriver::RS_DepthTesting, true); }
// --------------------------------------------------------------------------------------------------------- LVEDRENDERINGENGINE_API void __stdcall LvEd_RenderGame() { s_engineData->basicRenderer->End(); ErrorHandler::ClearError(); if(s_engineData->pRenderSurface == NULL || s_engineData->GameLevel == NULL) { ErrorHandler::SetError(ErrorType::UnknownError, L"%s: RenderSurface is 0x%x and GameLevel is 0x%x but they both must be non-NULL", __WFUNCTION__, s_engineData->pRenderSurface, s_engineData->GameLevel); return; } RenderState* renderState = RenderContext::Inst()->State(); GlobalRenderFlagsEnum flags = renderState->GetGlobalRenderFlags(); s_engineData->renderableSorter.SetFlags( flags ); s_engineData->GameLevel->GetRenderables(&s_engineData->renderableSorter, RenderContext::Inst()); // sort semi-transparent objects back to front for(unsigned int i = 0; i < s_engineData->renderableSorter.GetBucketCount(); ++i) { RenderableNodeSorter::Bucket& bucket = *s_engineData->renderableSorter.GetBucket(i); if (bucket.renderables.size() > 0 && (bucket.renderFlags & RenderFlags::AlphaBlend)) { // compute dist along camera's view vector. float3 camLook = RenderContext::Inst()->Cam().CamLook(); float3 camPos = RenderContext::Inst()->Cam().CamPos(); for(auto it = bucket.renderables.begin(); it != bucket.renderables.end(); it++) { RenderableNode& r = (*it); float3 viewVec = r.bounds.GetCenter() - camPos; r.Distance = dot(camLook, viewVec); } std::sort(bucket.renderables.begin(),bucket.renderables.end(),NodeSortGreater); } } bool renderShadows = (flags & GlobalRenderFlags::Shadows) != 0; ShadowMaps::Inst()->SetEnabled(renderShadows); // Pre-Pass For Shadow Maps if (renderShadows) { s_engineData->shadowMapShader->Begin( RenderContext::Inst(), s_engineData->pRenderSurface, s_engineData->GameLevel->GetBounds() ); for(unsigned int i = 0; i < s_engineData->renderableSorter.GetBucketCount(); ++i) { RenderableNodeSorter::Bucket& bucket = *s_engineData->renderableSorter.GetBucket(i); if (( bucket.shaderId == Shaders::TexturedShader ) && ( bucket.renderables.size() > 0 )) { s_engineData->shadowMapShader->DrawNodes( bucket.renderables); } } s_engineData->shadowMapShader->End(); } // render opaque objects for(unsigned int i = 0; i < s_engineData->renderableSorter.GetBucketCount(); ++i) { RenderableNodeSorter::Bucket& bucket = *s_engineData->renderableSorter.GetBucket(i); if ( bucket.renderables.size() > 0 && (bucket.renderFlags & RenderFlags::AlphaBlend) == 0) { Shader* pShader = ShaderLib::Inst()->GetShader((ShadersEnum)bucket.shaderId); pShader->Begin( RenderContext::Inst()); pShader->SetRenderFlag( bucket.renderFlags ); // call this *after* Begin() pShader->DrawNodes( bucket.renderables ); pShader->End(); } } auto terrainlist = &(s_engineData->GameLevel->Terrains); if(terrainlist->size() > 0) { TerrainShader* tshader = (TerrainShader*)ShaderLib::Inst()->GetShader(Shaders::TerrainShader); tshader->Begin(RenderContext::Inst()); for(auto it = terrainlist->begin(); it != terrainlist->end(); it++) { tshader->RenderTerrain(*it); } tshader->End(); } // render semi-transparent objects for(unsigned int i = 0; i < s_engineData->renderableSorter.GetBucketCount(); ++i) { RenderableNodeSorter::Bucket& bucket = *s_engineData->renderableSorter.GetBucket(i); if ( bucket.renderables.size() > 0 && (bucket.renderFlags & RenderFlags::AlphaBlend)) { Shader* pShader = ShaderLib::Inst()->GetShader((ShadersEnum)bucket.shaderId); pShader->Begin( RenderContext::Inst()); pShader->SetRenderFlag( bucket.renderFlags ); // call this *after* Begin() pShader->DrawNodes( bucket.renderables ); pShader->End(); } } if ( flags & GlobalRenderFlags::RenderNormals ) { Shader* normShader = ShaderLib::Inst()->GetShader(Shaders::NormalsShader); normShader->Begin( RenderContext::Inst()); for(unsigned int i = 0; i < s_engineData->renderableSorter.GetBucketCount(); ++i) { RenderableNodeSorter::Bucket& bucket = *s_engineData->renderableSorter.GetBucket(i); if ( bucket.renderables.size() > 0 ) { normShader->DrawNodes( bucket.renderables); } } normShader->End(); } //Level editor may perform additional rendering before LvEd_End() is called s_engineData->basicRenderer->Begin(RenderContext::Inst()->Context(), s_engineData->pRenderSurface, RenderContext::Inst()->Cam().View(), RenderContext::Inst()->Cam().Proj()); }