From 43d365eef447faf70ceefde685c0acdfd5d6817e Mon Sep 17 00:00:00 2001 From: Luca Conte Date: Thu, 6 Mar 2025 02:36:43 +0100 Subject: [PATCH] introduction done --- src/log.h | 10 +++--- src/main.c | 72 +++++++++++++++++++++++++++++++++++---- src/shader.c | 65 ++++++++++++++++++++++++++++------- src/shader.h | 6 ++++ src/shaders/fragment.glsl | 5 +++ src/shaders/vertex.glsl | 3 +- 6 files changed, 135 insertions(+), 26 deletions(-) create mode 100644 src/shaders/fragment.glsl diff --git a/src/log.h b/src/log.h index df86aa2..fe54fee 100644 --- a/src/log.h +++ b/src/log.h @@ -22,10 +22,10 @@ extern unsigned int logLevel; #define DEBUG_COL "\x1B[90m" #define NORMAL_COL "\x1B[0m" -#define FATAL(...) if (logLevel >= LOG_LEVEL_FATAL) { printf("| %sFATAL%s | ", FATAL_COL, NORMAL_COL); printf(__VA_ARGS__); } -#define ERROR(...) if (logLevel >= LOG_LEVEL_ERROR) { printf("| %sERROR%s | ", ERROR_COL, NORMAL_COL); printf(__VA_ARGS__); } -#define WARN(...) if (logLevel >= LOG_LEVEL_WARN) { printf("| %sWARN%s | ", WARN_COL, NORMAL_COL); printf(__VA_ARGS__); } -#define INFO(...) if (logLevel >= LOG_LEVEL_INFO) { printf("| %sINFO%s | ", INFO_COL, NORMAL_COL); printf(__VA_ARGS__); } -#define DEBUG(...) if (logLevel >= LOG_LEVEL_DEBUG) { printf("| %sDEBUG%s | ", DEBUG_COL, NORMAL_COL); printf(__VA_ARGS__); } +#define FATAL(...) if (logLevel >= LOG_LEVEL_FATAL) { printf("| %sFATAL%s | ", FATAL_COL, NORMAL_COL); printf(__VA_ARGS__); printf("\n"); } +#define ERROR(...) if (logLevel >= LOG_LEVEL_ERROR) { printf("| %sERROR%s | ", ERROR_COL, NORMAL_COL); printf(__VA_ARGS__); printf("\n"); } +#define WARN(...) if (logLevel >= LOG_LEVEL_WARN) { printf("| %sWARN%s | ", WARN_COL, NORMAL_COL); printf(__VA_ARGS__); printf("\n"); } +#define INFO(...) if (logLevel >= LOG_LEVEL_INFO) { printf("| %sINFO%s | ", INFO_COL, NORMAL_COL); printf(__VA_ARGS__); printf("\n"); } +#define DEBUG(...) if (logLevel >= LOG_LEVEL_DEBUG) { printf("| %sDEBUG%s | ", DEBUG_COL, NORMAL_COL); printf(__VA_ARGS__); printf("\n"); } #endif // LOG_H \ No newline at end of file diff --git a/src/main.c b/src/main.c index f5cbcbe..c439faf 100644 --- a/src/main.c +++ b/src/main.c @@ -7,37 +7,93 @@ #include "log.h" #include "src/shader.h" +GLuint program; + +GLuint vertexArrayObject; + +GLuint initialWindowWidth = 800; +GLuint initialWindowHeight = 600; + void init(void) { - INFO("Compiling Shaders...\n"); + INFO("Compiling Shaders..."); // create and compile vertex shader - INFO("Compiling Vertex Shader...\n"); + INFO("Compiling Vertex Shader..."); ShaderCompileResult vertexShader = readAndCompileShaderFromFile("src/shaders/vertex.glsl", GL_VERTEX_SHADER); if (!vertexShader.success) { - FATAL("Failed to compile Vertex Shader\n"); + FATAL("Failed to compile Vertex Shader"); exit(1); } // create and compile fragment shader - INFO("Compiling Fragment Shader...\n"); + INFO("Compiling Fragment Shader..."); ShaderCompileResult fragmentShader = readAndCompileShaderFromFile("src/shaders/fragment.glsl", GL_FRAGMENT_SHADER); if (!fragmentShader.success) { - FATAL("Failed to compile Vertex Shader\n"); + FATAL("Failed to compile Vertex Shader"); exit(1); } // create and link shader program + INFO("Linking Shader Program..."); + ProgramLinkResult linkResult = linkShaderProgram(vertexShader.shader, fragmentShader.shader); + if (!linkResult.success) { + FATAL("Failed to link Program"); + exit(1); + } + + program = linkResult.program; + + INFO("Shader Program Done."); // create triangle buffer + GLfloat triangleVertices[] = + { + //X //Y // R //G /B + 0.0f, 0.5f, 0.0f, 1.0f, 1.0f, + -0.5f, -0.5f, 1.0f, 0.0f, 1.0f, + 0.5f, -0.5f, 1.0f, 1.0f, 0.0f + }; + + GLuint vertexBuffer; + glGenBuffers(1, &vertexBuffer); + glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(triangleVertices), triangleVertices, GL_STATIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, 0); // create vertex array object + glGenVertexArrays(1, &vertexArrayObject); + glBindVertexArray(vertexArrayObject); + glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer); + + // vertex position data + glVertexAttribPointer( + 0, // shader location + 2, // number of values to read + GL_FLOAT, // type of value + GL_FALSE, // if values are normalised + 5 * sizeof(GLfloat), // stride - distance between vertices + 0 // start offset + ); + glEnableVertexAttribArray(0); + + // vertex color data + glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)(2 * sizeof(GLfloat))); + glEnableVertexAttribArray(1); + + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindVertexArray(0); glClearColor(0.1f, 0.1f, 0.1f, 1.0f); + glViewport(0, 0, initialWindowWidth, initialWindowHeight); } void draw(void) { glClear(GL_COLOR_BUFFER_BIT); + glUseProgram(program); + + glBindVertexArray(vertexArrayObject); + glDrawArrays(GL_TRIANGLES, 0, 3); } void framebuffer_size_callback(GLFWwindow* window, int width, int height) { @@ -56,14 +112,16 @@ int main(int argc, char const *argv[]) } } + INFO("Creating GLFW Window"); + glfwInit(); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); - GLFWwindow *window = glfwCreateWindow(800, 600, "CG1", NULL, NULL); + GLFWwindow *window = glfwCreateWindow(initialWindowWidth, initialWindowHeight, "CG1", NULL, NULL); if (!window) { - printf("Failed to open window\n"); + FATAL("Failed to open window"); glfwTerminate(); return 1; } diff --git a/src/shader.c b/src/shader.c index 9f79539..1c36ccf 100644 --- a/src/shader.c +++ b/src/shader.c @@ -40,39 +40,78 @@ const char* readFileToMemory(const char* filepath) { ShaderCompileResult readAndCompileShaderFromFile(const char* filepath, GLenum shaderType) { ShaderCompileResult result = { .success = false, .shader = 0 }; // Initialize result to indicate failure by default - DEBUG("%s - Reading shader\n", filepath); + DEBUG("%s - Reading shader", filepath); const char* shaderSource = readFileToMemory(filepath); if (!shaderSource) { - FATAL("Could not read shader source file\n"); + FATAL("Could not read shader source file"); return result; } GLint shaderSize = strlen(shaderSource); - DEBUG("%s - Creating shader\n", filepath); - GLuint shader = glCreateShader(shaderType); + DEBUG("%s - Creating shader", filepath); + result.shader = glCreateShader(shaderType); - DEBUG("%s - Applying shader source\n", filepath); - glShaderSource(shader, 1, &shaderSource, &shaderSize); + DEBUG("%s - Applying shader source", filepath); + glShaderSource(result.shader, 1, &shaderSource, &shaderSize); - DEBUG("%s - Compiling shader\n", filepath); - glCompileShader(shader); + DEBUG("%s - Compiling shader", filepath); + glCompileShader(result.shader); GLint status; - glGetShaderiv(shader, GL_COMPILE_STATUS, &status); + glGetShaderiv(result.shader, GL_COMPILE_STATUS, &status); if (!status) { - FATAL("Error compiling shader:\n"); + FATAL("Error compiling shader:"); GLchar infoLog[1024]; - glGetShaderInfoLog(shader, 1024, NULL, infoLog); + glGetShaderInfoLog(result.shader, 1024, NULL, infoLog); FATAL("%s", infoLog); result.success = false; } else { - DEBUG("%s - Successfully compiled shader\n", filepath); + DEBUG("%s - Successfully compiled shader", filepath); result.success = true; } - result.shader = shader; // Return the shader ID regardless of success or failure return result; // Return the ShaderCompileResult struct +} + +ProgramLinkResult linkShaderProgram(GLuint vertexShader, GLuint fragmentShader) { + ProgramLinkResult result = { .success = false, .program = 0 }; + + DEBUG("Creating program"); + result.program = glCreateProgram(); + + DEBUG("Attaching Vertex Shader"); + glAttachShader(result.program, vertexShader); + + DEBUG("Attaching Fragment Shader"); + glAttachShader(result.program, fragmentShader); + + DEBUG("Linking Program"); + glLinkProgram(result.program); + + GLint status; + glGetProgramiv(result.program, GL_LINK_STATUS, &status); + if (!status) { + FATAL("Error linking program:"); + GLchar infoLog[1024]; + glGetProgramInfoLog(result.program, 1024, NULL, infoLog); + FATAL("%s", infoLog); + return result; + } + + DEBUG("Validating Program"); + glValidateProgram(result.program); + glGetProgramiv(result.program, GL_VALIDATE_STATUS, &status); + if (!status) { + FATAL("Error validating program:"); + GLchar infoLog[1024]; + glGetProgramInfoLog(result.program, 1024, NULL, infoLog); + FATAL("%s", infoLog); + return result; + } + + result.success = true; + return result; } \ No newline at end of file diff --git a/src/shader.h b/src/shader.h index 86c32bc..a541b32 100644 --- a/src/shader.h +++ b/src/shader.h @@ -9,7 +9,13 @@ typedef struct { GLuint shader; } ShaderCompileResult; +typedef struct { + bool success; + GLuint program; +} ProgramLinkResult; + extern const char* readFileToMemory(const char* filepath); extern ShaderCompileResult readAndCompileShaderFromFile(const char* filepath, GLenum shaderType); +extern ProgramLinkResult linkShaderProgram(GLuint vertexShader, GLuint fragmentShader); #endif // SHADER_H \ No newline at end of file diff --git a/src/shaders/fragment.glsl b/src/shaders/fragment.glsl new file mode 100644 index 0000000..f569c18 --- /dev/null +++ b/src/shaders/fragment.glsl @@ -0,0 +1,5 @@ +#version 330 core +in vec3 vertexColor; +void main() { + gl_FragColor = vec4(vertexColor, 1.0); +} \ No newline at end of file diff --git a/src/shaders/vertex.glsl b/src/shaders/vertex.glsl index efc881d..fed0545 100644 --- a/src/shaders/vertex.glsl +++ b/src/shaders/vertex.glsl @@ -1,9 +1,10 @@ #version 330 core layout (location = 0) in vec2 aPosition; +layout (location = 1) in vec3 aColor; out vec3 vertexColor; void main() { - vertexColor = vec3(1.0, 0.0, 0.0); + vertexColor = aColor; gl_Position = vec4(aPosition, 0.0, 1.0); } \ No newline at end of file