void DirLightShadowNode::render()
{
    if(!tryRender()) return;

    if(!_sceneView)
        return;

    for(size_t i=0 ; i<_resolution.z() ; ++i)
    {
#warning OPTIMIZE SHADOW FOR LAST LEVEL
        _buffer.fbo()->attachDepthTexture(_buffer.buffer(0), i);
        _buffer.fbo()->bind();
        renderer::openGL.clearDepth();

        if(!_toDraw[i].empty())
        {
            vector<mat4> accMatr;
            vector<renderer::MeshBuffers*> accMesh;
            //vector<renderer::Material> accMate;

            for(uint index=0 ; index < _toDraw[i].size() ; ++index)
            {
                if(_toDraw[i][index].first->geometry().buffers() && !_toDraw[i][index].first->geometry().buffers()->isNull())
                {
                    accMatr.push_back(_toDraw[i][index].second->transposed());
                    accMesh.push_back(_toDraw[i][index].first->geometry().buffers());
                    //accMate.push_back(_toDraw[i][curIndex].first->internalMaterial());
                }
            }
            if(!accMesh.empty())
            {
                _meshDrawer.setDrawState(_defaultDrawState);

                mat4 viewMat = mat4::View(_sceneView->dirLightView.realPos[i], _sceneView->dirLightView.realPos[i] + _sceneView->dirLightView.lightDir,
                                          _sceneView->dirLightView.up);

                mat4 projView = _orthoMatrix[i] * viewMat;
                _matrix[i] = mat4::BIAS() * projView;
                _defaultDrawState.shader()->bind();
                _defaultDrawState.shader()->setUniform(projView,
                                                       _defaultDrawState.shader()->engineUniformId(renderer::Shader::PROJVIEW));

                _meshDrawer.draw(accMesh, accMatr, {}, {}, false);
            }
        }

        _buffer.fbo()->unbind();
    }
}
示例#2
0
文件: engine.cpp 项目: pmer/xombie
/**
 * mainLoop()
 * runs the game
 */
