123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292 |
- #include <cmath>
- #include <chrono>
- #include <thread>
- #include "client/engine/Wrapper.h"
- DummyClient DummyClient::dummy;
- IClient* Engine::client = &DummyClient::dummy;
- // window data
- GLFWwindow* Engine::window = nullptr;
- int Engine::scale = 1;
- int Engine::width = 0;
- int Engine::height = 0;
- int Engine::resizeTicks = -1;
- // projection data
- float Engine::fovY = 60;
- float Engine::nearClip = 0.1f;
- float Engine::farClip = 1000.0f;
- Matrix3D Engine::projMatrix;
- // rectangle for framebuffer drawing
- FramebufferRectangle Engine::rectangle;
- int Engine::stage = 0;
- // shader stage 1 - world
- WorldShader Engine::worldShader;
- // shader stage 2 - world ssao
- SSAOShader Engine::ssaoShader;
- // shader stage 3 - world ssao blur
- SSAOBlurShader Engine::ssaoBlurShader;
- // shader stage 4 - world post
- WorldPostShader Engine::worldPostShader;
- // shader stage 5 - 2D overlay
- OverlayShader Engine::overlayShader;
- void Engine::sleep(uint64_t nanos)
- {
- uint64_t end = glfwGetTimerValue() + nanos - 10000;
- // non busy wait until a close range
- while(end > glfwGetTimerValue() + 1000000)
- {
- this_thread::sleep_for(chrono::nanoseconds(1000000));
- }
- while(end > glfwGetTimerValue() + 100000)
- {
- this_thread::sleep_for(chrono::nanoseconds(100000));
- }
- // busy wait for higher accuracy at the end
- while(end > glfwGetTimerValue());
- }
- void Engine::stop()
- {
- glfwSetWindowShouldClose(window, 1);
- }
- void Engine::onKeyEvent(GLFWwindow* w, int key, int scancode, int action, int mods)
- {
- client->onKeyEvent(key, scancode, action, mods);
- }
- void Engine::onMouseMove(GLFWwindow* w, double x, double y)
- {
- client->onMouseMove(x, y);
- }
- void Engine::onMouseClick(GLFWwindow* w, int button, int action, int mods)
- {
- client->onMouseClick(button, action, mods);
- }
- void Engine::onWindowResize(GLFWwindow* w, int width, int height)
- {
- Engine::width = width;
- Engine::height = height;
- resizeTicks = 10;
- }
- void Engine::updateScale()
- {
- scale = 1;
- while(width / (scale + 1) >= 400 && height / (scale + 1) >= 300)
- {
- scale++;
- }
- }
- int Engine::getScale()
- {
- return scale;
- }
- int Engine::getWidth()
- {
- return width;
- }
- int Engine::getHeight()
- {
- return height;
- }
- float Engine::getScaledWidth()
- {
- return (float) width / scale;
- }
- float Engine::getScaledHeight()
- {
- return (float) height / scale;
- }
- float Engine::getFieldOfView()
- {
- return fovY;
- }
- float Engine::getNearClip()
- {
- return nearClip;
- }
- float Engine::getFarClip()
- {
- return farClip;
- }
- void Engine::printError()
- {
- GLenum error = glGetError();
- switch(error)
- {
- case GL_NO_ERROR:
- //cout << "> No error has been recorded." << endl;
- break;
- case GL_INVALID_ENUM:
- cout << "> An unacceptable value is specified for an enumerated argument." << endl;
- break;
- case GL_INVALID_VALUE:
- cout << "> A numeric argument is out of range." << endl;
- break;
- case GL_INVALID_OPERATION:
- cout << "> The specified operation is not allowed in the current state." << endl;
- break;
- case GL_INVALID_FRAMEBUFFER_OPERATION:
- cout << "> The framebuffer object is not complete." << endl;
- break;
- case GL_OUT_OF_MEMORY:
- cout << "> There is not enough memory left to execute the command." << endl;
- break;
- case GL_STACK_UNDERFLOW:
- cout << "> An attempt has been made to perform an operation that would cause an internal stack to underflow." << endl;
- break;
- case GL_STACK_OVERFLOW:
- cout << "> An attempt has been made to perform an operation that would cause an internal stack to overflow." << endl;
- break;
- default:
- cout << "> Unknown OpenGL error: " << error << endl;
- }
- }
- void Engine::onRenderTick(float lag)
- {
- // update projection matrix
- float tan = tanf((0.5f * fovY) * M_PI / 180.0f);
- float q = 1.0f / tan;
- float aspect = (float) width / height;
- projMatrix.set(0, 0, q / aspect);
- projMatrix.set(1, 1, q);
- projMatrix.set(2, 2, (nearClip + farClip) / (nearClip - farClip));
- projMatrix.set(3, 2, -1.0f);
- projMatrix.set(2, 3, (2.0f * nearClip * farClip) / (nearClip - farClip));
- projMatrix.set(3, 3, 0);
-
- // -------------------------------------------------------------------------
- // shader stage 1 - world
- // -------------------------------------------------------------------------
- stage = 1;
- worldShader.preRender(projMatrix.getValues());
- // call render tick for further drawing
- client->render3DTick(lag);
-
- // -------------------------------------------------------------------------
- // shader stage 2 - world ssao
- // -------------------------------------------------------------------------
- stage = 2;
- ssaoShader.preRender(projMatrix.getValues());
-
- // bind previously generated texture data buffers
- worldShader.bindPositionTexture(1);
- worldShader.bindNormalTexture(2);
- worldShader.bindColorTexture(3);
- worldShader.bindDepthTexture(4);
- ssaoShader.bindNoiseTexture(5);
-
- rectangle.draw();
-
- // -------------------------------------------------------------------------
- // shader stage 3 - world ssao blur
- // -------------------------------------------------------------------------
- stage = 3;
- ssaoBlurShader.preRender();
- ssaoShader.bindTexture(6);
- rectangle.draw();
-
- // -------------------------------------------------------------------------
- // shader stage 4 - world post
- // -------------------------------------------------------------------------
- stage = 4;
- worldPostShader.preRender();
- ssaoBlurShader.bindTexture(7);
- rectangle.draw();
-
- // -------------------------------------------------------------------------
- // shader stage 5 - 2D overlay
- // -------------------------------------------------------------------------
- stage = 5;
- overlayShader.preRender();
- worldPostShader.bindTexture(0);
- rectangle.draw();
- overlayShader.setViewMatrix();
-
- setMixMode();
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glBlendEquation(GL_FUNC_ADD);
- client->render2DTick(lag);
- glDisable(GL_BLEND);
- }
- void Engine::setViewMatrix(const float* data)
- {
- if(stage == 1)
- {
- worldShader.setViewMatrix(data);
- }
- }
- void Engine::setModelMatrix(const float* data)
- {
- if(stage == 1)
- {
- worldShader.setModelMatrix(data);
- }
- else if(stage == 5)
- {
- overlayShader.setModelMatrix(data);
- }
- }
- void Engine::setMouseTrapped(bool mode)
- {
- if(mode)
- {
- glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
- }
- else
- {
- glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
- }
- }
- void Engine::setMixMode()
- {
- if(stage == 5)
- {
- overlayShader.setUseColor(true);
- overlayShader.setUseTexture(true);
- }
- }
- void Engine::setColorMode()
- {
- if(stage == 5)
- {
- overlayShader.setUseColor(true);
- overlayShader.setUseTexture(false);
- }
- }
- void Engine::setTextureMode()
- {
- if(stage == 5)
- {
- overlayShader.setUseColor(false);
- overlayShader.setUseTexture(true);
- }
- }
|