Example #1
0
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());
}