openGL abstractiopn, segment fault!!

This commit is contained in:
MichaelFisher1997 2025-01-11 17:48:48 +00:00
parent c8764b135a
commit ed1cc02d3e
17 changed files with 452 additions and 66 deletions

16
.vscode/c_cpp_properties.json vendored Normal file
View File

@ -0,0 +1,16 @@
{
"configurations": [
{
"name": "linux-gcc-x64",
"includePath": [
"${workspaceFolder}/**"
],
"defines": [],
"compilerPath": "/nix/store/xcn9p4xxfbvlkpah7pwchpav4ab9d135-gcc-wrapper-14-20241116/bin/gcc",
"cStandard": "c17",
"cppStandard": "gnu++17",
"intelliSenseMode": "linux-gcc-x64"
}
],
"version": 4
}

55
.vscode/launch.json vendored Normal file
View File

@ -0,0 +1,55 @@
{
"version": "0.2.0",
"configurations": [
{
"type": "cppdbg",
"request": "launch",
"name": "Launch Program",
"program": "${workspaceFolder}/build/${input:executableName}",
"preLaunchTask": "build",
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
],
"miDebuggerPath": "/usr/bin/gdb",
"logging": {
"engineLogging": true
}
},
{
"name": "C/C++ Runner: Debug Session",
"type": "cppdbg",
"request": "launch",
"args": [],
"stopAtEntry": false,
"externalConsole": false,
"cwd": "/home/micqdf/opengl/cpp/src",
"program": "/home/micqdf/opengl/cpp/src/build/Debug/outDebug",
"MIMode": "gdb",
"miDebuggerPath": "/nix/store/xcn9p4xxfbvlkpah7pwchpav4ab9d135-gdb-wrapper-14-20241116/bin/gcc",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
]
}
],
"inputs": [
{
"type": "promptString",
"id": "executableName",
"description": "Name of your executable"
}
]
}

61
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,61 @@
{
"C_Cpp_Runner.cCompilerPath": "/nix/store/xcn9p4xxfbvlkpah7pwchpav4ab9d135-gcc-wrapper-14-20241116/bin/gcc",
"C_Cpp_Runner.cppCompilerPath": "/nix/store/xcn9p4xxfbvlkpah7pwchpav4ab9d135-g++-wrapper-14-20241116/bin/gcc",
"C_Cpp_Runner.debuggerPath": "/nix/store/xcn9p4xxfbvlkpah7pwchpav4ab9d135-gdb-wrapper-14-20241116/bin/gcc",
"C_Cpp_Runner.cStandard": "c17",
"C_Cpp_Runner.cppStandard": "gnu++17",
"C_Cpp_Runner.msvcBatchPath": "",
"C_Cpp_Runner.useMsvc": false,
"C_Cpp_Runner.warnings": [
"-Wall",
"-Wextra",
"-Wpedantic",
"-Wshadow",
"-Wformat=2",
"-Wcast-align",
"-Wconversion",
"-Wsign-conversion",
"-Wnull-dereference"
],
"C_Cpp_Runner.msvcWarnings": [
"/W4",
"/permissive-",
"/w14242",
"/w14287",
"/w14296",
"/w14311",
"/w14826",
"/w44062",
"/w44242",
"/w14905",
"/w14906",
"/w14263",
"/w44265",
"/w14928"
],
"C_Cpp_Runner.enableWarnings": true,
"C_Cpp_Runner.warningsAsError": false,
"C_Cpp_Runner.compilerArgs": [],
"C_Cpp_Runner.linkerArgs": [],
"C_Cpp_Runner.includePaths": [
"${workspaceFolder}/**"
],
"C_Cpp_Runner.includeSearch": [
"*",
"**/*"
],
"C_Cpp_Runner.excludeSearch": [
"**/build",
"**/build/**",
"**/.*",
"**/.*/**",
"**/.vscode",
"**/.vscode/**"
],
"C_Cpp_Runner.useAddressSanitizer": false,
"C_Cpp_Runner.useUndefinedSanitizer": false,
"C_Cpp_Runner.useLeakSanitizer": false,
"C_Cpp_Runner.showCompilationTime": false,
"C_Cpp_Runner.useLinkTimeOptimization": false,
"C_Cpp_Runner.msvcSecureNoWarnings": false
}

