Indexbuffer improvments

This commit is contained in:
MichaelFisher1997 2025-01-12 15:53:46 +00:00
parent fd13d0ba63
commit 8920379ce3
8 changed files with 148 additions and 79 deletions

View File

@ -1,38 +1,38 @@
CC=clang++ # Compiler and flags
current_directory=$(shell pwd) 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 # Source and output directories
CFLAGS+=-I$(current_directory) SRC_DIR := src
CFLAGS+=-I$(current_directory)/../external BUILD_DIR := build
TARGET := $(BUILD_DIR)/opengl
LDFLAGS=-L$(current_directory)/../lib # Source files and object files
LDFLAGS+=-lglfw3 SRC := $(wildcard $(SRC_DIR)/*.cpp)
LDFLAGS+=-lGLEW OBJ := $(SRC:$(SRC_DIR)/%.cpp=$(BUILD_DIR)/%.o)
SOURCES=$(wildcard *.cpp) # Default target
OBJECTS=$(patsubst %.cpp, %.o, $(SOURCES)) all: $(TARGET)
# Build the target executable
$(TARGET): $(OBJ)
mkdir -p $(BUILD_DIR)
$(CXX) $(CXXFLAGS) $^ -o $@ $(LDFLAGS)
%.o: %.cpp # Build object files
$(CC) $(CFLAGS) -c -o $@ $^ $(BUILD_DIR)/%.o: $(SRC_DIR)/%.cpp
mkdir -p $(BUILD_DIR)
$(CXX) $(CXXFLAGS) -c $< -o $@
default: debug # Clean up build files
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: clean:
rm -f *.o app rm -rf $(BUILD_DIR)
.PHONY: debugger # Run the application
debugger: debug run: $(TARGET)
PATH=/usr/bin /usr/bin/lldb ./app ./$(TARGET)
.PHONY: all clean run

View File

@ -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 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() // Destructor
{ IndexBuffer::~IndexBuffer() {
std::cout << "m_RendererID: " << &m_RendererID << " " << m_RendererID << std::endl; if (m_RendererID != 0) { // Only delete if valid
GLCall(glDeleteBuffers(1, &m_RendererID)); 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 void IndexBuffer::Bind() const

View File

@ -6,11 +6,19 @@ public:
IndexBuffer(const unsigned int* data, unsigned int count); IndexBuffer(const unsigned int* data, unsigned int count);
~IndexBuffer(); ~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 Bind() const;
void Unbind() const; void Unbind() const;
inline unsigned int GetCount() const { return m_Count; } inline unsigned int GetCount() const { return m_Count; }
private: private:
unsigned int m_RendererID; unsigned int m_RendererID = 0;
unsigned int m_Count; unsigned int m_Count = 0;
}; };

View File

@ -4,7 +4,7 @@
void GLClearError() { void GLClearError() {
//while (glGetError() != GL_NO_ERROR); while (glGetError() != GL_NO_ERROR);
} }

View File

@ -3,7 +3,11 @@
VertexArray::VertexArray() 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) { if (!m_RendererID) {
std::cerr << "Failed to generate VAO" << std::endl; std::cerr << "Failed to generate VAO" << std::endl;
} }

View File

@ -2,7 +2,9 @@
int main(int argc, char* argv[]) { int main(int argc, char* argv[]) {
// Create an instance of our SdlWindow class // Create an instance of our SdlWindow class
std::cout << "starting" << std::endl;
SdlWindow window("My SDL2 Window", 800, 600); SdlWindow window("My SDL2 Window", 800, 600);
std::cout << "About to run: " << std::endl;
// Run the main loop // Run the main loop
window.run(); window.run();

View File

@ -51,25 +51,30 @@ struct ShaderProgramSource {
}; };
SdlWindow::SdlWindow(const char* title, int width, int height) SdlWindow::SdlWindow(const char* title, int width, int height)
: m_window(nullptr), : m_window(nullptr),
m_renderer(nullptr), m_renderer(nullptr),
m_isRunning(false), m_isRunning(false),
m_isFullscreen(false), m_isFullscreen(false),
m_width(width), m_width(width),
m_height(height), m_height(height),
m_glContext(nullptr), m_windowedWidth(width),
m_windowedWidth(width), m_windowedHeight(height),
m_windowedHeight(height), r(0.5f),
r(0.5f), m_glContext(nullptr),
location(), increment(0.05f),
increment(0.05f), vao(0),
m_ib(nullptr, 0) layout(nullptr),
va(nullptr),
m_ib(nullptr)
{ {
std::cout << "Step 0: hellow world" << std::endl;
// 1. Set attributes // 1. Set attributes
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_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_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 // 2. Create the window with OpenGL flag
m_window = SDL_CreateWindow(title, m_window = SDL_CreateWindow(title,
SDL_WINDOWPOS_CENTERED, 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); SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN| SDL_WINDOW_RESIZABLE);
if (!m_window) { if (!m_window) {
std::cerr << "Failed to create window: " << SDL_GetError() << std::endl; std::cerr << "Failed to create window: " << SDL_GetError() << std::endl;
return; return;
} }
std::cout << "Step 2: SDL_CreateWindow completed" << std::endl;
// 3. Create OpenGL context
m_glContext = SDL_GL_CreateContext(m_window); m_glContext = SDL_GL_CreateContext(m_window);
if (!m_glContext) { if (!m_glContext) {
std::cerr << "Failed to create GL context: " << SDL_GetError() << std::endl; std::cerr << "Failed to create GL context: " << SDL_GetError() << std::endl;
return; 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__ #ifndef __APPLE__
glewExperimental = GL_TRUE; glewExperimental = GL_TRUE;
GLenum glewErr = glewInit(); GLenum glewErr = glewInit();
if (glewInit() != GLEW_OK) { if (glewErr != GLEW_OK) {
std::cerr << "Failed to init GLEW" << glewGetErrorString(glewErr) << std::endl; std::cerr << "Failed to init GLEW: " << glewGetErrorString(glewErr) << std::endl;
return; return;
} }
glGetError(); std::cout << "Step 5: GLEW initialized successfully" << std::endl;
glGetError(); // Clear GLEW's initial error
#endif #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) // 5. Set vsync (optional)
SDL_GL_SetSwapInterval(1); //Vsync SDL_GL_SetSwapInterval(1); //Vsync
SdlWindow::GLClearError();
// 6. Mark as running // 6. Mark as running
m_isRunning = true; m_isRunning = true;
@ -122,8 +139,9 @@ SdlWindow::SdlWindow(const char* title, int width, int height)
VertexArray va; VertexArray va;
VertexBuffer vb(positions, 4 * 2 * sizeof(float)); VertexBuffer vb(positions, 4 * 2 * sizeof(float));
IndexBuffer ib(indices, 6); m_ib = new IndexBuffer(indices, 6);
m_ib = ib;
VertexBufferLayout layout; VertexBufferLayout layout;
layout.Push<float>(2); layout.Push<float>(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 << "VERTEX" << std::endl << source.VertexSource << std::endl;
std::cout << "FRAGMENT" << std::endl << source.FragmentSource << std::endl; std::cout << "FRAGMENT" << std::endl << source.FragmentSource << std::endl;
unsigned int m_ShaderID = createShader(source.VertexSource, source.FragmentSource); unsigned int shader = createShader(source.VertexSource, source.FragmentSource);
GLCall(glUseProgram(m_ShaderID)); 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 ASSERT(location != -1); // -1 is an error
GLCall(glUniform4f(location, 0.8f, 0.3f, 0.8f, 1.0f)); 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() { SdlWindow::~SdlWindow() {
// If using SDL Renderer, destroy it. But if youre purely using OpenGL, you might remove it. // If using SDL Renderer, destroy it. But if youre purely using OpenGL, you might remove it.
if (m_renderer) { if (m_renderer) {
@ -172,11 +190,15 @@ SdlWindow::~SdlWindow() {
glDeleteProgram(shader); glDeleteProgram(shader);
shader = 0; shader = 0;
} }
if (m_ib) {
delete m_ib;
m_ib = nullptr;
}
SDL_Quit(); SDL_Quit();
} }
//
//
void SdlWindow::run() { void SdlWindow::run() {
while (m_isRunning) { while (m_isRunning) {
processEvents(); processEvents();
@ -185,7 +207,7 @@ void SdlWindow::run() {
} }
GLCall(glDeleteProgram(shader)); GLCall(glDeleteProgram(shader));
} }
//
void SdlWindow::processEvents() { void SdlWindow::processEvents() {
SDL_Event event; SDL_Event event;
while (SDL_PollEvent(&event)) { while (SDL_PollEvent(&event)) {
@ -231,7 +253,7 @@ SDL_Event event;
} }
} }
} }
//
void SdlWindow::update() { void SdlWindow::update() {
// Update game/application logic here // Update game/application logic here
if (r > 1.0f) { if (r > 1.0f) {
@ -241,7 +263,7 @@ void SdlWindow::update() {
} }
r += increment; r += increment;
} }
//
void SdlWindow::render() { void SdlWindow::render() {
// Use GL calls instead of SDLs renderer // Use GL calls instead of SDLs renderer
GLCall(glClearColor(0.0f, 0.0f, 0.0f, 1.0f)); //background 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(glClear(GL_COLOR_BUFFER_BIT));
GLCall(glUseProgram(shader)); 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)); GLCall(glUniform4f(location, r, 0.3f, 0.8f, 1.0f));
va.Bind(); va->Bind();
m_ib.Bind(); m_ib->Bind();
// TODO: Draw with OpenGL here (shaders, triangles, etc.) // TODO: Draw with OpenGL here (shaders, triangles, etc.)
//glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr); //glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr);
GLCall(glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr)); //macro assert for debugging GLCall(glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr)); //macro assert for debugging
@ -260,7 +284,7 @@ void SdlWindow::render() {
// Swap buffers // Swap buffers
SDL_GL_SwapWindow(m_window); SDL_GL_SwapWindow(m_window);
} }
//
void SdlWindow::setFullscreen(bool fullscreen) { void SdlWindow::setFullscreen(bool fullscreen) {
if (m_window) { if (m_window) {
m_isFullscreen = fullscreen; m_isFullscreen = fullscreen;
@ -283,7 +307,7 @@ void SdlWindow::setFullscreen(bool fullscreen) {
} }
} }
} }
//
unsigned int SdlWindow::compileShader(unsigned int type, const std::string& source) { unsigned int SdlWindow::compileShader(unsigned int type, const std::string& source) {
GLCall(unsigned int id = glCreateShader(type)); GLCall(unsigned int id = glCreateShader(type));
const char* src = source.c_str(); // <--- this string needs to exist when compiling/running 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() { void SdlWindow::GLClearError() {
//while (glGetError() != GL_NO_ERROR); while (glGetError() != GL_NO_ERROR);
} }

View File

@ -56,7 +56,7 @@ private:
float r; float r;
SDL_GLContext m_glContext; SDL_GLContext m_glContext;
float increment; float increment;
// temp shader stuff // // temp shader stuff
std::string vetexShader; std::string vetexShader;
std::string fragmentShader; std::string fragmentShader;
unsigned int buffer; unsigned int buffer;
@ -64,9 +64,9 @@ private:
unsigned int vao; unsigned int vao;
unsigned int shader; unsigned int shader;
unsigned int location; unsigned int location;
VertexBufferLayout layout; VertexBufferLayout* layout;
VertexArray va; VertexArray* va;
IndexBuffer m_ib; IndexBuffer* m_ib;
// Private methods // Private methods
void processEvents(); void processEvents();