diff --git a/.idea/.name b/.idea/.name new file mode 100644 index 0000000..4ce9e08 --- /dev/null +++ b/.idea/.name @@ -0,0 +1 @@ +gl_template \ No newline at end of file diff --git a/framework/include/framework.h b/framework/include/framework.h index 0a76d8c..5d105c4 100644 --- a/framework/include/framework.h +++ b/framework/include/framework.h @@ -11,6 +11,9 @@ private: GLFWwindow *_window = nullptr; int _gl_major, _gl_minor; std::string _title; + float _last_time = 0, _time = 0, _rate = 1; + float _last_glfw_time = 0, _glfw_time = 0; + int _frame = 0; static void onKey(GLFWwindow *window, int key, int scan_code, int action, int mods); @@ -23,6 +26,12 @@ private: protected: App(int gl_major, int gl_minor); + void setTime(float time); + + void setFrame(int frame); + + void setRate(float rate); + void setTitle(std::string title); void setX(int x); @@ -56,6 +65,14 @@ protected: public: GLFWwindow *getWindow(); + int getFrame(); + + float getRate(); + + float getTime(); + + float getTimeDelta(); + std::string getTitle(); int getX(); diff --git a/framework/include/util.h b/framework/include/util.h index b534058..e74457d 100644 --- a/framework/include/util.h +++ b/framework/include/util.h @@ -1,3 +1,7 @@ +#include + +#include + #ifndef GL_TEMPLATE_UTIL_H #define GL_TEMPLATE_UTIL_H @@ -5,7 +9,6 @@ #include -#include #include #include @@ -15,13 +18,22 @@ namespace util { glBufferData(target, data.size() * sizeof(T), &data.front(), usage); } - void shaderFile(GLuint shader, const std::string &path) { - const std::string str = readFile(path); - const char *c_str = str.c_str(); - glShaderSource(shader, 1, &c_str, nullptr); + template + void bufferData(GLenum target, T &data, GLenum usage) { + glBufferData(target, sizeof(T), &data, usage); } - const std::string shaderInfoLog(GLuint shader) { + void shaderFiles(GLuint shader, std::vector &paths) { + std::vector strs; + std::vector c_strs; + + for (const auto &path : paths) strs.push_back(readFile(path)); + for (const auto &str:strs) c_strs.push_back(str.c_str()); + + glShaderSource(shader, (GLsizei) c_strs.size(), &c_strs.front(), nullptr); + } + + std::string shaderInfoLog(GLuint shader) { GLint log_len; glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &log_len); char log[log_len]; @@ -29,7 +41,7 @@ namespace util { return std::string(log); } - const std::string programInfoLog(GLuint program) { + std::string programInfoLog(GLuint program) { GLint log_len; glGetProgramiv(program, GL_INFO_LOG_LENGTH, &log_len); char log[log_len]; @@ -37,28 +49,17 @@ namespace util { return std::string(log); } - GLuint buildShader(const std::string &path) { - std::string ext = path.substr(path.rfind(".")); - - GLenum kind; - if (ext == ".vert") { - kind = GL_VERTEX_SHADER; - } else if (ext == ".frag") { - kind = GL_FRAGMENT_SHADER; - } else { - fprintf(stderr, "Cannot parse path %s\n", path.c_str()); - return 0; - } - + GLuint buildShader(GLenum kind, const std::string &name, std::vector paths) { GLuint shader = glCreateShader(kind); - util::shaderFile(shader, path); + shaderFiles(shader, paths); + glCompileShader(shader); GLint comp; glGetShaderiv(shader, GL_COMPILE_STATUS, &comp); if (!comp) { - const std::string log = shaderInfoLog(shader); - fprintf(stderr, "SHADER ERROR: %s\n%s", path.c_str(), log.c_str()); + std::string log = shaderInfoLog(shader); + fprintf(stderr, "SHADER ERROR (%s):\n%s", name.c_str(), log.c_str()); glDeleteShader(shader); return 0; } @@ -66,9 +67,39 @@ namespace util { return shader; } - GLuint buildProgram(std::initializer_list shaders) { + GLuint buildShader(GLenum kind, const std::vector &paths) { + switch (kind) { + case GL_VERTEX_SHADER: + return buildShader(kind, "VERTEX", paths); + case GL_FRAGMENT_SHADER: + return buildShader(kind, "FRAGMENT", paths); + default: + return buildShader(kind, "?", paths); + } + } + + GLuint buildShader(const std::string &path) { + std::string ext = path.substr(path.rfind('.')); + std::string name; + + std::vector paths{path}; + + if (ext == ".vert") { + return buildShader(GL_VERTEX_SHADER, paths); + } else if (ext == ".frag") { + return buildShader(GL_FRAGMENT_SHADER, paths); + } else { + fprintf(stderr, "Cannot parse path %s\n", path.c_str()); + return 0; + } + } + + GLuint buildProgram(bool separable, std::vector shaders) { GLuint program = glCreateProgram(); + if (separable) + glProgramParameteri(program, GL_PROGRAM_SEPARABLE, GL_TRUE); + for (GLuint shader : shaders) glAttachShader(program, shader); @@ -77,7 +108,7 @@ namespace util { GLint link; glGetProgramiv(program, GL_LINK_STATUS, &link); if (!link) { - const std::string log = programInfoLog(program); + std::string log = programInfoLog(program); fprintf(stderr, "PROGRAM ERROR:\n%s", log.c_str()); glDeleteProgram(program); return 0; diff --git a/framework/src/framework.cpp b/framework/src/framework.cpp index 61e22f1..bbeb0cd 100644 --- a/framework/src/framework.cpp +++ b/framework/src/framework.cpp @@ -7,6 +7,18 @@ App::App(int gl_major, int gl_minor) { _gl_minor = gl_minor; } +void App::setFrame(int frame) { + _frame = frame; +} + +void App::setTime(float time) { + _time = time; +} + +void App::setRate(float rate) { + _rate = rate; +} + void App::setTitle(std::string title) { _title = title; glfwSetWindowTitle(getWindow(), title.c_str()); @@ -44,6 +56,22 @@ GLFWwindow *App::getWindow() { return _window; } +int App::getFrame() { + return _frame; +} + +float App::getTime() { + return _time; +} + +float App::getRate() { + return _rate; +} + +float App::getTimeDelta() { + return _time - _last_time; +} + std::string App::getTitle() { return _title; } @@ -139,6 +167,8 @@ int App::run() { if (!(_window = glfwCreateWindow(1280, 720, _title.c_str(), nullptr, nullptr))) return EXIT_FAILURE; + _last_glfw_time = (float) glfwGetTime(); + center(); glfwSetWindowSizeCallback(getWindow(), App::onSize); @@ -152,10 +182,19 @@ int App::run() { init(); + _last_time = _time = 0; + manager[getWindow()] = this; while (!glfwWindowShouldClose(_window)) { + _glfw_time = (float) glfwGetTime(); + + _time += (_glfw_time - _last_glfw_time) * _rate; + display(); + _last_time = _time; + _last_glfw_time = _glfw_time; + glfwPollEvents(); }; manager.erase(getWindow()); diff --git a/glapp/src/main.cpp b/glapp/src/main.cpp index cf973ea..c180436 100644 --- a/glapp/src/main.cpp +++ b/glapp/src/main.cpp @@ -102,7 +102,7 @@ protected: glBindBuffer(GL_ARRAY_BUFFER, circle_vert_buf); util::bufferData(GL_ARRAY_BUFFER, vertices, GL_STATIC_DRAW); - program = util::buildProgram({ + program = util::buildProgram(false, { vertex_shader = util::buildShader("shaders/main.vert"), fragment_shader = util::buildShader("shaders/main.frag"), }); @@ -133,9 +133,7 @@ protected: int width, height; float ratio; - glfwGetFramebufferSize(getWindow(), &width, &height - - ); + glfwGetFramebufferSize(getWindow(), &width, &height); ratio = (float) width / height; glViewport(0, 0, width, height); @@ -143,7 +141,7 @@ protected: mats.proj = glm::ortho(-ratio, ratio, -1.f, 1.f); mats.view = glmutil::scale(glm::vec3(0.9f)) * glmutil::eulerAngles(glm::vec3(angles.y, 0, angles.x)); - mats.model = glmutil::rotation((float) glfwGetTime(), glm::vec3(0.0f, 0.0f, 1.0f)); + mats.model = glmutil::rotation(getTime(), glm::vec3(0.0f, 0.0f, 1.0f)); glBindBuffer(GL_UNIFORM_BUFFER, matrix_buffer); glBufferData(GL_UNIFORM_BUFFER, sizeof(Matrices), &mats, GL_DYNAMIC_DRAW); @@ -173,7 +171,6 @@ public: int main() { - GLApp - app = GLApp(); + GLApp app = GLApp(); app.launch(); } \ No newline at end of file