View File

@ -1,41 +0,0 @@
# A simple Makefile for compiling small SDL projects
# set the compiler
CC := clang
# set the compiler flags
CFLAGS := `sdl2-config --libs --cflags` -ggdb3 -O0 --std=c99 -Wall -lSDL2_image -lm
# add header files here
HDRS :=
# add source files here
SRCS := #file-name.c
# generate names of object files
OBJS := $(SRCS:.c=.o)
# name of executable
EXEC := #name your executable file
# default recipe
all: $(EXEC)
showfont: showfont.c Makefile
$(CC) -o $@ $@.c $(CFLAGS) $(LIBS)
glfont: glfont.c Makefile
$(CC) -o $@ $@.c $(CFLAGS) $(LIBS)
# recipe for building the final executable
$(EXEC): $(OBJS) $(HDRS) Makefile
$(CC) -o $@ $(OBJS) $(CFLAGS)
# recipe for building object files
#$(OBJS): $(@:.o=.c) $(HDRS) Makefile
# $(CC) -o $@ $(@:.o=.c) -c $(CFLAGS)
# recipe to clean the workspace
clean:
rm -f $(EXEC) $(OBJS)
.PHONY: all clean

21
Makefile Executable file
View File

@ -0,0 +1,21 @@
CC = g++
CFLAGS = -Iinclude -Wall -g
LDFLAGS = -lSDL2 -lGL -lGLEW
SRC = src/main.cpp src/sdl.cpp
OBJ = $(SRC:.cpp=.o)
EXEC = opengl-app
all: $(EXEC)
$(EXEC): $(OBJ)
$(CC) -o $@ $^ $(LDFLAGS)
%.o: %.cpp
$(CC) $(CFLAGS) -c $< -o $@
clean:
rm -f $(OBJ) $(EXEC)
run: all
./$(EXEC)

27
src/IndexBuffer.cpp Normal file
View File

@ -0,0 +1,27 @@
#include "IndexBuffer.h"
#include "Renderer.h"
IndexBuffer::IndexBuffer(const unsigned int* data, unsigned int count)
: m_Count(count)
{
//ASSERT(sizeof(unsigned int) == sizeof(GLuint));
//
GLCall(glGenBuffers(1, &m_RendererID));
GLCall(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_RendererID)); //select buffer called 'buffer'
GLCall(glBufferData(GL_ELEMENT_ARRAY_BUFFER, count * sizeof(GLuint), data, GL_STATIC_DRAW)); // assigne buffer size, static as we use many times, but does not change
}
IndexBuffer::~IndexBuffer()
{
GLCall(glDeleteBuffers(1, &m_RendererID));
}
void IndexBuffer::Bind() const
{
GLCall(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_RendererID)); //select buffer called 'buffer'
}
void IndexBuffer::Unbind() const
{
GLCall(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); //select buffer called 'buffer'
}

16
src/IndexBuffer.h Normal file
View File

@ -0,0 +1,16 @@
#pragma once
class IndexBuffer
{
private:
unsigned int m_RendererID;
unsigned int m_Count;
public:
IndexBuffer(const unsigned int* data, unsigned int count);
~IndexBuffer();
void Bind() const;
void Unbind() const;
inline unsigned int GetCount() const { return m_Count; }
};

19
src/Renderer.cpp Normal file
View File

@ -0,0 +1,19 @@
#include "Renderer.h"
void GLClearError() {
while (glGetError() != GL_NO_ERROR);
}
bool GLLogCall() {
Color::Modifier red(Color::FG_RED);
Color::Modifier def(Color::FG_DEFAULT);
while (GLenum error = glGetError()) {
std::cout << red << "[OpenGL Error] (" << error << ")" << def << std::endl; //if error, it will return a number, this needs to be converted to hex to then look up that value inn GL docs
return false;
}
return true;
}

