From 3f97f18d607dc120cfb19b41c08de51991568168 Mon Sep 17 00:00:00 2001 From: Eddie Breeg Date: Fri, 2 Jun 2023 17:22:09 -0400 Subject: [PATCH] Added toggle UI + fullscreen mode --- CMakeLists.txt | 2 +- README.md | 5 +++++ examples/noise.glsl | 28 ++++++++++++++------------- examples/voronoi.glsl | 15 ++++++++++++++- include/GLBase/GLBase.hpp | 6 +++++- main.cpp | 40 +++++++++++++++++++++++++++++++++++---- src/GLBase.cpp | 20 ++++++++++++++++++-- 7 files changed, 94 insertions(+), 22 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index fe0a741..f2f4001 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.0) -project(GLBase VERSION 0.0.1) +project(GLBase VERSION 1.1.0) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) diff --git a/README.md b/README.md index c04df22..ff8521f 100644 --- a/README.md +++ b/README.md @@ -53,6 +53,11 @@ In this section your can find the general setup of the program: - **Slider sensitivity**: How sensitive should the sliders be for the custom shader parameters - **Render pass**: Selects the output texture currently being displayed on screen +### View options + +UI can be toggled by pressing tab. Fullscreen mode can also be toggled by pressing F11. +Both options are accessible in the View menu, at the top of the screen when UI is visible. + ### Navigation To pan the view, simply click and drag. To zoom in and out, hold shift and click and drag to the right/left. diff --git a/examples/noise.glsl b/examples/noise.glsl index 0d45ffe..30b46b6 100644 --- a/examples/noise.glsl +++ b/examples/noise.glsl @@ -1,18 +1,20 @@ -float hash(vec4 x) { - vec4 p = vec4(19.474959781, 51.422209728, 57.450435988, 777.79154659); - return fract(9581.400139252703 * sin(dot(x, p))); - } -vec4 hash4(vec4 x){ - return vec4( - hash(x), - hash(vec4(x.y, x.z, x.w, x.x)), - hash(vec4(x.z, x.w, x.x, x.y)), - hash(vec4(x.w, x.x, x.y, x.z)) - ); +uvec3 pcg3d(uvec3 v) +{ + v = v * 1664525u + 1013904223u; + v.x += v.y*v.z; v.y += v.z*v.x; v.z += v.x*v.y; + v ^= v >> 16u; + v.x += v.y*v.z; v.y += v.z*v.x; v.z += v.x*v.y; + return v; +} + +vec3 hash(vec3 p){ + return pcg3d(floatBitsToUint(p)) / 4294967295.0; } void main() { - vec4 p = (scale*pos+offset)/scale; - frag0 = vec4(hash4(p).xyz, 1); + vec4 p = scale*pos+offset; + p.x *= res.x / res.y; + p = floor(p); + frag0 = vec4(hash(p.xyz), 1); } \ No newline at end of file diff --git a/examples/voronoi.glsl b/examples/voronoi.glsl index cd172a2..35fcd17 100644 --- a/examples/voronoi.glsl +++ b/examples/voronoi.glsl @@ -40,6 +40,19 @@ const vec3 offsets[] = { vec3(1, 1, 1), }; +uvec3 pcg3d(uvec3 v) +{ + v = v * 1664525u + 1013904223u; + v.x += v.y*v.z; v.y += v.z*v.x; v.z += v.x*v.y; + v ^= v >> 16u; + v.x += v.y*v.z; v.y += v.z*v.x; v.z += v.x*v.y; + return v; +} + +vec3 hash(vec3 p){ + return pcg3d(floatBitsToUint(p)) / 4294967295.0; +} + float voronoi(vec3 P, out vec4 outColor){ vec3 S = floor(P); vec3 F = fract(P); @@ -47,7 +60,7 @@ float voronoi(vec3 P, out vec4 outColor){ for(int i=0; i<27; ++i){ vec3 t = offsets[i]; vec3 cell = S+t; - vec3 p = randomness*texture(texNoise, cell.xy/1e3).xyz; + vec3 p = randomness*hash(cell); float r = chebichev(p+t - F); if(r < d){ d = r; diff --git a/include/GLBase/GLBase.hpp b/include/GLBase/GLBase.hpp index a6fbcd6..b7f10b4 100644 --- a/include/GLBase/GLBase.hpp +++ b/include/GLBase/GLBase.hpp @@ -15,14 +15,18 @@ namespace GLBase { void newFrame() const; std::pair _winSize; bool _winResized = false; + bool _isFullScreen = false; + const char *_title; void render(); protected: bool wasWindowResized() const; public: GLFWwindow *_window; std::pair windowSize() const { return _winSize; } - Application(int width, int height, const std::string_view& title, bool resizeable = false, bool maximized = false); + Application(int width, int height, const char * title, bool resizeable = false, bool maximized = false, + GLFWkeyfun keyCallback = nullptr); void run(); + void fullScreen(bool onOff); virtual bool processEvents(); virtual void update(std::chrono::duration delta) = 0; virtual void draw(const Renderer&) = 0; diff --git a/main.cpp b/main.cpp index 2000242..146f9c2 100644 --- a/main.cpp +++ b/main.cpp @@ -27,6 +27,8 @@ class GLExplorer: public GLBase::Application GLBase::Texture _textures[8]; GLBase::Texture _noise; + static GLExplorer* _instance; + int _selectedRenderPass = 0; static constexpr const char *_renderPasses[] = { "Pass 0", @@ -39,8 +41,9 @@ class GLExplorer: public GLBase::Application "Pass 7", }; - bool _showInspector = true; + bool _fullScreen = false; bool _vsync = 0; + bool _showUI = true; std::chrono::steady_clock::time_point _start; float _scale = 1.0f; int _mouseSensitivity = 4; @@ -51,13 +54,39 @@ class GLExplorer: public GLBase::Application struct {std::string message; bool errStatus = false; } _glslStatus; bool _saveFrame =false, _saveFrameStatus = true; std::vector _frameData; + bool processEvents() override { + glfwPollEvents(); + // if(glfwGetKey(_window, GLFW_KEY_TAB) == GLFW_PRESS) + // _showUI = !_showUI; + // if(glfwGetKey(_window, GLFW_KEY_F11) == GLFW_PRESS){ + // fullScreen(_fullScreen = !_fullScreen); + // } + return !glfwWindowShouldClose(_window); + } + static void keyCallback(GLFWwindow* window, int key, int scancode, int action, int mods){ + if(action != GLFW_PRESS) return; + // std::cout << "Key pressed\n"; + switch (key) + { + case GLFW_KEY_TAB: + _instance->_showUI = !_instance->_showUI; + break; + case GLFW_KEY_F11: + _instance->fullScreen(_instance->_fullScreen = !_instance->_fullScreen); + break; + default: + break; + } + } public: - GLExplorer(): GLBase::Application(800, 800, "GLSL Explorer", true, true), + GLExplorer(): GLBase::Application(800, 800, "GLSL Explorer", true, true, keyCallback), _vbo(nullptr, 3*sizeof(GLBase::Vector3), GL_STATIC_DRAW), _ibo(nullptr, 6, GL_STATIC_DRAW), _vao(), _shader(vertexShader, defaultFragShader), _renderShader(vertexShader, simpleTextureShader) { + if(_instance) return; + _instance = this; GLBase::Shader::setGLSLErrorCallback(onGLSLError, this); _start = std::chrono::steady_clock::now(); _vao.addBuffer(_vbo, GLBase::VertexLayout<1>( @@ -118,6 +147,7 @@ class GLExplorer: public GLBase::Application t.resize(size.first, size.second); _frameData.resize(size.first * size.second * 3); } + fullScreen(_fullScreen); _textures[_selectedRenderPass].bind(); userInputs(size, delta); glViewport(0, 0, size.first, size.second); @@ -223,6 +253,7 @@ class GLExplorer: public GLBase::Application app->_glslStatus.message = msg; } void updateUI() { + if(!_showUI) return; if(!_saveFrameStatus){ _saveFrameStatus = true; ImGui::Begin("Error", &_saveFrameStatus); @@ -231,7 +262,8 @@ class GLExplorer: public GLBase::Application } if(ImGui::BeginMainMenuBar()){ if(ImGui::BeginMenu("View")){ - ImGui::MenuItem("Show inspector", "Ctrl+1", &_showInspector); + ImGui::MenuItem("Show UI", "Tab", &_showUI); + ImGui::MenuItem("Fullscreen", "F11", &_fullScreen); ImGui::EndMenu(); } ImGui::EndMainMenuBar(); @@ -248,7 +280,6 @@ class GLExplorer: public GLBase::Application ImGui::End(); } - if(!_showInspector) return; ImGui::Begin("Inspector"); ImGui::Text("%f FPS", ImGui::GetIO().Framerate); if(ImGui::TreeNode("General settings")){ @@ -339,6 +370,7 @@ class GLExplorer: public GLBase::Application } ~GLExplorer() = default; }; +GLExplorer* GLExplorer::_instance = nullptr; int main(int argc, char const *argv[]) diff --git a/src/GLBase.cpp b/src/GLBase.cpp index 0f44b0d..7e0a515 100644 --- a/src/GLBase.cpp +++ b/src/GLBase.cpp @@ -5,7 +5,8 @@ #include namespace GLBase{ - Application::Application(int width, int height, const std::string_view& title, bool resizeable, bool maximized) + Application::Application(int width, int height, const char* title, bool resizeable, bool maximized, + GLFWkeyfun cbk) { /* inits glfw, OpenGL and ImGUI */ if(!glfwInit()){ @@ -13,6 +14,7 @@ namespace GLBase{ glfwGetError(&err); throw std::runtime_error(err); } + _title = title; glfwWindowHint(GLFW_RESIZABLE, resizeable); glfwWindowHint(GLFW_MAXIMIZED, maximized); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); @@ -20,7 +22,7 @@ namespace GLBase{ glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); _winSize = {width, height}; - _window = glfwCreateWindow(width, height, title.data(), NULL, NULL); + _window = glfwCreateWindow(width, height, title, NULL, NULL); if(!_window) { const char *err; glfwGetError(&err); @@ -29,6 +31,7 @@ namespace GLBase{ glfwMakeContextCurrent(_window); glfwSwapInterval(0); // Disable vsync + glfwSetKeyCallback(_window, cbk); auto err = glewInit(); if(err != GLEW_OK) throw std::runtime_error((const char*)glewGetErrorString(err)); @@ -72,6 +75,19 @@ namespace GLBase{ return !(glfwWindowShouldClose(_window)); } bool Application::wasWindowResized() const { return _winResized; } + void Application::fullScreen(bool onOff){ + if(_isFullScreen == onOff) return; + _isFullScreen = onOff; + if(!onOff){ + glfwSetWindowMonitor(_window, nullptr, 0, 0, _winSize.first, _winSize.second, GLFW_DONT_CARE); + glfwMaximizeWindow(_window); + glfwGetWindowSize(_window, &_winSize.first, &_winSize.second); + return; + } + auto screen = glfwGetPrimaryMonitor(); + auto mode = glfwGetVideoMode(screen); + glfwSetWindowMonitor(_window, screen, 0, 0, mode->width, mode->height, GLFW_DONT_CARE); + } void Application::run() { /* simple loop */ using std::chrono::steady_clock, std::chrono::duration;