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); }
// --------------------------------------------------------------------------------------------------------- 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()); }