Compare commits
2 Commits
233cfdc356
...
63d0770b42
Author | SHA1 | Date | |
---|---|---|---|
63d0770b42 | |||
ce44dfc950 |
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
|
#ifndef MAIN_HPP
|
||||||
#define MAIN_HPP
|
#define MAIN_HPP
|
||||||
|
|
||||||
// ImGui
|
// Includes
|
||||||
#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
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <string>
|
#include "window.hpp"
|
||||||
#include <vector>
|
#include "graphics.hpp"
|
||||||
|
#include "utils.hpp"
|
||||||
// Structs
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Variables
|
// Variables
|
||||||
int window_width = 1920;
|
extern bool running;
|
||||||
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};
|
|
||||||
|
|
||||||
// Functions
|
// Functions
|
||||||
int main(int argc, char* argv[]);
|
int main(int argc, char* argv[]);
|
||||||
int initialize();
|
|
||||||
void cleanup();
|
|
||||||
|
|
||||||
#endif
|
#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
|
@ -21,6 +21,7 @@ Cus I cant think of a name and im uncreative.
|
|||||||
|
|
||||||
# Features
|
# Features
|
||||||
- FPS counter
|
- FPS counter
|
||||||
|
- !!! RGB RECTANGLE !!!
|
||||||
- Thats about it rly ¯\\_(ツ)\_/¯
|
- Thats about it rly ¯\\_(ツ)\_/¯
|
||||||
|
|
||||||
# Requirements
|
# Requirements
|
||||||
@ -35,3 +36,9 @@ Cus I cant think of a name and im uncreative.
|
|||||||
6. If it runs, enjoy the FPS counter
|
6. If it runs, enjoy the FPS counter
|
||||||
|
|
||||||
\* we dont like clang here (idk why, i just dont like it cus y not)
|
\* we dont like clang here (idk why, i just dont like it cus y not)
|
||||||
|
|
||||||
|
# Notes
|
||||||
|
OpenGl is scary >.<
|
||||||
|
|
||||||
|
# License
|
||||||
|
"yes"
|
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 "main.hpp"
|
||||||
|
#include <GL/glu.h>
|
||||||
|
|
||||||
|
// Variables
|
||||||
// Init
|
bool running = true;
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Main
|
// Main
|
||||||
int main(int argc, char* argv[]) {
|
int main(int argc, char* argv[]) {
|
||||||
// Initialize
|
// Initialize SDL
|
||||||
if (initialize() != 0) {
|
if (initialize_sdl() != 0) {
|
||||||
std::cerr << "Initialization failed." << std::endl;
|
std::cerr << "SDL initialization failed." << std::endl;
|
||||||
return -1; // Initialization failed
|
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
|
// Main loop
|
||||||
running = true;
|
|
||||||
last_time = SDL_GetTicks();
|
|
||||||
while (running) {
|
while (running) {
|
||||||
|
|
||||||
// Handle events
|
// Handle events
|
||||||
while (SDL_PollEvent(&event)) {
|
while (SDL_PollEvent(&event)) {
|
||||||
ImGui_ImplSDL3_ProcessEvent(&event);
|
ImGui_ImplSDL3_ProcessEvent(&event); // Process ImGui events
|
||||||
if (event.type == SDL_EVENT_QUIT) {
|
if (event.type == SDL_EVENT_QUIT) {
|
||||||
running = false; // Exit loop on quit event
|
running = false; // Exit loop on quit event
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start the ImGui frame
|
// Start the ImGui frame
|
||||||
ImGui_ImplOpenGL3_NewFrame();
|
new_frame_imgui();
|
||||||
ImGui_ImplSDL3_NewFrame();
|
|
||||||
ImGui::NewFrame();
|
|
||||||
|
|
||||||
// Show a simple ImGui window
|
// Frame time UI
|
||||||
ImGui::Begin("Hello, World!");
|
frame_time_ui();
|
||||||
ImGui::Text("This is a simple ImGui window.");
|
|
||||||
if (ImGui::Button("Close")) {
|
// Toggle wireframe mode ui
|
||||||
running = false; // Close button clicked
|
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();
|
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
|
// Render
|
||||||
ImGui::Render();
|
ImGui::Render();
|
||||||
glViewport(0, 0, (int)(window_width * main_scale), (int)(window_height * main_scale));
|
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
|
||||||
glClearColor(0.45f, 0.55f, 0.60f, 1.00f);
|
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
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());
|
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
|
||||||
SDL_GL_SwapWindow(window);
|
SDL_GL_SwapWindow(window);
|
||||||
|
|
||||||
// Calculate FPS
|
// Calculate FPS
|
||||||
current_time = SDL_GetTicks();
|
calc_frame_time();
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cleanup
|
// 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;
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user