void Engine::mainLoop()
{
	long dt = 0; // delta time since last frame

	while (!quitting) {
		captureInput();
		runGameEngine(dt);
		tryRender();

		// Sleep 'till next frame, don't waste the CPU
		dt = wait();
	}

	Quit();
}
void DeferredRendererNode::render()
{
    if(!tryRender()) return;

    if(_rendererEntity == nullptr)
        return;

    if(_sceneView)
        _meshDrawer.frameState().setCamera(_sceneView->camera);

    _rendererEntity->deferredRenderer().acquire();
    _rendererEntity->deferredRenderer().frameBuffer()->bind();

    openGL.clearDepth();
    openGL.clearColor(vec4::construct(0));

    openGL.scissorTest(_useScissor);
    if(_useScissor)
    {
        if(buffer(0))
        {
            uivec2 coord = {static_cast<uint>(buffer(0)->resolution().x() * _coordScissor.x()),
                            static_cast<uint>(buffer(0)->resolution().y() * _coordScissor.y())};
            uivec2 size = {static_cast<uint>(buffer(0)->resolution().x() * _sizeScissor.x()),
                           static_cast<uint>(buffer(0)->resolution().y() * _sizeScissor.y())};

            openGL.scissorParam(coord, size);
        }

    }

    for(int i=0 ; i<NB_CLIP_PLAN ; ++i)
        if(_useClipPlan[i]) glEnable(GL_CLIP_DISTANCE0+i);
        else glDisable(GL_CLIP_DISTANCE0+i);

    std::set<Shader*> alreadyUsed;

    if(!_toDraw.empty())
    {
        vector<mat4> accMatr;
        vector<renderer::MeshBuffers*> accMesh;
        vector<renderer::DummyMaterial> accMate;
        vector<vector<uint>> accExtraUbo;
        renderer::DrawState curDrawState = _toDraw[0].elem->drawState();
        uint curIndex=0;

        for(curIndex=0 ; curIndex < _toDraw.size() ; ++curIndex)
        {
            if(curDrawState != _toDraw[curIndex].elem->drawState())
            {
                _meshDrawer.setDrawState(curDrawState);

                if(curDrawState.shader())
                {
                    if(alreadyUsed.find(curDrawState.shader()) == alreadyUsed.end())
                    {
                        alreadyUsed.insert(curDrawState.shader());
                        curDrawState.shader()->bind();
                        for(int i=0 ; i<NB_CLIP_PLAN ; ++i)
                        {
                            if(_useClipPlan[i])
                                curDrawState.shader()->setUniform(_clipPlan[i],
                                                                  curDrawState.shader()->engineUniformId(Shader::EngineUniform::CLIP_PLAN_0+i));
                        }
                    }
                }

                _meshDrawer.draw(accMesh, accMatr, accMate);
                accMesh.resize(0);
                accMatr.resize(0);
                accMate.resize(0);
                accExtraUbo.resize(0);
                curDrawState = _toDraw[curIndex].elem->drawState();
            }

            if(_toDraw[curIndex].elem->geometry().buffers() && !_toDraw[curIndex].elem->geometry().buffers()->isNull())
            {
                accMatr.push_back(_toDraw[curIndex].matrix->transposed());
                accMesh.push_back(_toDraw[curIndex].elem->geometry().buffers());
                accMate.push_back(_toDraw[curIndex].elem->dummyMaterial());
                accExtraUbo.push_back(*(_toDraw[curIndex].extraUbo));
            }
        }
        if(!accMesh.empty())
        {
            _meshDrawer.setDrawState(curDrawState);

            if(curDrawState.shader())
            {
                if(alreadyUsed.find(curDrawState.shader()) == alreadyUsed.end())
                {
                    alreadyUsed.insert(curDrawState.shader());
                    curDrawState.shader()->bind();
                    for(int i=0 ; i<NB_CLIP_PLAN ; ++i)
                    {
                        if(_useClipPlan[i])
                            curDrawState.shader()->setUniform(_clipPlan[i],
                                                              curDrawState.shader()->engineUniformId(Shader::EngineUniform::CLIP_PLAN_0+i));
                    }
                }
            }

            _meshDrawer.draw(accMesh, accMatr, accMate, accExtraUbo);
        }
    }

    for(int i=0 ; i<NB_CLIP_PLAN ; ++i)
        if(_useClipPlan[i])
            glDisable(GL_CLIP_DISTANCE0+i);

    vector<LightContextRenderer::Light> lights(_culledLight.size());
    for(uint i=0 ; i<lights.size() ; ++i)
        lights[i] = _culledLight[i].get().get();

    _rendererEntity->lightContext()->acquire();

    renderer::Texture* globalPSkybox = nullptr;
    if(_globalLightInfo)
        globalPSkybox = _globalLightInfo->skybox.second;

    if (_rendererEntity->lightRenderer())
        _rendererEntity->lightRenderer()->draw(lights, globalPSkybox);
    else
        _rendererEntity->lightContext()->clear();

    if(_globalLightInfo)
    {
        openGL.scissorTest(false);
        for(uint i=0 ; i<std::min(_dirLightDepthMapRenderer.size(),_globalLightInfo->dirLights.size()) ; ++i)
        {
            if(_dirLightDepthMapRenderer[i] && _globalLightInfo->dirLights[i].projectShadow)
            {
                _dirLightDepthMapRenderer[i]->acquire(0);
                _dirLightDepthMapRenderer[i]->render();
            }
        }
        openGL.scissorTest(_useScissor);

        vector<IndirectLightRenderer::Light> lights(_globalLightInfo->dirLights.size());
        for(uint i=0 ; i<_globalLightInfo->dirLights.size() ; ++i)
        {
            lights[i].direction = _globalLightInfo->dirLights.at(i).direction;
            lights[i].color = vec3(_globalLightInfo->dirLights.at(i).color);
            lights[i].depthMap = nullptr;
            if(_globalLightInfo->dirLights.at(i).projectShadow && i<_dirLightDepthMapRenderer.size() &&
               _dirLightDepthMapRenderer[i])
            {
                lights[i].depthMap = _dirLightDepthMapRenderer[i]->buffer(0);
                lights[i].matrix =    _dirLightDepthMapRenderer[i]->matrix();
            }
        }

//        if(_rendererEntity->envLightRenderer().isLocalReflexionEnabled())
//        {
//            if(!_copyToFBO)
//            {
//                renderer::Texture::GenTexParam param;
//                param.size = uivec3(_rendererEntity->lightContext()->resolution(), 0);
//                param.nbLevels = 1;
//                param.format = _rendererEntity->lightContext()->buffer()->format();
//                _copyBuffer = renderer::Texture::genTexture2D(param);

//                _copyToFBO = new renderer::FrameBuffer(_rendererEntity->lightContext()->resolution());
//                _copyToFBO->attachTexture(0, _copyBuffer);
//            }

//            openGL.scissorTest(false);
//            _rendererEntity->lightContext()->frameBuffer().copyTo(*_copyToFBO);
//            openGL.scissorTest(_useScissor);

//            _rendererEntity->envLightRenderer().setReflexionBuffer(_copyBuffer);
//        }

        _rendererEntity->envLightRenderer().setSkybox(_globalLightInfo->skybox.first, _globalLightInfo->skybox.second);
        _rendererEntity->envLightRenderer().draw(lights);

        for(uint i=0 ; i<std::min(_dirLightDepthMapRenderer.size(),_globalLightInfo->dirLights.size()) ; ++i)
            if(_dirLightDepthMapRenderer[i] && _globalLightInfo->dirLights[i].projectShadow)
                _dirLightDepthMapRenderer[i]->release(0);
    }

    if(_rendererEntity->reflexionRenderer())
        _rendererEntity->reflexionRenderer()->draw();

    _rendererEntity->lightContext()->release();
    _rendererEntity->deferredRenderer().release();

    openGL.scissorTest(false);
}