From 8920379ce3aef1adf31deab09dcc6fcbe68e45f9 Mon Sep 17 00:00:00 2001 From: MichaelFisher1997 Date: Sun, 12 Jan 2025 15:53:46 +0000 Subject: [PATCH] Indexbuffer improvments --- Makefile | 58 ++++++++++++------------- src/IndexBuffer.cpp | 39 +++++++++++++++-- src/IndexBuffer.h | 12 +++++- src/Renderer.cpp | 2 +- src/VertexArray.cpp | 6 ++- src/main.cpp | 2 + src/sdl.cpp | 100 +++++++++++++++++++++++++++----------------- src/sdl.hpp | 8 ++-- 8 files changed, 148 insertions(+), 79 deletions(-) diff --git a/Makefile b/Makefile index e26ddfc..e3e9861 100755 --- a/Makefile +++ b/Makefile @@ -1,38 +1,38 @@ -CC=clang++ -current_directory=$(shell pwd) +# Compiler and flags +CXX := g++ +CXXFLAGS := -g #-O0 -Wall -Wextra -FRAMEWORKS=-framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo +# Libraries +LDFLAGS := -lSDL2 -lGLEW -lGL -CFLAGS=-std=c++11 -CFLAGS+=-I$(current_directory) -CFLAGS+=-I$(current_directory)/../external +# Source and output directories +SRC_DIR := src +BUILD_DIR := build +TARGET := $(BUILD_DIR)/opengl -LDFLAGS=-L$(current_directory)/../lib -LDFLAGS+=-lglfw3 -LDFLAGS+=-lGLEW +# Source files and object files +SRC := $(wildcard $(SRC_DIR)/*.cpp) +OBJ := $(SRC:$(SRC_DIR)/%.cpp=$(BUILD_DIR)/%.o) -SOURCES=$(wildcard *.cpp) -OBJECTS=$(patsubst %.cpp, %.o, $(SOURCES)) +# Default target +all: $(TARGET) +# Build the target executable +$(TARGET): $(OBJ) + mkdir -p $(BUILD_DIR) + $(CXX) $(CXXFLAGS) $^ -o $@ $(LDFLAGS) -%.o: %.cpp - $(CC) $(CFLAGS) -c -o $@ $^ +# Build object files +$(BUILD_DIR)/%.o: $(SRC_DIR)/%.cpp + mkdir -p $(BUILD_DIR) + $(CXX) $(CXXFLAGS) -c $< -o $@ -default: debug - -app: $(OBJECTS) - $(CC) $(CFLAGS) $(LDFLAGS) $(FRAMEWORKS) -o $@ $(OBJECTS) - -# Define debug and -g enables debug symbols -debug: CFLAGS+=-DDEBUG -g -debug: app - -release: app - -.PHONY: clean +# Clean up build files clean: - rm -f *.o app + rm -rf $(BUILD_DIR) -.PHONY: debugger -debugger: debug - PATH=/usr/bin /usr/bin/lldb ./app \ No newline at end of file +# Run the application +run: $(TARGET) + ./$(TARGET) + +.PHONY: all clean run diff --git a/src/IndexBuffer.cpp b/src/IndexBuffer.cpp index 4349232..55cb8e2 100644 --- a/src/IndexBuffer.cpp +++ b/src/IndexBuffer.cpp @@ -12,10 +12,41 @@ IndexBuffer::IndexBuffer(const unsigned int* data, unsigned int count) GLCall(glBufferData(GL_ELEMENT_ARRAY_BUFFER, count * sizeof(unsigned int), data, GL_STATIC_DRAW)); // assigne buffer size, static as we use many times, but does not change } -IndexBuffer::~IndexBuffer() -{ - std::cout << "m_RendererID: " << &m_RendererID << " " << m_RendererID << std::endl; - GLCall(glDeleteBuffers(1, &m_RendererID)); +// Destructor +IndexBuffer::~IndexBuffer() { + if (m_RendererID != 0) { // Only delete if valid + GLCall(glDeleteBuffers(1, &m_RendererID)); + std::cout << "IndexBuffer destroyed with RendererID: " << m_RendererID << std::endl; + } +} + +// Move Constructor +IndexBuffer::IndexBuffer(IndexBuffer&& other) noexcept + : m_RendererID(other.m_RendererID), m_Count(other.m_Count) { + other.m_RendererID = 0; // Invalidate the moved-from object + other.m_Count = 0; + std::cout << "IndexBuffer moved (constructor)" << std::endl; +} + +// Move Assignment Operator +IndexBuffer& IndexBuffer::operator=(IndexBuffer&& other) noexcept { + if (this != &other) { + // Free existing resources + if (m_RendererID != 0) { + GLCall(glDeleteBuffers(1, &m_RendererID)); + } + + // Transfer ownership + m_RendererID = other.m_RendererID; + m_Count = other.m_Count; + + // Invalidate the moved-from object + other.m_RendererID = 0; + other.m_Count = 0; + + std::cout << "IndexBuffer moved (assignment)" << std::endl; + } + return *this; } void IndexBuffer::Bind() const diff --git a/src/IndexBuffer.h b/src/IndexBuffer.h index d37125f..ec77e6d 100644 --- a/src/IndexBuffer.h +++ b/src/IndexBuffer.h @@ -6,11 +6,19 @@ public: IndexBuffer(const unsigned int* data, unsigned int count); ~IndexBuffer(); + // Disallow copy operations + IndexBuffer(const IndexBuffer&) = delete; + IndexBuffer& operator=(const IndexBuffer&) = delete; + + // Enable move operations + IndexBuffer(IndexBuffer&& other) noexcept; + IndexBuffer& operator=(IndexBuffer&& other) noexcept; + void Bind() const; void Unbind() const; inline unsigned int GetCount() const { return m_Count; } private: - unsigned int m_RendererID; - unsigned int m_Count; + unsigned int m_RendererID = 0; + unsigned int m_Count = 0; }; diff --git a/src/Renderer.cpp b/src/Renderer.cpp index 537c7b6..811b91b 100644 --- a/src/Renderer.cpp +++ b/src/Renderer.cpp @@ -4,7 +4,7 @@ void GLClearError() { - //while (glGetError() != GL_NO_ERROR); + while (glGetError() != GL_NO_ERROR); } diff --git a/src/VertexArray.cpp b/src/VertexArray.cpp index d33885e..372edb4 100644 --- a/src/VertexArray.cpp +++ b/src/VertexArray.cpp @@ -3,7 +3,11 @@ VertexArray::VertexArray() { - GLCall(glGenVertexArrays(1, &m_RendererID)); + std::cout << "VertexArray::VertexArray()" << std::endl; + std::cout << "m_RendererID: " << &m_RendererID << " " << m_RendererID << std::endl; + //GLCall(glGenVertexArrays(1, &m_RendererID)); + glGenVertexArrays(1, &m_RendererID); + std::cout << "m_RendererID: " << &m_RendererID << " " << m_RendererID << std::endl; if (!m_RendererID) { std::cerr << "Failed to generate VAO" << std::endl; } diff --git a/src/main.cpp b/src/main.cpp index f958fe7..6390123 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2,7 +2,9 @@ int main(int argc, char* argv[]) { // Create an instance of our SdlWindow class + std::cout << "starting" << std::endl; SdlWindow window("My SDL2 Window", 800, 600); + std::cout << "About to run: " << std::endl; // Run the main loop window.run(); diff --git a/src/sdl.cpp b/src/sdl.cpp index 71c1110..db6389b 100644 --- a/src/sdl.cpp +++ b/src/sdl.cpp @@ -51,25 +51,30 @@ struct ShaderProgramSource { }; SdlWindow::SdlWindow(const char* title, int width, int height) - : m_window(nullptr), - m_renderer(nullptr), - m_isRunning(false), - m_isFullscreen(false), - m_width(width), - m_height(height), - m_glContext(nullptr), - m_windowedWidth(width), - m_windowedHeight(height), - r(0.5f), - location(), - increment(0.05f), - m_ib(nullptr, 0) +: m_window(nullptr), + m_renderer(nullptr), + m_isRunning(false), + m_isFullscreen(false), + m_width(width), + m_height(height), + m_windowedWidth(width), + m_windowedHeight(height), + r(0.5f), + m_glContext(nullptr), + increment(0.05f), + vao(0), + layout(nullptr), + va(nullptr), + m_ib(nullptr) { + + std::cout << "Step 0: hellow world" << std::endl; + // 1. Set attributes 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); - + std::cout << "Step 1: SDL_GL_SetAttribute completed" << std::endl; // 2. Create the window with OpenGL flag m_window = SDL_CreateWindow(title, SDL_WINDOWPOS_CENTERED, @@ -79,30 +84,42 @@ SdlWindow::SdlWindow(const char* title, int width, int height) SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN| SDL_WINDOW_RESIZABLE); if (!m_window) { - std::cerr << "Failed to create window: " << SDL_GetError() << std::endl; - return; + std::cerr << "Failed to create window: " << SDL_GetError() << std::endl; + return; } + std::cout << "Step 2: SDL_CreateWindow completed" << std::endl; - // 3. Create OpenGL context m_glContext = SDL_GL_CreateContext(m_window); if (!m_glContext) { std::cerr << "Failed to create GL context: " << SDL_GetError() << std::endl; return; } - // 4. Optionally init GLEW (if not on macOS core profile) + std::cout << "Step 3: SDL_GL_CreateContext completed" << std::endl; + + if (SDL_GL_MakeCurrent(m_window, m_glContext) != 0) { + std::cerr << "Failed to make GL context current: " << SDL_GetError() << std::endl; + return; + } + std::cout << "Step 4: SDL_GL_MakeCurrent completed" << std::endl; + #ifndef __APPLE__ glewExperimental = GL_TRUE; GLenum glewErr = glewInit(); - if (glewInit() != GLEW_OK) { - std::cerr << "Failed to init GLEW" << glewGetErrorString(glewErr) << std::endl; + if (glewErr != GLEW_OK) { + std::cerr << "Failed to init GLEW: " << glewGetErrorString(glewErr) << std::endl; return; } - glGetError(); + std::cout << "Step 5: GLEW initialized successfully" << std::endl; + glGetError(); // Clear GLEW's initial error #endif + std::cout << "OpenGL Version: " << glGetString(GL_VERSION) << std::endl; + std::cout << "GLSL Version: " << glGetString(GL_SHADING_LANGUAGE_VERSION) << std::endl; + std::cout << "Vendor: " << glGetString(GL_VENDOR) << std::endl; + + // 5. Set vsync (optional) SDL_GL_SetSwapInterval(1); //Vsync - SdlWindow::GLClearError(); // 6. Mark as running m_isRunning = true; @@ -122,8 +139,9 @@ SdlWindow::SdlWindow(const char* title, int width, int height) VertexArray va; VertexBuffer vb(positions, 4 * 2 * sizeof(float)); - IndexBuffer ib(indices, 6); - m_ib = ib; + m_ib = new IndexBuffer(indices, 6); + + VertexBufferLayout layout; layout.Push(2); @@ -135,10 +153,11 @@ SdlWindow::SdlWindow(const char* title, int width, int height) std::cout << "VERTEX" << std::endl << source.VertexSource << std::endl; std::cout << "FRAGMENT" << std::endl << source.FragmentSource << std::endl; - unsigned int m_ShaderID = createShader(source.VertexSource, source.FragmentSource); - GLCall(glUseProgram(m_ShaderID)); + unsigned int shader = createShader(source.VertexSource, source.FragmentSource); + std::cout << "shader: " << shader << std::endl; + GLCall(glUseProgram(shader)); - GLCall(unsigned int location = glGetUniformLocation(m_ShaderID, "u_Color")); + GLCall(unsigned int location = glGetUniformLocation(shader, "u_Color")); ASSERT(location != -1); // -1 is an error GLCall(glUniform4f(location, 0.8f, 0.3f, 0.8f, 1.0f)); @@ -150,7 +169,6 @@ SdlWindow::SdlWindow(const char* title, int width, int height) } - SdlWindow::~SdlWindow() { // If using SDL Renderer, destroy it. But if you’re purely using OpenGL, you might remove it. if (m_renderer) { @@ -172,11 +190,15 @@ SdlWindow::~SdlWindow() { glDeleteProgram(shader); shader = 0; } + if (m_ib) { + delete m_ib; + m_ib = nullptr; + } SDL_Quit(); } - - +// +// void SdlWindow::run() { while (m_isRunning) { processEvents(); @@ -185,7 +207,7 @@ void SdlWindow::run() { } GLCall(glDeleteProgram(shader)); } - +// void SdlWindow::processEvents() { SDL_Event event; while (SDL_PollEvent(&event)) { @@ -231,7 +253,7 @@ SDL_Event event; } } } - +// void SdlWindow::update() { // Update game/application logic here if (r > 1.0f) { @@ -241,7 +263,7 @@ void SdlWindow::update() { } r += increment; } - +// void SdlWindow::render() { // Use GL calls instead of SDL’s renderer GLCall(glClearColor(0.0f, 0.0f, 0.0f, 1.0f)); //background @@ -249,10 +271,12 @@ void SdlWindow::render() { GLCall(glClear(GL_COLOR_BUFFER_BIT)); GLCall(glUseProgram(shader)); + std::cout << "shader: " << shader << std::endl; + std::cout << "location: " << location << std::endl; GLCall(glUniform4f(location, r, 0.3f, 0.8f, 1.0f)); - va.Bind(); - m_ib.Bind(); + va->Bind(); + m_ib->Bind(); // TODO: Draw with OpenGL here (shaders, triangles, etc.) //glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr); GLCall(glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr)); //macro assert for debugging @@ -260,7 +284,7 @@ void SdlWindow::render() { // Swap buffers SDL_GL_SwapWindow(m_window); } - +// void SdlWindow::setFullscreen(bool fullscreen) { if (m_window) { m_isFullscreen = fullscreen; @@ -283,7 +307,7 @@ void SdlWindow::setFullscreen(bool fullscreen) { } } } - +// unsigned int SdlWindow::compileShader(unsigned int type, const std::string& source) { GLCall(unsigned int id = glCreateShader(type)); const char* src = source.c_str(); // <--- this string needs to exist when compiling/running @@ -360,7 +384,7 @@ SdlWindow::ShaderProgramSource SdlWindow::parseShader(const std::string& filepat } void SdlWindow::GLClearError() { - //while (glGetError() != GL_NO_ERROR); + while (glGetError() != GL_NO_ERROR); } diff --git a/src/sdl.hpp b/src/sdl.hpp index 6a03628..2a66e71 100644 --- a/src/sdl.hpp +++ b/src/sdl.hpp @@ -56,7 +56,7 @@ private: float r; SDL_GLContext m_glContext; float increment; - // temp shader stuff +// // temp shader stuff std::string vetexShader; std::string fragmentShader; unsigned int buffer; @@ -64,9 +64,9 @@ private: unsigned int vao; unsigned int shader; unsigned int location; - VertexBufferLayout layout; - VertexArray va; - IndexBuffer m_ib; + VertexBufferLayout* layout; + VertexArray* va; + IndexBuffer* m_ib; // Private methods void processEvents();