pain
This commit is contained in:
		
							
								
								
									
										45
									
								
								include/graphics.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								include/graphics.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,45 @@
 | 
			
		||||
#ifndef GRAPHICS_HPP
 | 
			
		||||
#define GRAPHICS_HPP
 | 
			
		||||
#define GL_GLEXT_PROTOTYPES
 | 
			
		||||
 | 
			
		||||
// Includes
 | 
			
		||||
#include "imgui.h"
 | 
			
		||||
#include "imgui_impl_sdl3.h"
 | 
			
		||||
#include "imgui_impl_opengl3.h"
 | 
			
		||||
#include <SDL3/SDL_opengl.h>
 | 
			
		||||
#include "window.hpp"
 | 
			
		||||
 | 
			
		||||
// Constants
 | 
			
		||||
const int open_gl_major_version = 3;
 | 
			
		||||
const int open_gl_minor_version = 3;
 | 
			
		||||
const int enable_vsync = 1;
 | 
			
		||||
 | 
			
		||||
// Variables
 | 
			
		||||
extern Uint32 last_time;
 | 
			
		||||
extern Uint32 current_time;
 | 
			
		||||
extern float frame_time;
 | 
			
		||||
extern float fps;
 | 
			
		||||
extern float frame_time_graph[100];
 | 
			
		||||
extern SDL_GLContext gl_context;
 | 
			
		||||
 | 
			
		||||
extern ImGuiIO& io;
 | 
			
		||||
extern ImGuiStyle& style;
 | 
			
		||||
 | 
			
		||||
// Functions
 | 
			
		||||
int initialize_opengl();
 | 
			
		||||
void cleanup_opengl();
 | 
			
		||||
 | 
			
		||||
// ImGui
 | 
			
		||||
int initialize_imgui();
 | 
			
		||||
void cleanup_imgui();
 | 
			
		||||
void new_frame_imgui();
 | 
			
		||||
void frame_time_ui();
 | 
			
		||||
 | 
			
		||||
// Frame time calculation
 | 
			
		||||
void calc_frame_time();
 | 
			
		||||
 | 
			
		||||
// Shader management
 | 
			
		||||
unsigned int compile_shader(const char* shader_source, GLenum shader_type);
 | 
			
		||||
unsigned int create_program(unsigned int vertex_shader, unsigned int fragment_shader);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@@ -1,44 +1,16 @@
 | 
			
		||||
#ifndef MAIN_HPP
 | 
			
		||||
#define MAIN_HPP
 | 
			
		||||
 | 
			
		||||
// ImGui
 | 
			
		||||
#include "imgui.h"
 | 
			
		||||
#include "imgui_impl_sdl3.h"
 | 
			
		||||
#include "imgui_impl_opengl3.h"
 | 
			
		||||
 | 
			
		||||
// SDL3 and OpenGL
 | 
			
		||||
#include <SDL3/SDL.h>
 | 
			
		||||
#include <SDL3/SDL_opengl.h>
 | 
			
		||||
 | 
			
		||||
// C++ Standard Library
 | 
			
		||||
// Includes
 | 
			
		||||
#include <iostream>
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <vector>
 | 
			
		||||
 | 
			
		||||
// Structs
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#include "window.hpp"
 | 
			
		||||
#include "graphics.hpp"
 | 
			
		||||
#include "utils.hpp"
 | 
			
		||||
 | 
			
		||||
// Variables
 | 
			
		||||
int window_width = 1920;
 | 
			
		||||
int window_height = 1080;
 | 
			
		||||
 | 
			
		||||
float main_scale;
 | 
			
		||||
SDL_WindowFlags window_flags = SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIDDEN | SDL_WINDOW_HIGH_PIXEL_DENSITY;
 | 
			
		||||
SDL_Window* window;
 | 
			
		||||
 | 
			
		||||
bool running;
 | 
			
		||||
SDL_Event event;
 | 
			
		||||
 | 
			
		||||
Uint32 last_time;
 | 
			
		||||
Uint32 current_time;
 | 
			
		||||
float frame_time;
 | 
			
		||||