37
src/Renderer.h Normal file
View File

@ -0,0 +1,37 @@
#pragma once
#include "colormod.h"
#include <iostream>
#include <GL/glew.h>
#if defined(_MSC_VER) // Microsoft Visual C++
#include <intrin.h>
#define DEBUG_BREAK() __debugbreak()
#elif defined(__i386__) || defined(__x86_64__)
// Use inline assembly for x86/x86_64
#define DEBUG_BREAK() __asm__ volatile("int3")
#else
// Fallback on non-x86 platforms
#include <signal.h>
#define DEBUG_BREAK() raise(SIGTRAP)
#endif
// ASSERT macro that shows file, line, and the failed expression
#define ASSERT(x) \
do { \
if (!(x)) { \
std::cerr << "Assertion Failed: " << #x << '\n' \
<< "File: " << __FILE__ << '\n' \
<< "Line: " << __LINE__ << std::endl; \
DEBUG_BREAK(); \
} \
} while (false)
#define GLCall(x) GLClearError();\
x;\
ASSERT(GLLogCall())
void GLClearError();
bool GLLogCall();

39
src/VertexArray.cpp Normal file
View File

@ -0,0 +1,39 @@
#include "VertexArray.h"
#include "VertexBuffer.h"
#include "Renderer.h"
#include "VertexBufferLayout.h"
VertexArray::VertexArray()
{
GLCall(glGenVertexArrays(1, &m_RendererID));
if (!m_RendererID) {
std::cerr << "Failed to generate VAO" << std::endl;
}
}
VertexArray::~VertexArray()
{
GLCall(glDeleteVertexArrays(1, &m_RendererID));
}
void VertexArray::AddBuffer(const VertexBuffer& vb, const VertexBufferLayout& layout)
{
Bind();
vb.Bind();
const auto& elements = layout.GetElements();
GLsizei offset = 0;
for (unsigned int i = 0; i < elements.size(); i++) {
const auto& element = elements[i];
GLCall(glEnableVertexAttribArray(i));
GLCall(glVertexAttribPointer(i, element.count, element.type, element.normalized, layout.GetStride(), (const void*)offset));
offset += element.count * VertexBufferElement::GetSizeOfType(element.type);
}
}
void VertexArray::Bind() const {
GLCall(glBindVertexArray(m_RendererID));
}
void VertexArray::Unbind() const {
GLCall(glBindVertexArray(0));
}

18
src/VertexArray.h Normal file
View File

@ -0,0 +1,18 @@
#pragma once
#include "VertexBuffer.h"
#include "VertexBufferLayout.h"
class VertexArray
{
private:
unsigned int m_RendererID;
public:
VertexArray();
~VertexArray();
void AddBuffer(const VertexBuffer& vb, const VertexBufferLayout& layout);
void Bind() const;
void Unbind() const;
};

24
src/VertexBuffer.cpp Normal file
View File

@ -0,0 +1,24 @@
#include "VertexBuffer.h"
#include "Renderer.h"
VertexBuffer::VertexBuffer(const void* data, unsigned int size)
{
GLCall(glGenBuffers(1, &m_RendererID));
GLCall(glBindBuffer(GL_ARRAY_BUFFER, m_RendererID)); //select buffer called 'buffer'
GLCall(glBufferData(GL_ARRAY_BUFFER, size, data, GL_STATIC_DRAW)); // assigne buffer size, static as we use many times, but does not change
}
VertexBuffer::~VertexBuffer()
{
GLCall(glDeleteBuffers(1, &m_RendererID));
}
void VertexBuffer::Bind() const
{
GLCall(glBindBuffer(GL_ARRAY_BUFFER, m_RendererID)); //select buffer called 'buffer'
}
void VertexBuffer::Unbind() const
{
GLCall(glBindBuffer(GL_ARRAY_BUFFER, 0)); //select buffer called 'buffer'
}

