#include "client/rendering/Engine.h" #include "client/rendering/ShaderMatrix.h" #include "gaming-core/wrapper/GL.h" Engine::Engine(Shaders& shaders, Framebuffers& fb, const Size& size, RenderSettings& renderSettings) : shaders(shaders), framebuffers(fb), size(size), renderSettings(renderSettings), frustum(60.0f, 0.1f, 1000.0f, size) { TypedBuffer buffer(2); buffer.add( Triangle(Vertex(Vector3(-1.0f, -1.0f, 0.0f), Vector2(0, 0.0f)), Vertex(Vector3(1.0f, 1.0f, 0.0f), Vector2(1.0f, 1.0f)), Vertex(Vector3(-1.0f, 1.0f, 0.0f), Vector2(0.0f, 1.0f)))); buffer.add( Triangle(Vertex(Vector3(-1.0f, -1.0f, 0.0f), Vector2(0, 0.0f)), Vertex(Vector3(1.0f, -1.0f, 0.0f), Vector2(1.0f, 0.0f)), Vertex(Vector3(1.0f, 1.0f, 0.0f), Vector2(1.0f, 1.0f)))); rectangle.build(buffer); } void Engine::renderTick(float lag, Game& game) { updateWorldProjection(); updateWorldView(); if(renderSettings.shadows) { renderShadow(lag, game); } renderWorld(lag, game); if(renderSettings.ssao) { renderSSAO(); } renderPostWorld(); renderOverlay(lag, game); } void Engine::renderShadow(float lag, Game& game) { framebuffers.shadow.bindAndClear(); GL::enableDepthTesting(); shaders.shadow.use(); worldShadowProjView = worldShadowProj; worldShadowProjView *= worldShadowView; shaders.shadow.setMatrix("projView", worldShadowProjView.getValues()); model.clear(); shaders.shadow.setMatrix("model", model.peek().getValues()); ShaderMatrix sm(shaders.shadow, model, worldView); game.renderWorld(lag, sm); } void Engine::renderWorld(float lag, Game& game) { framebuffers.world.bindAndClear(); GL::enableDepthTesting(); shaders.world.use(); Matrix rWorldShadowProjView; rWorldShadowProjView.scale(0.5f).translate(Vector3(0.5f, 0.5f, 0.5f)); rWorldShadowProjView *= worldShadowProjView; shaders.world.setMatrix("projViewShadow", rWorldShadowProjView.getValues()); shaders.world.setMatrix("proj", worldProj.getValues()); worldView = Matrix(); shaders.world.setMatrix("view", worldView.getValues()); model.clear(); shaders.world.setMatrix("model", model.peek().getValues()); framebuffers.shadow.bindTextureTo(0, 1); shaders.world.setInt("shadows", renderSettings.shadows); shaders.world.setFloat("radius", renderSettings.testRadius); shaders.world.setFloat("zbias", renderSettings.testBias); ShaderMatrix sm(shaders.world, model, worldView); game.renderWorld(lag, sm); } void Engine::renderSSAO() { shaders.ssao.use(); Matrix rProj; rProj.scale(0.5f).translate(Vector3(0.5f, 0.5f, 0.5f)); rProj *= worldProj; shaders.ssao.setMatrix("proj", rProj.getValues()); shaders.ssao.setInt("width", size.width); shaders.ssao.setInt("height", size.height); framebuffers.world.bindTextureTo(0, 0); framebuffers.world.bindTextureTo(4, 1); ssaoNoise.bindTo(2); framebuffers.ssao.bindAndClear(); rectangle.draw(); shaders.ssaoBlur.use(); framebuffers.ssao.bindTextureTo(0, 0); framebuffers.ssaoBlur.bindAndClear(); rectangle.draw(); } void Engine::renderPostWorld() { GL::bindMainFramebuffer(); GL::clear(); shaders.postWorld.use(); framebuffers.world.bindTextureTo(2, 0); framebuffers.ssaoBlur.bindTextureTo(0, 1); framebuffers.world.bindTextureTo(3, 2); framebuffers.world.bindTextureTo(1, 3); shaders.postWorld.setInt("ssao", renderSettings.ssao); shaders.postWorld.setInt("shadows", renderSettings.shadows); rectangle.draw(); } void Engine::renderOverlay(float lag, Game& game) { GL::disableDepthTesting(); shaders.overlay.use(); Matrix m; m.scale(Vector3(2.0f / size.width, -2.0f / size.height, 1.0f)) .translate(Vector3(-1.0f, 1.0f, 0.0f)); shaders.overlay.setMatrix("view", m.getValues()); model.clear(); shaders.overlay.setMatrix("model", model.peek().getValues()); GL::enableBlending(); ShaderMatrix sm(shaders.overlay, model, m); game.renderOverlay(lag, sm, renderer); GL::disableBlending(); } void Engine::updateWorldProjection() { worldProj = frustum.updateProjection(); if(!renderSettings.shadows) { return; } worldShadowProj.set(0, Vector4(2.0f / 40.0f, 0.0f, 0.0f, 0.0f)); worldShadowProj.set(1, Vector4(0.0f, 2.0f / 30.0f, 0.0f, 0.0f)); worldShadowProj.set(2, Vector4(0.0f, 0.0f, -2.0f / (1000.0f - 0.1f), 0.0f)); worldShadowProj.set(3, Vector4(0.0f, 0.0f, 0.0f, 1.0f)); } void Engine::updateWorldView() { if(!renderSettings.shadows) { return; } Vector3 right(0.939693f, 0.0f, -0.34202f); Vector3 back(0.280166f, 0.573576f, 0.769751f); Vector3 up(-0.196175f, 0.819152f, -0.538986f); Vector3 center(16.0f, 24.0f, 24.0f); worldShadowView.set( 0, Vector4(right[0], right[1], right[2], right.dot(-center))); worldShadowView.set(1, Vector4(up[0], up[1], up[2], up.dot(-center))); worldShadowView.set(2, Vector4(back[0], back[1], back[2], back.dot(-center))); worldShadowView.set(3, Vector4(0.0f, 0.0f, 0.0f, 1.0f)); }