diff --git a/CMakeLists.txt b/CMakeLists.txt index d17699fdc0bfc37000c343769f5f215e170349f9..526401edd27d286f50fa3d589c6929c353527d4a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -30,8 +30,11 @@ endif() add_subdirectory(qpong_core) include_directories(qpong_core) -# Dear ImGui based application -add_subdirectory(imgui_app) +# Dear ImGui and SDL based application +add_subdirectory(imgui_sdl_app) + +# Dear ImGui and GLFW based application +add_subdirectory(imgui_glfw_app) # Add dir with gtk qpong app add_subdirectory(gtk_qpong_app) diff --git a/README.md b/README.md index 44b8087c6c5e910c074e8287dea7cb8a002208aa..2a2e31e28f742baec3a3ada1a00a3f0fedbe4f60 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,10 @@ Dependencies: * cmake * libgtkmm-3.0-dev * libfftw3-dev + * libsdl2-dev + * libglfw3-dev + * libglm-dev + --- diff --git a/imgui_glfw_app/CMakeLists.txt b/imgui_glfw_app/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..a4bee75a9f5dbaa4b24df409505880d1a40b2a17 --- /dev/null +++ b/imgui_glfw_app/CMakeLists.txt @@ -0,0 +1,83 @@ + +# Dear ImGui include dirs +include_directories( + ../libs/imgui + ../libs/imgui/examples + ../libs/imgui/examples/libs/gl3w +) + +# Main Dear ImGui src files. +set( + dear_im_gui_srcs + ../libs/imgui/imgui.cpp + ../libs/imgui/imgui_draw.cpp + ../libs/imgui/imgui_widgets.cpp +) + +# Impl files from Dear ImGui. +set( + dear_im_gui_impl_srcs + ../libs/imgui/examples/imgui_impl_glfw.cpp + ../libs/imgui/examples/imgui_impl_opengl3.cpp +) + +# Dear ImGui lib +add_library( + dear_im_gui_glfw + ${dear_im_gui_srcs} + ${dear_im_gui_impl_srcs} + ../libs/imgui/examples/libs/gl3w/GL/gl3w.c +) + +# Application base on Dear ImGui +add_executable( + imgui_glfw_playground.app + imgui_glfw_playground.cpp + LoadShaders.cpp +) + +add_custom_command(TARGET imgui_glfw_playground.app PRE_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_directory + ${CMAKE_SOURCE_DIR}/imgui_glfw_app/shaders $<TARGET_FILE_DIR:imgui_glfw_playground.app>) + + +pkg_check_modules(GLFW glfw3) +include_directories(${GLFW_INCLUDE_DIRS}) +message(${GLFW_LIBRARIES}) + +# Link everything together +target_link_libraries( + imgui_glfw_playground.app + dear_im_gui_glfw + qpong_core + ${GLFW_LIBRARIES} +) + +# Include macOS specific things. +if(APPLE) + # dependencies for macOS + # brew install glfw + # brew install glm + find_library(COCOA_LIBRARY Cocoa REQUIRED) + find_library(IOKIT_LIBRARY IOKit REQUIRED) + find_library(COREVID_LIBRARY CoreVideo REQUIRED) + find_library(OPENGL_LIBRARY OpenGL REQUIRED) + + message(${COCOA_LIBRARY}) + message(${IOKIT_LIBRARY}) + message(${COREVID_LIBRARY}) + message(${OPENGL_LIBRARY}) + + target_link_libraries( + imgui_glfw_playground.app + ${COCOA_LIBRARY} + ${IOKIT_LIBRARY} + ${COREVID_LIBRARY} + ${OPENGL_LIBRARY} + ) +else(APPLE) + find_package(OpenGL REQUIRED) + target_link_libraries(imgui_glfw_playground.app OpenGL::GL ${CMAKE_DL_LIBS}) +endif() + + diff --git a/imgui_glfw_app/LoadShaders.cpp b/imgui_glfw_app/LoadShaders.cpp new file mode 100644 index 0000000000000000000000000000000000000000..36feb49be346efb6fc1d3146eca0a575df8af3b9 --- /dev/null +++ b/imgui_glfw_app/LoadShaders.cpp @@ -0,0 +1,96 @@ +#include "LoadShaders.hpp" + +#include <iostream> +#include <fstream> +#include <string> +#include <sstream> +#include <vector> +#include <GL/gl3w.h> + +unsigned int LoadShaders(const char * vertex_file_path,const char * fragment_file_path){ + + // Create the shaders + unsigned int VertexShaderID = glCreateShader(GL_VERTEX_SHADER); + unsigned int FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER); + + // Read the Vertex Shader code from the file + std::string VertexShaderCode; + std::ifstream VertexShaderStream(vertex_file_path, std::ios::in); + if(VertexShaderStream.is_open()){ + std::stringstream sstr; + sstr << VertexShaderStream.rdbuf(); + VertexShaderCode = sstr.str(); + VertexShaderStream.close(); + }else{ + printf("Impossible to open %s. Are you in the right directory ? Don't forget to read the FAQ !\n", vertex_file_path); + getchar(); + return 0; + } + + // Read the Fragment Shader code from the file + std::string FragmentShaderCode; + std::ifstream FragmentShaderStream(fragment_file_path, std::ios::in); + if(FragmentShaderStream.is_open()){ + std::stringstream sstr; + sstr << FragmentShaderStream.rdbuf(); + FragmentShaderCode = sstr.str(); + FragmentShaderStream.close(); + } + + GLint Result = GL_FALSE; + int InfoLogLength; + + // Compile Vertex Shader + printf("Compiling shader : %s\n", vertex_file_path); + char const * VertexSourcePointer = VertexShaderCode.c_str(); + glShaderSource(VertexShaderID, 1, &VertexSourcePointer , NULL); + glCompileShader(VertexShaderID); + + // Check Vertex Shader + glGetShaderiv(VertexShaderID, GL_COMPILE_STATUS, &Result); + glGetShaderiv(VertexShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength); + if ( InfoLogLength > 0 ){ + std::vector<char> VertexShaderErrorMessage(InfoLogLength+1); + glGetShaderInfoLog(VertexShaderID, InfoLogLength, NULL, &VertexShaderErrorMessage[0]); + printf("%s\n", &VertexShaderErrorMessage[0]); + } + + // Compile Fragment Shader + printf("Compiling shader : %s\n", fragment_file_path); + char const * FragmentSourcePointer = FragmentShaderCode.c_str(); + glShaderSource(FragmentShaderID, 1, &FragmentSourcePointer , NULL); + glCompileShader(FragmentShaderID); + + // Check Fragment Shader + glGetShaderiv(FragmentShaderID, GL_COMPILE_STATUS, &Result); + glGetShaderiv(FragmentShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength); + if ( InfoLogLength > 0 ){ + std::vector<char> FragmentShaderErrorMessage(InfoLogLength+1); + glGetShaderInfoLog(FragmentShaderID, InfoLogLength, NULL, &FragmentShaderErrorMessage[0]); + printf("%s\n", &FragmentShaderErrorMessage[0]); + } + + // Link the program + printf("Linking program\n"); + GLuint ProgramID = glCreateProgram(); + glAttachShader(ProgramID, VertexShaderID); + glAttachShader(ProgramID, FragmentShaderID); + glLinkProgram(ProgramID); + + // Check the program + glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result); + glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength); + if ( InfoLogLength > 0 ){ + std::vector<char> ProgramErrorMessage(InfoLogLength+1); + glGetProgramInfoLog(ProgramID, InfoLogLength, NULL, &ProgramErrorMessage[0]); + printf("%s\n", &ProgramErrorMessage[0]); + } + + glDetachShader(ProgramID, VertexShaderID); + glDetachShader(ProgramID, FragmentShaderID); + + glDeleteShader(VertexShaderID); + glDeleteShader(FragmentShaderID); + + return ProgramID; +} diff --git a/imgui_glfw_app/LoadShaders.hpp b/imgui_glfw_app/LoadShaders.hpp new file mode 100644 index 0000000000000000000000000000000000000000..69b61c6057829fd51044929d85afcddff800fa9b --- /dev/null +++ b/imgui_glfw_app/LoadShaders.hpp @@ -0,0 +1,7 @@ +/// @brief LoadShader from filesystem. +/// +/// @param vertex_file_path Path to the vertex shader file +/// @param fragment_file_path Path to the fragment shader file +/// @return Returns the id of the shader +/// +unsigned int LoadShaders(const char * vertex_file_path,const char * fragment_file_path); \ No newline at end of file diff --git a/imgui_glfw_app/imgui_glfw_playground.cpp b/imgui_glfw_app/imgui_glfw_playground.cpp new file mode 100644 index 0000000000000000000000000000000000000000..04a49d669852ba5eeb60941af78d776a0e975c6f --- /dev/null +++ b/imgui_glfw_app/imgui_glfw_playground.cpp @@ -0,0 +1,348 @@ +#include "imgui.h" +#include "imgui_impl_glfw.h" +#include "imgui_impl_opengl3.h" +#include <stdio.h> + +#include <GL/gl3w.h> // Initialize with gl3wInit() +#include <GLFW/glfw3.h> + +#include <iostream> + +#include "LoadShaders.hpp" +#include <glm/glm.hpp> +#include <glm/gtc/matrix_transform.hpp> + +static void glfw_error_callback(int error, const char* description) +{ + fprintf(stderr, "Glfw Error %d: %s\n", error, description); +} + +void drawGui() +{ + ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); + + static float f = 0.0f; + static int counter = 0; + + ImGui::Begin("Hello, world!"); // Create a window called "Hello, world!" and append into it. + + ImGui::Text("This is some useful text."); // Display some text (you can use a format strings too) + + ImGui::SliderFloat("float", &f, 0.0f, 1.0f); // Edit 1 float using a slider from 0.0f to 1.0f + ImGui::ColorEdit3("clear color", (float*)&clear_color); // Edit 3 floats representing a color + + if (ImGui::Button("Button")){ // Buttons return true when clicked (most widgets return true when edited/activated) + counter++; + } + ImGui::SameLine(); + ImGui::Text("counter = %d", counter); + + ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); + ImGui::End(); +} + +int main(int, char**) +{ + // Setup window + glfwSetErrorCallback(glfw_error_callback); + if (!glfwInit()) + return 1; + + // Decide GL+GLSL versions +#if __APPLE__ + // GL 3.2 + GLSL 150 + const char* glsl_version = "#version 150"; + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2); + glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // 3.2+ only + glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // Required on Mac +#else + // GL 3.0 + GLSL 130 + const char* glsl_version = "#version 130"; + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0); +#endif + + // Create window with graphics context + GLFWwindow* window = glfwCreateWindow(1280, 720, "Dear ImGui GLFW+OpenGL3 example", NULL, NULL); + if (window == NULL) + return 1; + glfwMakeContextCurrent(window); + glfwSwapInterval(1); // Enable vsync + + // Initialize OpenGL loader + bool err = gl3wInit() != 0; + if (err) + { + fprintf(stderr, "Failed to initialize OpenGL loader!\n"); + return 1; + } + + // Setup Dear ImGui context + IMGUI_CHECKVERSION(); + ImGui::CreateContext(); + ImGuiIO& io = ImGui::GetIO(); (void)io; + + // Setup Dear ImGui style + ImGui::StyleColorsDark(); + + // Setup Platform/Renderer bindings + ImGui_ImplGlfw_InitForOpenGL(window, true); + ImGui_ImplOpenGL3_Init(glsl_version); + + + // unsigned int vertexArrayId {}; // Store a vertex array id. + // glGenVertexArrays(1, &vertexArrayId); // Receive a id. + // glBindVertexArray(vertexArrayId); // Bind that id. + + static const float g_vertex_buffer_data_triangle[] = { + -1.0f, -1.0f, 0.0f, + 1.0f, -1.0f, 0.0f, + 0.0f, 1.0f, 0.0f, + }; + + static GLfloat g_color_buffer_data_triangle[12*3*3]; + for (int v = 0; v < 12*3 ; v++){ + g_color_buffer_data_triangle[3*v+0] = 0.1f; + g_color_buffer_data_triangle[3*v+1] = 0.5f; + g_color_buffer_data_triangle[3*v+2] = 0.7f; + } + + static const GLfloat g_vertex_buffer_data_cube[] = { + -1.0f,-1.0f,-1.0f, // triangle 1 : begin + -1.0f,-1.0f, 1.0f, + -1.0f, 1.0f, 1.0f, // triangle 1 : end + 1.0f, 1.0f,-1.0f, // triangle 2 : begin + -1.0f,-1.0f,-1.0f, + -1.0f, 1.0f,-1.0f, // triangle 2 : end + 1.0f,-1.0f, 1.0f, + -1.0f,-1.0f,-1.0f, + 1.0f,-1.0f,-1.0f, + 1.0f, 1.0f,-1.0f, + 1.0f,-1.0f,-1.0f, + -1.0f,-1.0f,-1.0f, + -1.0f,-1.0f,-1.0f, + -1.0f, 1.0f, 1.0f, + -1.0f, 1.0f,-1.0f, + 1.0f,-1.0f, 1.0f, + -1.0f,-1.0f, 1.0f, + -1.0f,-1.0f,-1.0f, + -1.0f, 1.0f, 1.0f, + -1.0f,-1.0f, 1.0f, + 1.0f,-1.0f, 1.0f, + 1.0f, 1.0f, 1.0f, + 1.0f,-1.0f,-1.0f, + 1.0f, 1.0f,-1.0f, + 1.0f,-1.0f,-1.0f, + 1.0f, 1.0f, 1.0f, + 1.0f,-1.0f, 1.0f, + 1.0f, 1.0f, 1.0f, + 1.0f, 1.0f,-1.0f, + -1.0f, 1.0f,-1.0f, + 1.0f, 1.0f, 1.0f, + -1.0f, 1.0f,-1.0f, + -1.0f, 1.0f, 1.0f, + 1.0f, 1.0f, 1.0f, + -1.0f, 1.0f, 1.0f, + 1.0f,-1.0f, 1.0f +}; + +static const GLfloat g_color_buffer_data_cube[] = { + 0.583f, 0.771f, 0.014f, + 0.609f, 0.115f, 0.436f, + 0.327f, 0.483f, 0.844f, + 0.822f, 0.569f, 0.201f, + 0.435f, 0.602f, 0.223f, + 0.310f, 0.747f, 0.185f, + 0.597f, 0.770f, 0.761f, + 0.559f, 0.436f, 0.730f, + 0.359f, 0.583f, 0.152f, + 0.483f, 0.596f, 0.789f, + 0.559f, 0.861f, 0.639f, + 0.195f, 0.548f, 0.859f, + 0.014f, 0.184f, 0.576f, + 0.771f, 0.328f, 0.970f, + 0.406f, 0.615f, 0.116f, + 0.676f, 0.977f, 0.133f, + 0.971f, 0.572f, 0.833f, + 0.140f, 0.616f, 0.489f, + 0.997f, 0.513f, 0.064f, + 0.945f, 0.719f, 0.592f, + 0.543f, 0.021f, 0.978f, + 0.279f, 0.317f, 0.505f, + 0.167f, 0.620f, 0.077f, + 0.347f, 0.857f, 0.137f, + 0.055f, 0.953f, 0.042f, + 0.714f, 0.505f, 0.345f, + 0.783f, 0.290f, 0.734f, + 0.722f, 0.645f, 0.174f, + 0.302f, 0.455f, 0.848f, + 0.225f, 0.587f, 0.040f, + 0.517f, 0.713f, 0.338f, + 0.053f, 0.959f, 0.120f, + 0.393f, 0.621f, 0.362f, + 0.673f, 0.211f, 0.457f, + 0.820f, 0.883f, 0.371f, + 0.982f, 0.099f, 0.879f +}; + + unsigned int vertexBufferCube {}; + glGenBuffers(1, &vertexBufferCube); + glBindBuffer(GL_ARRAY_BUFFER, vertexBufferCube); + glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data_cube), g_vertex_buffer_data_cube, GL_STATIC_DRAW); + + unsigned int colorBufferCube {}; + glGenBuffers(1, &colorBufferCube); + glBindBuffer(GL_ARRAY_BUFFER, colorBufferCube); + glBufferData(GL_ARRAY_BUFFER, sizeof(g_color_buffer_data_cube), g_color_buffer_data_cube, GL_STATIC_DRAW); + + unsigned int vertexBufferTriangle {}; + glGenBuffers(1, &vertexBufferTriangle); + glBindBuffer(GL_ARRAY_BUFFER, vertexBufferTriangle); + glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data_triangle), g_vertex_buffer_data_triangle, GL_STATIC_DRAW); + + unsigned int colorBufferTriangle {}; + glGenBuffers(1, &colorBufferTriangle); + glBindBuffer(GL_ARRAY_BUFFER, colorBufferTriangle); + glBufferData(GL_ARRAY_BUFFER, sizeof(g_color_buffer_data_triangle), g_color_buffer_data_triangle, GL_STATIC_DRAW); + + unsigned int shaderId = LoadShaders("SimpleVertexShader.glsl", "FragmentShader.glsl"); + + glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_LESS); + + + int width, height; + glfwGetFramebufferSize(window, &width, &height); + + // Projection matrix : 45° Field of View, 4:3 ratio, display range : 0.1 unit <-> 100 units + glm::mat4 Projection = glm::perspective(glm::radians(150.0f), (float) width / (float)height, 0.1f, 100.0f); + glm::mat4 ProjectionTriangle = glm::perspective(glm::radians(30.0f), (float) width / (float)height, 0.1f, 100.0f); + + // Camera matrix + glm::mat4 View = glm::lookAt( + glm::vec3(4,3,3), // Camera is at (4,3,3), in World Space + glm::vec3(0,0,0), // and looks at the origin + glm::vec3(0,1,0) // Head is up (set to 0,-1,0 to look upside-down) + ); + + // Model matrix : an identity matrix (model will be at the origin) + glm::mat4 Model = glm::mat4(1.0f); + // Our ModelViewProjection : multiplication of our 3 matrices + glm::mat4 mvp = Projection * View * Model; // Remember, matrix multiplication is the other way around + glm::mat4 mvpTriangle = ProjectionTriangle * View * Model; + + // Get a handle for our "MVP" uniform + // Only during the initialisation + // GLuint MatrixID = glGetUniformLocation(shaderId, "MVP"); + // GLuint MatrixIDT = glGetUniformLocation(shaderId, "MVPT"); + + + unsigned int MatrixIDCube = glGetUniformLocation(shaderId, "MVP"); + unsigned int MatrixIDTriangle = glGetUniformLocation(shaderId, "MVPT"); + + // Main loop + while (!glfwWindowShouldClose(window)) + { + glfwPollEvents(); + + // Start the Dear ImGui frame + ImGui_ImplOpenGL3_NewFrame(); + ImGui_ImplGlfw_NewFrame(); + ImGui::NewFrame(); + + // Draw GUI with Dear ImGui. + drawGui(); + + // Rendering + ImGui::Render(); + { + // int width, height; + glfwGetFramebufferSize(window, &width, &height); + glViewport(0, 0, width, height); + glClearColor(0.1f, 0.2f, 0.2f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + // Send our transformation to the currently bound shader, in the "MVP" uniform + // This is done in the main loop since each model will have a different MVP matrix (At least for the M part) + glUniformMatrix4fv(MatrixIDCube, 1, GL_FALSE, &mvp[0][0]); + glUseProgram(shaderId); + + glEnableVertexAttribArray(0); + glBindBuffer(GL_ARRAY_BUFFER, vertexBufferCube); + glVertexAttribPointer( + 0, + 3, + GL_FLOAT, + GL_FALSE, + 0, + (void*)0 + ); + + glEnableVertexAttribArray(1); + glBindBuffer(GL_ARRAY_BUFFER, colorBufferCube); + glVertexAttribPointer( + 1, + 3, + GL_FLOAT, + GL_FALSE, + 0, + (void*)0 + ); + + // glUniformMatrix4fv(MatrixIDCube, 1, GL_FALSE, &mvp[0][0]); + glDrawArrays(GL_TRIANGLES, 0, sizeof(g_vertex_buffer_data_cube)/3); + + + // glDisableVertexAttribArray(0); + // glDisableVertexAttribArray(1); + + + // glUniformMatrix4fv(MatrixIDTriangle, 1, GL_FALSE, &mvpTriangle[0][0]); + // glUseProgram(shaderId); + // glEnableVertexAttribArray(0); + + // glBindBuffer(GL_ARRAY_BUFFER, vertexBufferTriangle); + // glVertexAttribPointer( + // 0, + // 3, + // GL_FLOAT, + // GL_FALSE, + // 0, + // (void*)0 + // ); + // glEnableVertexAttribArray(1); + + // glBindBuffer(GL_ARRAY_BUFFER, colorBufferTriangle); + // glVertexAttribPointer( + // 1, + // 3, + // GL_FLOAT, + // GL_FALSE, + // 0, + // (void*)0 + // ); + + + // glDrawArrays(GL_TRIANGLES, 0, sizeof(g_vertex_buffer_data_triangle)/3); + + glDisableVertexAttribArray(0); + glDisableVertexAttribArray(1); + + } + + + ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); + glfwSwapBuffers(window); + } + + // Cleanup + ImGui_ImplOpenGL3_Shutdown(); + ImGui_ImplGlfw_Shutdown(); + ImGui::DestroyContext(); + + glfwDestroyWindow(window); + glfwTerminate(); + + return 0; +} diff --git a/imgui_glfw_app/shaders/FragmentShader.glsl b/imgui_glfw_app/shaders/FragmentShader.glsl new file mode 100644 index 0000000000000000000000000000000000000000..9ed28d89d28b442abbc3d598478d388a6f079368 --- /dev/null +++ b/imgui_glfw_app/shaders/FragmentShader.glsl @@ -0,0 +1,8 @@ +#version 330 + +in vec3 fragmentColor; +out vec3 outColor; + +void main(){ + outColor = fragmentColor; +} \ No newline at end of file diff --git a/imgui_glfw_app/shaders/SimpleVertexShader.glsl b/imgui_glfw_app/shaders/SimpleVertexShader.glsl new file mode 100644 index 0000000000000000000000000000000000000000..0aca2dff189585b9a085795aaca380f0e09d5840 --- /dev/null +++ b/imgui_glfw_app/shaders/SimpleVertexShader.glsl @@ -0,0 +1,13 @@ +#version 330 core + +layout(location = 0) in vec3 vertexPosition_modelspace; +layout(location = 1) in vec3 vertexColor; + +out vec3 fragmentColor; + +uniform mat4 MVP; + +void main(){ + gl_Position = MVP * vec4(vertexPosition_modelspace, 1); + fragmentColor = vertexColor; +} \ No newline at end of file diff --git a/imgui_app/CMakeLists.txt b/imgui_sdl_app/CMakeLists.txt similarity index 94% rename from imgui_app/CMakeLists.txt rename to imgui_sdl_app/CMakeLists.txt index 5ca9d7039b12694e85a549ca2b3b2ffe013ca315..dcbb8a88737022b7db925014fefb72f172e8610d 100644 --- a/imgui_app/CMakeLists.txt +++ b/imgui_sdl_app/CMakeLists.txt @@ -1,6 +1,4 @@ -add_definitions(-DIMGUI_IMPL_OPENGL_LOADER_GL3W) # Define OpenGL loader for Dear ImGui - # Dear ImGui include dirs include_directories( ../libs/imgui diff --git a/imgui_app/imgui_playground.cpp b/imgui_sdl_app/imgui_playground.cpp similarity index 50% rename from imgui_app/imgui_playground.cpp rename to imgui_sdl_app/imgui_playground.cpp index 35ecb27c614ec5d5e4c1dd1fdf6fb21b3d26c78d..368f3688f0e639af6fda713c6b7547366227239d 100644 --- a/imgui_app/imgui_playground.cpp +++ b/imgui_sdl_app/imgui_playground.cpp @@ -3,74 +3,127 @@ /// @brief Working example for Dear ImGui with OpenGL3 and SDL2 /// +#include<iostream> + +#include <SDL.h> +#include <GL/gl3w.h> + #include "imgui.h" #include "imgui_impl_sdl.h" #include "imgui_impl_opengl3.h" -#include <stdio.h> -#include <SDL.h> -#if defined(IMGUI_IMPL_OPENGL_LOADER_GL3W) -#include <GL/gl3w.h> -#endif + +void setSdlGlAttributesApple() +{ + SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG); // Always required on Mac + SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2); +} + +void setSdlGlAttributesLinux() +{ + SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, 0); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); +} + +void setSdlGlAttributesCommon() +{ + // Create window with graphics context + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); + SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); + SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8); +} + +#include <vector> +#include "ImageBuffer.hpp" +const std::vector<QPong::QColor> colors { + {0.3f, 0.2f, 0.4f}, + {0.3f, 0.2f, 0.4f}, + {0.3f, 0.2f, 0.4f}, + {0.3f, 0.2f, 0.4f}, + {0.3f, 0.2f, 0.4f}, + {0.3f, 0.2f, 0.4f}, + {0.3f, 0.2f, 0.4f}, + {0.3f, 0.2f, 0.4f}, + {0.3f, 0.2f, 0.4f}, + {0.3f, 0.2f, 0.4f}, + {0.3f, 0.2f, 0.4f}, + {0.3f, 0.2f, 0.4f}, + {0.3f, 0.2f, 0.4f}, + {0.3f, 0.2f, 0.4f}, + {0.3f, 0.2f, 0.4f}, + {0.3f, 0.2f, 0.4f}, + {0.3f, 0.2f, 0.4f}, + {0.3f, 0.2f, 0.4f}, + {0.3f, 0.2f, 0.4f}, + {0.3f, 0.2f, 0.4f}, + {0.3f, 0.2f, 0.4f} +}; + +const std::vector<ImVec2> positions { + {0.0f, 0.0f}, + {0.1f, 0.0f}, + {0.2f, 0.0f}, + {0.3f, 0.0f}, + {0.4f, 0.0f}, + {0.5f, 0.0f}, + {0.6f, 0.0f}, + {0.7f, 0.0f}, + {0.8f, 0.0f}, + {0.9f, 0.0f}, + {0.0f, 0.1f}, + {0.0f, 0.2f}, + {0.0f, 0.3f}, + {0.0f, 0.4f}, + {0.0f, 0.5f}, + {0.0f, 0.6f}, + {0.0f, 0.7f}, + {0.0f, 0.8f}, + {0.0f, 0.9f}, + {0.0f, 0.9f}, + {0.5f, 0.5f} +}; + +void displayPoints() +{ +} int main(void) { if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_GAMECONTROLLER) != 0) { - printf("Error: %s\n", SDL_GetError()); + std::cerr << "Error: " << SDL_GetError() << '\n'; return -1; } - // Decide GL+GLSL versions #if __APPLE__ // GL 3.2 Core + GLSL 150 const char* glsl_version = "#version 150"; - SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG); // Always required on Mac - SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2); + setSdlGlAttributesApple(); #else // GL 3.0 + GLSL 130 const char* glsl_version = "#version 130"; - SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, 0); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0); + setSdlGlAttributesLinux(); #endif + setSdlGlAttributesCommon(); - // Create window with graphics context - SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); - SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); - SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8); - SDL_WindowFlags window_flags = (SDL_WindowFlags)(SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI); + SDL_WindowFlags window_flags = static_cast<SDL_WindowFlags>(SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI); SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL2+OpenGL3 example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, window_flags); SDL_GLContext gl_context = SDL_GL_CreateContext(window); SDL_GL_MakeCurrent(window, gl_context); SDL_GL_SetSwapInterval(1); // Enable vsync // Initialize OpenGL loader - #if defined(IMGUI_IMPL_OPENGL_LOADER_GL3W) - bool err = gl3wInit() != 0; - #elif defined(IMGUI_IMPL_OPENGL_LOADER_GLEW) - bool err = glewInit() != GLEW_OK; - #elif defined(IMGUI_IMPL_OPENGL_LOADER_GLAD) - bool err = gladLoadGL() == 0; - #elif defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING2) - bool err = false; - glbinding::Binding::initialize(); - #elif defined(IMGUI_IMPL_OPENGL_LOADER_GLBINDING3) - bool err = false; - glbinding::initialize([](const char* name) { return (glbinding::ProcAddress)SDL_GL_GetProcAddress(name); }); - #else - bool err = false; // If you use IMGUI_IMPL_OPENGL_LOADER_CUSTOM, your loader is likely to requires some form of initialization. - #endif - if (err) - { - fprintf(stderr, "Failed to initialize OpenGL loader!\n"); - return 1; - } + if (gl3wInit() != 0) + { + std::cerr << "Failed to initialize OpenGL loader!\n"; + return 1; + } IMGUI_CHECKVERSION(); ImGui::CreateContext(); @@ -79,50 +132,52 @@ int main(void) ImGui_ImplSDL2_InitForOpenGL(window, gl_context); ImGui_ImplOpenGL3_Init(glsl_version); - ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); bool done = false; while (!done) { - SDL_Event event; + SDL_Event event {}; while (SDL_PollEvent(&event)) { ImGui_ImplSDL2_ProcessEvent(&event); - if (event.type == SDL_QUIT) + if (event.type == SDL_QUIT){ done = true; - if (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_CLOSE && event.window.windowID == SDL_GetWindowID(window)) + } + else if (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_CLOSE && event.window.windowID == SDL_GetWindowID(window)){ done = true; + } } ImGui_ImplOpenGL3_NewFrame(); ImGui_ImplSDL2_NewFrame(window); ImGui::NewFrame(); - { + { // Config GUI static float f = 0.0f; static int counter = 0; ImGui::Begin("Hello, world!"); // Create a window called "Hello, world!" and append into it. - ImGui::Text("This is some useful text."); // Display some text (you can use a format strings too) - ImGui::SliderFloat("float", &f, 0.0f, 1.0f); // Edit 1 float using a slider from 0.0f to 1.0f ImGui::ColorEdit3("clear color", (float*)&clear_color); // Edit 3 floats representing a color - - if (ImGui::Button("Button")) // Buttons return true when clicked (most widgets return true when edited/activated) + if (ImGui::Button("Button")){ // Buttons return true when clicked (most widgets return true when edited/activated) counter++; + } ImGui::SameLine(); ImGui::Text("counter = %d", counter); - ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); ImGui::End(); } - // Rendering + // Rendering ImGui::Render(); - glViewport(0, 0, (int)io.DisplaySize.x, (int)io.DisplaySize.y); - glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w); - glClear(GL_COLOR_BUFFER_BIT); + + { // own OpenGL code goes here like this background clearing. + glViewport(0, 0, (int)io.DisplaySize.x, (int)io.DisplaySize.y); + glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w); + glClear(GL_COLOR_BUFFER_BIT); + } + ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); SDL_GL_SwapWindow(window); } @@ -135,6 +190,5 @@ int main(void) SDL_DestroyWindow(window); SDL_Quit(); - return 0; } \ No newline at end of file diff --git a/qpong_core/ImageBuffer.cpp b/qpong_core/ImageBuffer.cpp index b4a524b9b65cb2edcd870e0871c34c8e87511aed..7f4aa82e1f47955290c5c61b392e216b91f431c2 100644 --- a/qpong_core/ImageBuffer.cpp +++ b/qpong_core/ImageBuffer.cpp @@ -24,29 +24,26 @@ void ImageBuffer::updateAt(unsigned index, std::complex<double> v, double obs) const QColor ImageBuffer::getValue(unsigned index) { std::complex<double> val = m_complexBuffer[index]; - double r = real(val); - double i = imag(val); - double obs = m_potbuf[index]; + double r {real(val)}; + double i {imag(val)}; + double obs {m_potbuf[index]}; QColor c { - static_cast<float>(obs + r*r), //< red - static_cast<float>(r*r + i*i + obs/1.5), //< green - static_cast<float>(i*i) //< blue + static_cast<float>(obs + r*r), // red + static_cast<float>(r*r + i*i + obs/1.5f), // green + static_cast<float>(i*i) // blue }; constexpr double max = 0.81; - if (c.r > max) - { + if (c.r > max){ c.r = max; } - if (c.g > max) - { + if (c.g > max){ c.g = max; } - if (c.b > max) - { + if (c.b > max){ c.b = max; } return c;