13
src/VertexBuffer.h Normal file
View File

@ -0,0 +1,13 @@
#pragma once
class VertexBuffer
{
private:
unsigned int m_RendererID;
public:
VertexBuffer(const void* data, unsigned int size);
~VertexBuffer();
void Bind() const;
void Unbind() const;
};

56
src/VertexBufferLayout.h Normal file
View File

@ -0,0 +1,56 @@
#ifndef VERTEXBUFFERLAYOUT_H
#define VERTEXBUFFERLAYOUT_H
#include <vector>
#include "Renderer.h"
struct VertexBufferElement {
unsigned int type;
unsigned int count;
unsigned char normalized;
VertexBufferElement(unsigned int type, unsigned int count, unsigned char normalized)
: type(type), count(count), normalized(normalized) {}
static unsigned int GetSizeOfType(unsigned int type) {
switch (type) {
case GL_FLOAT: return sizeof(GLfloat);
case GL_UNSIGNED_INT: return sizeof(GLuint);
case GL_UNSIGNED_BYTE: return sizeof(GLubyte);
}
return 0;
}
};
class VertexBufferLayout {
public:
VertexBufferLayout() : m_Stride(0) {}
template<typename T>
void Push(int count);
inline const std::vector<VertexBufferElement>& GetElements() const { return m_Elements; }
inline unsigned int GetStride() const { return m_Stride; }
private:
std::vector<VertexBufferElement> m_Elements;
unsigned int m_Stride;
};
// Explicit specializations
template<>
inline void VertexBufferLayout::Push<float>(int count) {
m_Elements.push_back({ GL_FLOAT, static_cast<unsigned int>(count), GL_FALSE });
m_Stride += VertexBufferElement::GetSizeOfType(GL_FLOAT);
}
template<>
inline void VertexBufferLayout::Push<unsigned int>(int count) {
m_Elements.push_back({ GL_UNSIGNED_INT,static_cast<unsigned int>(count), GL_FALSE });
m_Stride += VertexBufferElement::GetSizeOfType(GL_UNSIGNED_INT);
}
template<>
inline void VertexBufferLayout::Push<unsigned char>(int count) {
m_Elements.push_back({ GL_UNSIGNED_BYTE, static_cast<unsigned int>(count), GL_TRUE });
m_Stride += VertexBufferElement::GetSizeOfType(GL_UNSIGNED_BYTE);
}
#endif // VERTEXBUFFERLAYOUT_H

View File

@ -1,3 +1,5 @@
#ifndef COLORMOD_H
#define COLORMOD_H
#include <ostream>
namespace Color {
enum Code {
@ -20,3 +22,4 @@ namespace Color {
}
};
}
#endif // COLORMOD_H

View File

