|
@@ -1,26 +1,42 @@
|
|
|
-#include "GameEngine.h"
|
|
|
-#include "MouseManager.h"
|
|
|
-#include <cmath>
|
|
|
+#include "Wrapper.h"
|
|
|
+#include <fstream>
|
|
|
+#include <cstring>
|
|
|
+#include <iostream>
|
|
|
|
|
|
-GameEngine* GameEngine::instance = nullptr;
|
|
|
+using namespace std;
|
|
|
|
|
|
-void GameEngine::start(int width, int height, const char* name, InitFunction init, TickFunction tick, RenderTickFunction renderTick)
|
|
|
-{
|
|
|
+DummyClient DummyClient::dummy;
|
|
|
+
|
|
|
+IClient* Engine::client = &DummyClient::dummy;
|
|
|
+GLFWwindow* Engine::window = nullptr;
|
|
|
+GLuint Engine::vShader = 0;
|
|
|
+GLuint Engine::fShader = 0;
|
|
|
+GLuint Engine::program = 0;
|
|
|
+int Engine::scale = 1;
|
|
|
+int Engine::width = 0;
|
|
|
+int Engine::height = 0;
|
|
|
+
|
|
|
+bool Engine::init(int width, int height, const char* name)
|
|
|
+{
|
|
|
+ Engine::width = width;
|
|
|
+ Engine::height = height;
|
|
|
+ updateScale();
|
|
|
+
|
|
|
if(!glfwInit())
|
|
|
{
|
|
|
cout << "could not initialize GLFW" << endl;
|
|
|
- return;
|
|
|
+ return false;
|
|
|
}
|
|
|
|
|
|
glfwDefaultWindowHints();
|
|
|
glfwWindowHint(GLFW_VISIBLE, 0);
|
|
|
glfwWindowHint(GLFW_RESIZABLE, 1);
|
|
|
- GLFWwindow* window = glfwCreateWindow(width, height, name, nullptr, nullptr);
|
|
|
+ window = glfwCreateWindow(width, height, name, nullptr, nullptr);
|
|
|
if(!window)
|
|
|
{
|
|
|
cout << "could not create window" << endl;
|
|
|
glfwTerminate();
|
|
|
- return;
|
|
|
+ return false;
|
|
|
}
|
|
|
|
|
|
glfwMakeContextCurrent(window);
|
|
@@ -32,13 +48,13 @@ void GameEngine::start(int width, int height, const char* name, InitFunction ini
|
|
|
if(GLEW_OK != err)
|
|
|
{
|
|
|
cout << "could not initialize GLEW: " << glewGetErrorString(err) << endl;
|
|
|
- return;
|
|
|
+ return false;
|
|
|
}
|
|
|
cout << "Status: Using GLEW " << glewGetString(GLEW_VERSION) << endl;
|
|
|
|
|
|
- GLuint vShader = 0;
|
|
|
- GLuint fShader = 0;
|
|
|
- GLuint program = createProgram(vShader, program);
|
|
|
+ vShader = 0;
|
|
|
+ fShader = 0;
|
|
|
+ program = createProgram(vShader, program);
|
|
|
if(program == 0)
|
|
|
{
|
|
|
if(vShader != 0)
|
|
@@ -51,40 +67,21 @@ void GameEngine::start(int width, int height, const char* name, InitFunction ini
|
|
|
}
|
|
|
glfwDestroyWindow(window);
|
|
|
glfwTerminate();
|
|
|
- return;
|
|
|
+ return false;
|
|
|
}
|
|
|
-
|
|
|
- GameEngine::instance = new GameEngine(program, vShader, fShader, window, width, height, tick, renderTick);
|
|
|
- glfwSetKeyCallback(window, [](GLFWwindow* w, int key, int scancode, int action, int mods)
|
|
|
- {
|
|
|
- GameEngine::instance->onKeyEvent(w, key, scancode, action, mods);
|
|
|
- });
|
|
|
- glfwSetMouseButtonCallback(window, [](GLFWwindow* w, int button, int action, int mods)
|
|
|
- {
|
|
|
- GameEngine::instance->onMouseClick(w, button, action, mods);
|
|
|
- });
|
|
|
- glfwSetFramebufferSizeCallback(window, [](GLFWwindow* w, int width, int height)
|
|
|
- {
|
|
|
- GameEngine::instance->onWindowResize(w, width, height);
|
|
|
- });
|
|
|
+
|
|
|
+ glfwSetKeyCallback(window, onKeyEvent);
|
|
|
+ glfwSetMouseButtonCallback(window, onMouseClick);
|
|
|
+ glfwSetFramebufferSizeCallback(window, onWindowResize);
|
|
|
|
|
|
|
|
|
-
|
|
|
- init();
|
|
|
- instance->run();
|
|
|
- delete instance;
|
|
|
+ return true;
|
|
|
}
|
|
|
|
|
|
-void GameEngine::stop()
|
|
|
+void Engine::start(IClient& client)
|
|
|
{
|
|
|
- if(GameEngine::instance != nullptr)
|
|
|
- {
|
|
|
- glfwSetWindowShouldClose(GameEngine::instance->window, 1);
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-void GameEngine::run()
|
|
|
-{
|
|
|
+ Engine::client = &client;
|
|
|
+
|
|
|
glEnable(GL_CULL_FACE);
|
|
|
glEnable(GL_DEPTH_TEST);
|
|
|
glDepthFunc(GL_LEQUAL);
|
|
@@ -105,10 +102,7 @@ void GameEngine::run()
|
|
|
{
|
|
|
lag -= NANOS_PER_TICK;
|
|
|
|
|
|
- tps.update();
|
|
|
- tick();
|
|
|
- keyManager.tick();
|
|
|
- mouseManager.tick();
|
|
|
+ Engine::client->tick();
|
|
|
ticksPerFrame++;
|
|
|
|
|
|
if(ticksPerFrame >= MAX_TICKS_PER_FRAME)
|
|
@@ -123,8 +117,7 @@ void GameEngine::run()
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- fps.update();
|
|
|
- renderTick((float) lag / NANOS_PER_TICK);
|
|
|
+ Engine::client->renderTick((float) lag / NANOS_PER_TICK);
|
|
|
|
|
|
glfwSwapBuffers(window);
|
|
|
glfwPollEvents();
|
|
@@ -137,89 +130,12 @@ void GameEngine::run()
|
|
|
glfwTerminate();
|
|
|
}
|
|
|
|
|
|
-GLuint GameEngine::setInstance(GLuint program, GameEngine* en)
|
|
|
-{
|
|
|
- GameEngine::instance = en;
|
|
|
- return program;
|
|
|
-}
|
|
|
-
|
|
|
-GameEngine::GameEngine(GLuint program, GLuint vShader, GLuint fShader, GLFWwindow* window,
|
|
|
- int width, int height, TickFunction tick, RenderTickFunction renderTick) :
|
|
|
- program(setInstance(program, this)), vShader(vShader), fShader(fShader), window(window), width(width), height(height), tick(tick), renderTick(renderTick)
|
|
|
-{
|
|
|
- updateScale();
|
|
|
-}
|
|
|
-
|
|
|
-GameEngine::~GameEngine()
|
|
|
-{
|
|
|
-}
|
|
|
-
|
|
|
-void GameEngine::onKeyEvent(GLFWwindow* w, int key, int scancode, int action, int mods)
|
|
|
-{
|
|
|
- if(action == GLFW_RELEASE)
|
|
|
- {
|
|
|
- if(key == GLFW_KEY_ESCAPE)
|
|
|
- {
|
|
|
-
|
|
|
- glfwSetInputMode(w, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
|
|
|
- }
|
|
|
- keyManager.release(key);
|
|
|
- }
|
|
|
- else if(action == GLFW_PRESS)
|
|
|
- {
|
|
|
- keyManager.press(key);
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-void GameEngine::onMouseClick(GLFWwindow* w, int button, int action, int mods)
|
|
|
+void Engine::stop()
|
|
|
{
|
|
|
- if(action == GLFW_PRESS)
|
|
|
- {
|
|
|
-
|
|
|
- {
|
|
|
- glfwSetInputMode(w, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
|
|
|
- oldMouseX = 0;
|
|
|
- oldMouseY = 0;
|
|
|
- activeFocus = 1;
|
|
|
- }
|
|
|
- else
|
|
|
- {*/
|
|
|
- mouseManager.press(button);
|
|
|
-
|
|
|
- }
|
|
|
- else if(action == GLFW_RELEASE)
|
|
|
- {
|
|
|
- mouseManager.release(button);
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-{
|
|
|
- if(activeFocus)
|
|
|
- {
|
|
|
- if(oldMouseX == 0 && oldMouseY == 0)
|
|
|
- {
|
|
|
- oldMouseX = x;
|
|
|
- oldMouseY = y;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- mouseMove(x - oldMouseX, y - oldMouseY);
|
|
|
- oldMouseX = x;
|
|
|
- oldMouseY = y;
|
|
|
- }
|
|
|
- }
|
|
|
-}*/
|
|
|
-
|
|
|
-void GameEngine::onWindowResize(GLFWwindow* w, int width, int height)
|
|
|
-{
|
|
|
- glViewport(0, 0, width, height);
|
|
|
- GameEngine::width = width;
|
|
|
- GameEngine::height = height;
|
|
|
- updateScale();
|
|
|
+ glfwSetWindowShouldClose(window, 1);
|
|
|
}
|
|
|
|
|
|
-GLchar* GameEngine::readFile(const char* name)
|
|
|
+GLchar* Engine::readFile(const char* name)
|
|
|
{
|
|
|
ifstream in;
|
|
|
in.open(name);
|
|
@@ -257,7 +173,7 @@ GLchar* GameEngine::readFile(const char* name)
|
|
|
return nullptr;
|
|
|
}
|
|
|
|
|
|
-bool GameEngine::checkShaderErrors(const char* name, GLuint shader)
|
|
|
+bool Engine::checkShaderErrors(const char* name, GLuint shader)
|
|
|
{
|
|
|
bool returnValue = false;
|
|
|
|
|
@@ -294,7 +210,7 @@ bool GameEngine::checkShaderErrors(const char* name, GLuint shader)
|
|
|
return returnValue;
|
|
|
}
|
|
|
|
|
|
-GLuint GameEngine::compileProgram(GLuint& vShader, GLuint& fShader, const GLchar* vertex, const GLchar* fragment)
|
|
|
+GLuint Engine::compileProgram(GLuint& vShader, GLuint& fShader, const GLchar* vertex, const GLchar* fragment)
|
|
|
{
|
|
|
vShader = glCreateShader(GL_VERTEX_SHADER);
|
|
|
glShaderSource(vShader, 1, &vertex, nullptr);
|
|
@@ -355,7 +271,7 @@ GLuint GameEngine::compileProgram(GLuint& vShader, GLuint& fShader, const GLchar
|
|
|
return program;
|
|
|
}
|
|
|
|
|
|
-GLuint GameEngine::createProgram(GLuint& vShader, GLuint& fShader)
|
|
|
+GLuint Engine::createProgram(GLuint& vShader, GLuint& fShader)
|
|
|
{
|
|
|
GLchar* vertex = readFile("shader/vertex.vs");
|
|
|
if(vertex == nullptr)
|
|
@@ -377,117 +293,98 @@ GLuint GameEngine::createProgram(GLuint& vShader, GLuint& fShader)
|
|
|
return program;
|
|
|
}
|
|
|
|
|
|
-void GameEngine::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 GameEngine::updateScale()
|
|
|
-{
|
|
|
- scale = 1;
|
|
|
- while(width / (scale + 1) >= 400 && height / (scale + 1) >= 300)
|
|
|
- {
|
|
|
- scale++;
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-GameEngine* GameEngine::get()
|
|
|
-{
|
|
|
- return instance;
|
|
|
-}
|
|
|
-
|
|
|
-KeyManager& GameEngine::getKeyManager()
|
|
|
+void Engine::onKeyEvent(GLFWwindow* w, int key, int scancode, int action, int mods)
|
|
|
{
|
|
|
- return keyManager;
|
|
|
+ client->onKeyEvent(key, scancode, action, mods);
|
|
|
}
|
|
|
|
|
|
-MouseManager& GameEngine::getMouseManager()
|
|
|
+void Engine::onMouseClick(GLFWwindow* w, int button, int action, int mods)
|
|
|
{
|
|
|
- return mouseManager;
|
|
|
+ client->onMouseClick(button, action, mods);
|
|
|
}
|
|
|
|
|
|
-Shader& GameEngine::getShader()
|
|
|
+void Engine::onWindowResize(GLFWwindow* w, int width, int height)
|
|
|
{
|
|
|
- return shader;
|
|
|
-}
|
|
|
-
|
|
|
-DirectRenderer& GameEngine::getDirectRenderer()
|
|
|
-{
|
|
|
- return directRenderer;
|
|
|
-}
|
|
|
-
|
|
|
-double GameEngine::getTicksPerSecond() const
|
|
|
-{
|
|
|
- return tps.getUpdatesPerSecond();
|
|
|
+ glViewport(0, 0, width, height);
|
|
|
+ Engine::width = width;
|
|
|
+ Engine::height = height;
|
|
|
+ updateScale();
|
|
|
}
|
|
|
|
|
|
-double GameEngine::getFramesPerSecond() const
|
|
|
+void Engine::updateScale()
|
|
|
{
|
|
|
- return fps.getUpdatesPerSecond();
|
|
|
+ scale = 1;
|
|
|
+ while(width / (scale + 1) >= 400 && height / (scale + 1) >= 300)
|
|
|
+ {
|
|
|
+ scale++;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
-int GameEngine::getScale() const
|
|
|
+int Engine::getScale()
|
|
|
{
|
|
|
return scale;
|
|
|
}
|
|
|
|
|
|
-int GameEngine::getWidth() const
|
|
|
+int Engine::getWidth()
|
|
|
{
|
|
|
return width;
|
|
|
}
|
|
|
|
|
|
-int GameEngine::getHeight() const
|
|
|
+int Engine::getHeight()
|
|
|
{
|
|
|
return height;
|
|
|
}
|
|
|
|
|
|
-GLint GameEngine::getUniformLocation(const GLchar* name) const
|
|
|
+GLint Engine::getUniformLocation(const GLchar* name)
|
|
|
{
|
|
|
return glGetUniformLocation(program, name);
|
|
|
}
|
|
|
|
|
|
-void GameEngine::setMatrix(GLint location, const GLfloat* m)
|
|
|
+void Engine::setMatrix(GLint location, const GLfloat* m)
|
|
|
{
|
|
|
glUniformMatrix4fv(location, 1, 0, m);
|
|
|
}
|
|
|
|
|
|
-void GameEngine::setInt(GLint location, GLint i)
|
|
|
+void Engine::setInt(GLint location, GLint i)
|
|
|
{
|
|
|
glUniform1i(location, i);
|
|
|
}
|
|
|
|
|
|
-void GameEngine::setFloat(GLint location, GLfloat f1, GLfloat f2, GLfloat f3, GLfloat f4)
|
|
|
+void Engine::setFloat(GLint location, GLfloat f1, GLfloat f2, GLfloat f3, GLfloat f4)
|
|
|
{
|
|
|
glUniform4f(location, f1, f2, f3, f4);
|
|
|
}
|
|
|
|
|
|
-
|
|
|
+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;
|
|
|
+ }
|
|
|
+}
|