float fps;
 | 
			
		||||
float frame_time_graph[100] = {0.0f};
 | 
			
		||||
extern bool running;
 | 
			
		||||
 | 
			
		||||
// Functions
 | 
			
		||||
int main(int argc, char* argv[]);
 | 
			
		||||
int initialize();
 | 
			
		||||
void cleanup();
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										11
									
								
								include/utils.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								include/utils.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,11 @@
 | 
			
		||||
#ifndef UTILS_HPP
 | 
			
		||||
#define UTILS_HPP
 | 
			
		||||
 | 
			
		||||
// Includes
 | 
			
		||||
#include <fstream>
 | 
			
		||||
#include <iostream>
 | 
			
		||||
 | 
			
		||||
// Function
 | 
			
		||||
char* read_file(const char* file_path);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										22
									
								
								include/window.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								include/window.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,22 @@
 | 
			
		||||
#ifndef WINDOW_HPP
 | 
			
		||||
#define WINDOW_HPP
 | 
			
		||||
 | 
			
		||||
// Includes
 | 
			
		||||
#include "iostream"
 | 
			
		||||
#include <SDL3/SDL.h>
 | 
			
		||||
 | 
			
		||||
// Constants
 | 
			
		||||
const int window_width = 800;
 | 
			
		||||
const int window_height = 600;
 | 
			
		||||
 | 
			
		||||
// Variables
 | 
			
		||||
const SDL_WindowFlags window_flags = SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIDDEN | SDL_WINDOW_HIGH_PIXEL_DENSITY;
 | 
			
		||||
extern float main_scale;
 | 
			
		||||
extern SDL_Window* window;
 | 
			
		||||
extern SDL_Event event;
 | 
			
		||||
 | 
			
		||||
// Functions
 | 
			
		||||
int initialize_sdl();
 | 
			
		||||
void cleanup_sdl();
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										8
									
								
								shaders/triangle.frag
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								shaders/triangle.frag
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,8 @@
 | 
			
		||||
#version 330 core
 | 
			
		||||
 | 
			
		||||
out vec4 FragColor;
 | 
			
		||||
in vec3 color; // Input color from the vertex shader
 | 
			
		||||
 | 
			
		||||
void main() {
 | 
			
		||||
    FragColor = vec4(color, 1.0); // Set the fragment color to the input color
 | 
			
		||||
} 
 | 
			
		||||
							
								
								
									
										9
									
								
								shaders/triangle.vert
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								shaders/triangle.vert
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
			
		||||
#version 330 core
 | 
			
		||||
 | 
			
		||||
layout(location = 0) in vec3 position; // Vertex position
 | 
			
		||||
out vec3 color; // Output color to the fragment shader
 | 
			
		||||
 | 
			
		||||