@ -1,5 +1,6 @@
#include <GL/glew.h> // Include GLEW before <SDL2/SDL.h>?
#include "sdl.hpp"
#include "VertexBufferLayout.h"
#include "colormod.h"
#include <SDL2/SDL_video.h>
#include <alloca.h>
@ -54,9 +55,10 @@ SdlWindow::SdlWindow(const char* title, int width, int height)
m_glContext(nullptr),
m_windowedWidth(width),
m_windowedHeight(height),
r(0.0f),
r(0.5f),
location(),
increment(0.05f)
increment(0.05f),
ib(nullptr, 0)
{
// 1. Set attributes
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
@ -95,6 +97,7 @@ SdlWindow::SdlWindow(const char* title, int width, int height)
// 5. Set vsync (optional)
SDL_GL_SetSwapInterval(1); //Vsync
SdlWindow::GLClearError();
// 6. Mark as running
m_isRunning = true;
@ -111,28 +114,32 @@ SdlWindow::SdlWindow(const char* title, int width, int height)
0, 1, 2,
2, 3, 0
};
//vertex buffer
unsigned int buffer;
GLCall(glGenBuffers(1, &buffer));
GLCall(glBindBuffer(GL_ARRAY_BUFFER, buffer)); //select buffer called 'buffer'
GLCall(glBufferData(GL_ARRAY_BUFFER, 6 * 2 * sizeof(float), positions, GL_STATIC_DRAW)); // assigne buffer size, static as we use many times, but does not change
//vertext attributes / layout
GLCall(glEnableVertexAttribArray(0));
GLCall(glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 2, 0));
//indext beffer
unsigned int ibo; //indext buffer object
GLCall(glGenBuffers(1, &ibo));
GLCall(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo)); //select buffer called 'buffer'
GLCall(glBufferData(GL_ELEMENT_ARRAY_BUFFER, 6 * sizeof(unsigned int), indices, GL_STATIC_DRAW)); // assigne buffer size, static as we use many times, but does not change
unsigned int vao; //vertext array object
GLCall(glGenVertexArrays(1, &vao));
GLCall(glBindVertexArray(vao));
VertexArray va;
VertexBuffer vb(positions, 4 * 2 * sizeof(float));
VertexBufferLayout layout;
layout.Push<float>(2);
va.AddBuffer(vb, layout);
IndexBuffer ib(indices, 6);
ShaderProgramSource source = parseShader("res/shaders/Basic.shader");
unsigned int shader = createShader(source.VertexSource, source.FragmentSource);
GLCall(glUseProgram(shader));
unsigned int m_ShaderID = createShader(source.VertexSource, source.FragmentSource);
GLCall(glUseProgram(m_ShaderID));
GLCall(int location = glGetUniformLocation(shader, "u_Color"));
GLCall(int location = glGetUniformLocation(m_ShaderID, "u_Color"));
ASSERT(location != -1); // -1 is an error
GLCall(glUniform4f(location, 0.8f, 0.3f, 0.8f, 1.0f));
GLCall(glBindVertexArray(0));
GLCall(glUseProgram(0));
GLCall(glBindBuffer(GL_ARRAY_BUFFER, 0));
GLCall(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
}
@ -153,7 +160,12 @@ SdlWindow::~SdlWindow() {
SDL_DestroyWindow(m_window);
m_window = nullptr;
}
if (shader) {
glDeleteProgram(shader);
shader = 0;
}
delete &ib;
SDL_Quit();
}
@ -226,10 +238,15 @@ void SdlWindow::update() {
void SdlWindow::render() {
// Use GL calls instead of SDLs renderer
GLCall(glClearColor(0.0f, 0.0f, 0.0f, 1.0f)); //background
//
GLCall(glClear(GL_COLOR_BUFFER_BIT));
GLCall(glUseProgram(shader));
GLCall(glUniform4f(location, r, 0.3f, 0.8f, 1.0f));
va.Bind();
ib.Bind();
// TODO: Draw with OpenGL here (shaders, triangles, etc.)
GLCall(glUniform4f( location, r, 0.3f, 0.8f, 1.0f));
//glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr);
GLCall(glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr)); //macro assert for debugging

View File

@ -9,10 +9,10 @@
#include <GL/glew.h> // or <glad/glad.h> if using GLAD
#endif
//#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include "IndexBuffer.h"
#include "VertexBufferLayout.h"
#include "VertexArray.h"
// Forward declaration of classes and structs if needed
// class SomethingElse;
@ -54,14 +54,19 @@ private:
int m_windowedWidth; // stored width before fullscreen
int m_windowedHeight; // stored height before fullscreen
float r;
int location;
SDL_GLContext m_glContext;
float increment;
// temp shader stuff
std::string vetexShader;
std::string fragmentShader;
unsigned int shader;
unsigned int buffer;
unsigned int ibo;
unsigned int vao;
IndexBuffer ib; // pointer, no default constructor needed
unsigned int shader;
unsigned int location;
VertexBufferLayout layout;
VertexArray va;
// Private methods
void processEvents();