void main() {
 | 
			
		||||
    gl_Position = vec4(position, 1.0); // Set the position of the vertex
 | 
			
		||||
    color = position + vec3(0.5); // Set the color based on the vertex position
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										158
									
								
								src/graphics.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										158
									
								
								src/graphics.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,158 @@
 | 
			
		||||
#include "graphics.hpp"
 | 
			
		||||
 | 
			
		||||
// Variables
 | 
			
		||||
Uint32 last_time;
 | 
			
		||||
Uint32 current_time;
 | 
			
		||||
float frame_time;
 | 
			
		||||
float fps;
 | 
			
		||||
float frame_time_graph[100];
 | 
			
		||||
 | 
			
		||||
SDL_GLContext gl_context;
 | 
			
		||||
 | 
			
		||||
// Functions
 | 
			
		||||
int initialize_opengl() {
 | 
			
		||||
    // Initialize OpenGL
 | 
			
		||||
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, open_gl_major_version);
 | 
			
		||||
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, open_gl_minor_version);
 | 
			
		||||
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
 | 
			
		||||
 | 
			
		||||
    // Initialize OpenGL context
 | 
			
		||||
    gl_context = SDL_GL_CreateContext(window);
 | 
			
		||||
    if (!gl_context) {
 | 
			
		||||
        std::cerr << "OpenGL context could not be created! SDL_Error: " << SDL_GetError() << std::endl;
 | 
			
		||||
        return 1; // OpenGL context creation failed
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Initialize OpenGL settings for the window
 | 
			
		||||
    SDL_GL_MakeCurrent(window, gl_context);
 | 
			
		||||
    SDL_GL_SetSwapInterval(enable_vsync);
 | 
			
		||||
    SDL_SetWindowPosition(window, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
 | 
			
		||||
    SDL_ShowWindow(window);
 | 
			
		||||
 | 
			
		||||
    glViewport(0, 0, (int)(window_width * main_scale), (int)(window_height * main_scale));
 | 
			
		||||
 | 
			
		||||
    return 0; // OpenGL initialization successful
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cleanup_opengl() {
 | 
			
		||||
    // Destroy OpenGL context
 | 
			
		||||
    if (gl_context) {
 | 
			
		||||
        SDL_GL_MakeCurrent(NULL, NULL);
 | 
			
		||||
        SDL_GL_DestroyContext(gl_context);
 | 
			
		||||
        gl_context = nullptr;
 | 
			
		||||
    }
 | 
			
		||||
    std::cout << "OpenGL cleanup successful." << std::endl;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
unsigned int compile_shader(const char* shader_source, GLenum shader_type) {
 | 
			
		||||
    unsigned int shader = glCreateShader(shader_type);
 | 
			
		||||
    if (shader == 0) {
 | 
			
		||||
        std::cerr << "Failed to create shader." << std::endl;
 | 
			
		||||
        return 0; // Shader creation failed
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    glShaderSource(shader, 1, &shader_source, nullptr);
 | 
			
		||||
    glCompileShader(shader);
 | 
			
		||||
 | 
			
		||||
    // Check for compilation errors
 | 
			
		||||
    int success;
 | 
			
		||||
    glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
 | 
			
		||||
    if (!success) {
 | 
			
		||||
        char info_log[512];
 | 
			
		||||
        glGetShaderInfoLog(shader, sizeof(info_log), nullptr, info_log);
 | 
			
		||||
        std::cerr << "Shader compilation error: " << info_log << std::endl;
 | 
			
		||||
        glDeleteShader(shader);
 | 
			
		||||
        return 0; // Shader compilation failed
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return shader; // Shader compiled successfully
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
unsigned int create_program(unsigned int vertex_shader, unsigned int fragment_shader) {
 | 
			
		||||
    unsigned int program = glCreateProgram();
 | 
			
		||||
    if (program == 0) {
 | 
			
		||||
        std::cerr << "Failed to create shader program." << std::endl;
 | 
			
		||||
        return 0; // Program creation failed
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    glAttachShader(program, vertex_shader);
 | 
			
		||||
    glAttachShader(program, fragment_shader);
 | 
			
		||||
    glLinkProgram(program);
 | 
			
		||||
 | 
			
		||||
    // Check for linking errors
 | 
			
		||||
    int success;
 | 
			
		||||
    glGetProgramiv(program, GL_LINK_STATUS, &success);
 | 
			
		||||
    if (!success) {
 | 
			
		||||
        char info_log[512];
 | 
			
		||||
        glGetProgramInfoLog(program, sizeof(info_log), nullptr, info_log);
 | 
			
		||||
        std::cerr << "Shader program linking error: " << info_log << std::endl;
 | 
			
		||||
        glDeleteProgram(program);
 | 
			
		||||
        return 0; // Program linking failed
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return program; // Program created successfully
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int initialize_imgui() {
 | 
			
		||||
    IMGUI_CHECKVERSION();
 | 
			
		||||
    ImGui::CreateContext();
 | 
			
		||||
    ImGuiIO& io = ImGui::GetIO(); (void)io;
 | 
			
		||||
    io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
 | 
			
		||||
    io.ConfigFlags |= ImGuiConfigFlags_DockingEnable;
 | 
			
		||||
 | 
			
		||||
    ImGui::StyleColorsDark();
 | 
			
		||||
    ImGuiStyle& style = ImGui::GetStyle();
 | 
			
		||||
    style.ScaleAllSizes(main_scale);
 | 
			
		||||
    style.FontScaleDpi = main_scale;
 | 
			
		||||
 | 
			
		||||
    if (!ImGui_ImplSDL3_InitForOpenGL(window, gl_context)) {
 | 
			
		||||
        std::cerr << "ImGui_ImplSDL3_InitForOpenGL failed!" << std::endl;
 | 
			
		||||
        return 1; // Initialization failed
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    char glsl_version[32];
 | 
			
		||||
    snprintf(glsl_version, sizeof(glsl_version), "#version %d%d0", open_gl_major_version, open_gl_minor_version);
 | 
			
		||||
    if (!ImGui_ImplOpenGL3_Init(glsl_version)) {
 | 
			
		||||
        std::cerr << "ImGui_ImplOpenGL3_Init failed!" << std::endl;
 | 
			
		||||
        ImGui_ImplSDL3_Shutdown();
 | 
			
		||||
        ImGui::DestroyContext();
 | 
			
		||||
        return 1; // Initialization failed
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cleanup_imgui() {
 | 
			
		||||
    ImGui_ImplOpenGL3_Shutdown();
 | 
			
		||||
    ImGui_ImplSDL3_Shutdown();
 | 
			
		||||
    ImGui::DestroyContext();
 | 
			
		||||
    std::cout << "ImGui cleanup successful." << std::endl;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void calc_frame_time() {
 | 
			
		||||
    // Calculate frame time
 | 
			
		||||
    current_time = SDL_GetTicks();
 | 
			
		||||
    frame_time = (current_time - last_time) / 1000.0f; // Convert milliseconds to seconds
 | 
			
		||||
    fps = 1.0f / frame_time;
 | 
			
		||||
    last_time = current_time;
 | 
			
		||||
 | 
			
		||||
    // Update frame time graph
 | 
			
		||||
    for (int i = 99; i > 0; --i) {
 | 
			
		||||
        frame_time_graph[i] = frame_time_graph[i - 1]; // Shift old values
 | 
			
		||||
    }
 | 
			
		||||
    frame_time_graph[0] = frame_time; // Add new frame time
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void new_frame_imgui() {
 | 
			
		||||
    ImGui_ImplOpenGL3_NewFrame();
 | 
			
		||||
    ImGui_ImplSDL3_NewFrame();
 | 
			
		||||
    ImGui::NewFrame();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void frame_time_ui() {
 | 
			
		||||
    ImGui::Begin("Frame Time");
 | 
			
		||||
    ImGui::Text("Current FPS: %.2f", fps);
 | 
			
		||||
    ImGui::Text("Current Frame Time: %.3f ms", frame_time * 1000.0f);
 | 
			
		||||
    ImGui::PlotLines("##Frame Time Graph", frame_time_graph, 100, 0, "Frame Time (ms)", 0.0f, 0.1f, ImVec2(200, 80));
 | 
			
		||||
    ImGui::End();
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										239
									
								
								src/main.cpp
									
									
									
									
									
								
							
							
						
						
									
										239
									
								
								src/main.cpp
									
									
									
									
									
								
							@@ -1,170 +1,135 @@
 | 
			
		||||
#include "main.hpp"
 | 
			
		||||
#include <GL/glu.h>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// Init
 | 
			
		||||
int initialize() {
 | 
			
		||||
    // Initialize SDL
 | 
			
		||||
    if (!SDL_Init(SDL_INIT_VIDEO)) {
 | 
			
		||||
        std::cerr << "SDL could not initialize! SDL_Error: " << SDL_GetError() << std::endl;
 | 
			
		||||
        return 1; // Initialization failed
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Create a window with OpenGL context
 | 
			
		||||
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
 | 
			
		||||
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
 | 
			
		||||
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
 | 
			
		||||
    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
 | 
			
		||||
    SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
 | 
			
		||||
    SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
 | 
			
		||||
 | 
			
		||||
    main_scale = SDL_GetDisplayContentScale(SDL_GetPrimaryDisplay());
 | 
			
		||||
    window = SDL_CreateWindow("Untitled", (int)(window_width * main_scale), (int)(window_height * main_scale), window_flags);
 | 
			
		||||
    if (!window) {
 | 
			
		||||
        std::cerr << "Window could not be created! SDL_Error: " << SDL_GetError() << std::endl;
 | 
			
		||||
        SDL_Quit();
 | 
			
		||||
        return 1; // Window creation failed
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    // Initialize OpenGL context
 | 
			
		||||
    SDL_GLContext gl_context = SDL_GL_CreateContext(window);
 | 
			
		||||
    if (!gl_context) {
 | 
			
		||||
        std::cerr << "OpenGL context could not be created! SDL_Error: " << SDL_GetError() << std::endl;
 | 
			
		||||
        SDL_DestroyWindow(window);
 | 
			
		||||
        SDL_Quit();
 | 
			
		||||
        return 1; // OpenGL context creation failed
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    SDL_GL_MakeCurrent(window, gl_context);
 | 
			
		||||
    SDL_GL_SetSwapInterval(1); // Enable VSync
 | 
			
		||||
    SDL_SetWindowPosition(window, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
 | 
			
		||||
    SDL_ShowWindow(window);
 | 
			
		||||
 | 
			
		||||
    // Initialize ImGui
 | 
			
		||||
    IMGUI_CHECKVERSION();
 | 
			
		||||
    ImGui::CreateContext();
 | 
			
		||||
    ImGuiIO& io = ImGui::GetIO(); (void)io;
 | 
			
		||||
    io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
 | 
			
		||||
 | 
			
		||||
    // Setup Dear ImGui style
 | 
			
		||||
    ImGui::StyleColorsDark();
 | 
			
		||||
 | 
			
		||||
    // Setup scale
 | 
			
		||||
    ImGuiStyle& style = ImGui::GetStyle();
 | 
			
		||||
    style.ScaleAllSizes(main_scale);
 | 
			
		||||
    style.FontScaleDpi = main_scale;
 | 
			
		||||
 | 
			
		||||
    // Setup Platform/Renderer bindings
 | 
			
		||||
    if (!ImGui_ImplSDL3_InitForOpenGL(window, gl_context)) {
 | 
			
		||||
        std::cerr << "ImGui_ImplSDL3_InitForOpenGL failed!" << std::endl;
 | 
			
		||||
        SDL_GL_DestroyContext(gl_context);
 | 
			
		||||
        SDL_DestroyWindow(window);
 | 
			
		||||
        SDL_Quit();
 | 
			
		||||
        return 1; // Initialization failed
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!ImGui_ImplOpenGL3_Init("#version 330")) {
 | 
			
		||||
        std::cerr << "ImGui_ImplOpenGL3_Init failed!" << std::endl;
 | 
			
		||||
        ImGui_ImplSDL3_Shutdown();
 | 
			
		||||
        SDL_GL_DestroyContext(gl_context);
 | 
			
		||||
        SDL_DestroyWindow(window);
 | 
			
		||||
        SDL_Quit();
 | 
			
		||||
        return 1; // Initialization failed
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return 0; // Initialization successful
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// Cleanup
 | 
			
		||||
void cleanup() {
 | 
			
		||||
    // Shutdown ImGui
 | 
			
		||||
    ImGui_ImplOpenGL3_Shutdown();
 | 
			
		||||
    ImGui_ImplSDL3_Shutdown();
 | 
			
		||||
    ImGui::DestroyContext();
 | 
			
		||||
 | 
			
		||||
    // Destroy OpenGL context
 | 
			
		||||
    SDL_GLContext gl_context = SDL_GL_GetCurrentContext();
 | 
			
		||||
    if (gl_context) {
 | 
			
		||||
        SDL_GL_MakeCurrent(NULL, NULL);
 | 
			
		||||
        SDL_GL_DestroyContext(gl_context);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Destroy window
 | 
			
		||||
    if (window) {
 | 
			
		||||
        SDL_DestroyWindow(window);
 | 
			
		||||
        window = nullptr;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Quit SDL
 | 
			
		||||
    SDL_Quit();
 | 
			
		||||
    std::cout << "Cleanup successful." << std::endl;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Variables
 | 
			
		||||
bool running = true;
 | 
			
		||||
 | 
			
		||||
// Main
 | 
			
		||||
int main(int argc, char* argv[]) {
 | 
			
		||||
    // Initialize
 | 
			
		||||
    if (initialize() != 0) {
 | 
			
		||||
        std::cerr << "Initialization failed." << std::endl;
 | 
			
		||||
        return -1; // Initialization failed
 | 
			
		||||
    // Initialize SDL
 | 
			
		||||
    if (initialize_sdl() != 0) {
 | 
			
		||||
        std::cerr << "SDL initialization failed." << std::endl;
 | 
			
		||||
        return 1; // SDL initialization failed
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Initialize OpenGL
 | 
			
		||||
    if (initialize_opengl() != 0) {
 | 
			
		||||
        std::cerr << "OpenGL initialization failed." << std::endl;
 | 
			
		||||
        cleanup_sdl();
 | 
			
		||||
        return 1; // OpenGL initialization failed
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Initialize ImGui
 | 
			
		||||
    if (initialize_imgui() != 0) {
 | 
			
		||||
        std::cerr << "ImGui initialization failed." << std::endl;
 | 
			
		||||
        cleanup_opengl();
 | 
			
		||||
        cleanup_sdl();
 | 
			
		||||
        return 1; // ImGui initialization failed
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Triangle vertices
 | 
			
		||||
    float vertices[] = {
 | 
			
		||||
        0.5f,  0.5f, 0.0f,  // top right
 | 
			
		||||
        0.5f, -0.5f, 0.0f,  // bottom right
 | 
			
		||||
        -0.5f, -0.5f, 0.0f,  // bottom left
 | 
			
		||||
        -0.5f,  0.5f, 0.0f   // top left 
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    unsigned int indices[] = {
 | 
			
		||||
        0, 1, 3,   // first triangle
 | 
			
		||||
        1, 2, 3    // second triangle
 | 
			
		||||
    };  
 | 
			
		||||
 | 
			
		||||
    // Vertex buffer object (VBO) and vertex array object (VAO) and element buffer object (EBO)
 | 
			
		||||
    unsigned int VBO, VAO, EBO;
 | 
			
		||||
 | 
			
		||||
    glGenVertexArrays(1, &VAO); // Generate a vertex array object
 | 
			
		||||
    glGenBuffers(1, &VBO); // Generate a vertex buffer object
 | 
			
		||||
    glGenBuffers(1, &EBO); // Generate an element buffer object
 | 
			
		||||
 | 
			
		||||
    glBindVertexArray(VAO); // Bind the vertex array object
 | 
			
		||||
    glBindBuffer(GL_ARRAY_BUFFER, VBO); // Bind the vertex buffer object
 | 
			
		||||
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); // Bind the element buffer object
 | 
			
		||||
 | 
			
		||||
    // Upload vertex data to the buffer
 | 
			
		||||
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
 | 
			
		||||
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
 | 
			
		||||
 | 
			
		||||
    // Set up vertex attributes
 | 
			
		||||
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
 | 
			
		||||
    glEnableVertexAttribArray(0);
 | 
			
		||||
 | 
			
		||||
    glBindVertexArray(0); // Unbind the vertex array object
 | 
			
		||||
 | 
			
		||||
    // Load shaders
 | 
			
		||||
    const char* vertex_shader_source = read_file("shaders/triangle.vert");
 | 
			
		||||
    const char* fragment_shader_source = read_file("shaders/triangle.frag");
 | 
			
		||||
 | 
			
		||||
    unsigned int vertex_shader = compile_shader(vertex_shader_source, GL_VERTEX_SHADER);
 | 
			
		||||
    unsigned int fragment_shader = compile_shader(fragment_shader_source, GL_FRAGMENT_SHADER);
 | 
			
		||||
    unsigned int shader_program = create_program(vertex_shader, fragment_shader);
 | 
			
		||||
 | 
			
		||||
    // Set the shader program
 | 
			
		||||
    glUseProgram(shader_program);
 | 
			
		||||
 | 
			
		||||
    // Wireframe toggle
 | 
			
		||||
    bool wireframe_mode = false;
 | 
			
		||||
 | 
			
		||||
    // Main loop
 | 
			
		||||
    running = true;
 | 
			
		||||
    last_time = SDL_GetTicks();
 | 
			
		||||
    while (running) {
 | 
			
		||||
 | 
			
		||||
        // Handle events
 | 
			
		||||
        while (SDL_PollEvent(&event)) {
 | 
			
		||||
            ImGui_ImplSDL3_ProcessEvent(&event);
 | 
			
		||||
            ImGui_ImplSDL3_ProcessEvent(&event); // Process ImGui events
 | 
			
		||||
            if (event.type == SDL_EVENT_QUIT) {
 | 
			
		||||
                running = false; // Exit loop on quit event
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Start the ImGui frame
 | 
			
		||||
        ImGui_ImplOpenGL3_NewFrame();
 | 
			
		||||
        ImGui_ImplSDL3_NewFrame();
 | 
			
		||||
        ImGui::NewFrame();
 | 
			
		||||
        new_frame_imgui();
 | 
			
		||||
 | 
			
		||||
        // Show a simple ImGui window
 | 
			
		||||
        ImGui::Begin("Hello, World!");
 | 
			
		||||
        ImGui::Text("This is a simple ImGui window.");
 | 
			
		||||
        if (ImGui::Button("Close")) {
 | 
			
		||||
            running = false; // Close button clicked
 | 
			
		||||
        // Frame time UI
 | 
			
		||||
        frame_time_ui();
 | 
			
		||||
 | 
			
		||||
        // Toggle wireframe mode ui
 | 
			
		||||
        ImGui::Begin("Wireframe Mode");
 | 
			
		||||
        if (ImGui::Checkbox("Enable Wireframe Mode", &wireframe_mode)) {
 | 
			
		||||
            if (wireframe_mode) {
 | 
			
		||||
                glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); // Enable wireframe mode
 | 
			
		||||
            } else {
 | 
			
		||||
                glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); // Disable wireframe mode
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        ImGui::End();
 | 
			
		||||
 | 
			
		||||
        // Display FPS in the ImGui window
 | 
			
		||||
        ImGui::Begin("FPS Counter");
 | 
			
		||||
        ImGui::Text("Current FPS: %.2f", fps);
 | 
			
		||||
        // Frame time graph
 | 
			
		||||
        ImGui::PlotLines("##FrameTime", frame_time_graph, 100, 0, "Frame Time (ms)", 0.0f, 0.1f, ImVec2(200, 80));
 | 
			
		||||
        ImGui::Text("Current Time: %u ms", current_time);
 | 
			
		||||
 | 
			
		||||
        ImGui::End();
 | 
			
		||||
 | 
			
		||||
        // Render
 | 
			
		||||
        ImGui::Render();
 | 
			
		||||
        glViewport(0, 0, (int)(window_width * main_scale), (int)(window_height * main_scale));
 | 
			
		||||
        glClearColor(0.45f, 0.55f, 0.60f, 1.00f);
 | 
			
		||||
        glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
 | 
			
		||||
        glClear(GL_COLOR_BUFFER_BIT);
 | 
			
		||||
 | 
			
		||||
        glBindVertexArray(VAO); // Bind the vertex array object
 | 
			
		||||
        glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); // Draw the triangles
 | 
			
		||||
 | 
			
		||||
        ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
 | 
			
		||||
        SDL_GL_SwapWindow(window);
 | 
			
		||||
 | 
			
		||||
        // Calculate FPS
 | 
			
		||||
        current_time = SDL_GetTicks();
 | 
			
		||||
        frame_time = (current_time - last_time) / 1000.0f; // Convert milliseconds to seconds
 | 
			
		||||
        fps = 1.0f / frame_time;
 | 
			
		||||
        last_time = current_time;
 | 
			
		||||
 | 
			
		||||
        // Update frame time graph
 | 
			
		||||
        for (int i = 99; i > 0; --i) {
 | 
			
		||||
            frame_time_graph[i] = frame_time_graph[i - 1]; // Shift old values
 | 
			
		||||
        }
 | 
			
		||||
        frame_time_graph[0] = frame_time; // Add new frame time
 | 
			
		||||
        calc_frame_time();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Cleanup
 | 
			
		||||
    cleanup();
 | 
			
		||||
    glDeleteVertexArrays(1, &VAO);
 | 
			
		||||
    glDeleteBuffers(1, &VBO);
 | 
			
		||||
    glDeleteBuffers(1, &EBO);
 | 
			
		||||
    glDeleteProgram(shader_program);
 | 
			
		||||
    glDeleteShader(vertex_shader);
 | 
			
		||||
    glDeleteShader(fragment_shader);
 | 
			
		||||
    free((void*)vertex_shader_source);
 | 
			
		||||
    free((void*)fragment_shader_source);
 | 
			
		||||
    cleanup_imgui();
 | 
			
		||||
    cleanup_opengl();
 | 
			
		||||
    cleanup_sdl();
 | 
			
		||||
    std::cout << "Application exited successfully." << std::endl;
 | 
			
		||||
    return 0; // Exit code
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										24
									
								
								src/utils.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								src/utils.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,24 @@
 | 
			
		||||
#include "utils.hpp"
 | 
			
		||||
 | 
			
		||||
char* read_file(const char* file_path) {
 | 
			
		||||
    std::ifstream file(file_path);
 | 
			
		||||
    if (!file) {
 | 
			
		||||
        std::cerr << "Could not open file: " << file_path << std::endl;
 | 
			
		||||
        return nullptr; // Return null if file cannot be opened
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    file.seekg(0, std::ios::end);
 | 
			
		||||
    size_t file_size = file.tellg();
 | 
			
		||||
    file.seekg(0, std::ios::beg);
 | 
			
		||||
 | 
			
		||||
    char* buffer = new char[file_size + 1];
 | 
			
		||||
    if (!buffer) {
 | 
			
		||||
        std::cerr << "Memory allocation failed" << std::endl;
 | 
			
		||||
        return nullptr;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    file.read(buffer, file_size);
 | 
			
		||||
    buffer[file_size] = '\0'; // Null-terminate the string
 | 
			
		||||
 | 
			
		||||
    return buffer;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										37
									
								
								src/window.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								src/window.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,37 @@
 | 
			
		||||
#include "window.hpp"
 | 
			
		||||
 | 
			
		||||
// Variables
 | 
			
		||||
float main_scale;
 | 
			
		||||
SDL_Window* window;
 | 
			
		||||
SDL_Event event;
 | 
			
		||||
 | 
			
		||||
// Functions
 | 
			
		||||
int initialize_sdl() {
 | 
			
		||||
    // Initialize SDL
 | 
			
		||||
    if (!SDL_Init(SDL_INIT_VIDEO)) {
 | 
			
		||||
        std::cerr << "SDL could not initialize! SDL_Error: " << SDL_GetError() << std::endl;
 | 
			
		||||
        return 1; // Initialization failed
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    main_scale = SDL_GetDisplayContentScale(SDL_GetPrimaryDisplay());
 | 
			
		||||
    window = SDL_CreateWindow("Untitled", (int)(window_width * main_scale), (int)(window_height * main_scale), window_flags);
 | 
			
		||||
    if (!window) {
 | 
			
		||||
        std::cerr << "Window could not be created! SDL_Error: " << SDL_GetError() << std::endl;
 | 
			
		||||
        SDL_Quit();
 | 
			
		||||
        return 1; // Window creation failed
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return 0; // Initialization successful
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cleanup_sdl() {
 | 
			
		||||
    if (window) {
 | 
			
		||||
        // Destroy window
 | 
			
		||||
        SDL_DestroyWindow(window);
 | 
			
		||||
        window = nullptr;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Quit SDL
 | 
			
		||||
    SDL_Quit();
 | 
			
		||||
    std::cout << "SDL cleanup successful." << std::endl;
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user