I have checked the entire codebase and have not been able to recognize the problem.
Here’s the main part where I hypothesize it lies:
unsigned int vertexShader;
if(compileVertexShader(&vertexShader, vertexShaderSource) == FAIL)
{
return FAIL;
}
unsigned int fragmentShader;
if(compileFragmentShader(&fragmentShader, fragmentShaderSource) == FAIL)
{
return FAIL;
}
unsigned int shaderProgram;
shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
if(checkShaderProgramSuccess(shaderProgram) == FAIL)
{
return FAIL;
}
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
unsigned int VBO;
unsigned int VAO;
unsigned int EBO;
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glGenBuffers(1, &EBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(rectangle.vertices), rectangle.vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(rectangle.indices), rectangle.indices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
while(!glfwWindowShouldClose(window))
{
windowRender(window, shaderProgram, VBO, EBO);
glfwPollEvents();
}
printf("Program closing due to user input. The program ran successfully without error.\n");
cleanup();
return SUCCESS;
And here’s the entire codebase
main.c
#include "main.h"
#include "window.h"
#include "display.h"
#include "shaders.h"
// gcc Assets/Code/main.c Assets/Code/window.c Assets/Code/display.c Assets/Code/shaders.c -lGLEW -lGL -lglfw -o "Game" -Wall
const char* vertexShaderSource = "#version 330 core\n"
"layout (location = 0) in vec3 aPos;\n"
"void main()\n"
"{\n"
" gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);\n"
"}\0";
const char* fragmentShaderSource = "#version 330 core\n"
"out vec4 FragColor;\n"
"void main()\n"
"{\n"
"FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);\n"
"}\0";
GLFWwindow* window;
float test_rectangle_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 test_rectangle_indices[] = {
0, 1, 3,
1, 2, 3
};
void cleanup()
{
if(window)
{
glfwDestroyWindow(window);
}
glfwTerminate();
}
void print_glfw_error()
{
const char* error_ptr;
glfwGetError(&error_ptr);
printf("%s\n", error_ptr);
}
void print_glew_error(GLenum error)
{
printf("%s\n", glewGetErrorString(error));
}
bool initialize_glew()
{
// GLAD is not very glad, GLEW is what makes me glad
GLenum glewinit_return_value = glewInit();
if(glewinit_return_value != GLEW_OK)
{
print_glew_error(glewinit_return_value);
handle_error(true, true); // clean up, and the error was fatal
return FAIL;
}
return SUCCESS;
}
void handle_error(bool is_cleanup, bool is_fatal)
{
if(is_fatal)
{
printf("Fatal error. Program aborted.\n");
}
if(is_cleanup)
{
cleanup();
}
}
void createShape(Shape* rectangle, float* shape_vertices, unsigned int* shape_indices)
{
printf("Creating shape...\n");
rectangle->vertices = shape_vertices;
rectangle->indices = shape_indices;
printf("Shape created.\n");
}
int main()
{
if(!glfwInit())
{
print_glfw_error();
handle_error(false, true); // do not clean up, and the error was fatal
return FAIL;
}
window = createWindow();
if(window == NULL)
{
return FAIL;
}
if(initialize_glew() == FAIL)
{
return FAIL;
}
glViewport(0, 0, 1920, 1080);
Shape rectangle;
createShape(&rectangle, test_rectangle_vertices, test_rectangle_indices);
unsigned int vertexShader;
if(compileVertexShader(&vertexShader, vertexShaderSource) == FAIL)
{
return FAIL;
}
unsigned int fragmentShader;
if(compileFragmentShader(&fragmentShader, fragmentShaderSource) == FAIL)
{
return FAIL;
}
unsigned int shaderProgram;
shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
if(checkShaderProgramSuccess(shaderProgram) == FAIL)
{
return FAIL;
}
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
unsigned int VBO;
unsigned int VAO;
unsigned int EBO;
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glGenBuffers(1, &EBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(rectangle.vertices), rectangle.vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(rectangle.indices), rectangle.indices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
while(!glfwWindowShouldClose(window))
{
windowRender(window, shaderProgram, VBO, EBO);
glfwPollEvents();
}
printf("Program closing due to user input. The program ran successfully without error.\n");
cleanup();
return SUCCESS;
}
display.c
#include "main.h"
// Rectangle's gone. This is depressing.
void windowRender(GLFWwindow* window, unsigned int shaderProgram, unsigned int VAO, unsigned int EBO)
{
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(shaderProgram);
glBindVertexArray(VAO);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glfwSwapBuffers(window);
}
#include "main.h"
// Please stop
bool compileVertexShader(unsigned int* vertexShaderInput, const char* vertexShaderSourceInput)
{
*vertexShaderInput = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(*vertexShaderInput, 1, &vertexShaderSourceInput, NULL);
glCompileShader(*vertexShaderInput);
int is_successful;
char infoLog[512];
glGetShaderiv(*vertexShaderInput, GL_COMPILE_STATUS, &is_successful);
if(!is_successful)
{
glGetShaderInfoLog(*vertexShaderInput, 512, NULL, infoLog);
printf("Vertex shader compilation failed. Error log is as follows:\n%s", infoLog);
handle_error(true, true); // clean up, and the error was fatal
return FAIL;
}
return SUCCESS;
}
bool compileFragmentShader(unsigned int* fragmentShaderInput, const char* fragmentShaderSourceInput)
{
*fragmentShaderInput = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(*fragmentShaderInput, 1, &fragmentShaderSourceInput, NULL);
glCompileShader(*fragmentShaderInput);
int is_successful;
char infoLog[512];
glGetShaderiv(*fragmentShaderInput, GL_COMPILE_STATUS, &is_successful);
if(!is_successful)
{
glGetShaderInfoLog(*fragmentShaderInput, 512, NULL, infoLog);
printf("Fragment shader compilation failed. Error log is as follows:\n%s", infoLog);
handle_error(true, true); // clean up, and the error was fatal
return FAIL;
}
return SUCCESS;
}
bool checkShaderProgramSuccess(unsigned int shaderProgram)
{
int is_successful;
char infoLog[512];
glGetProgramiv(shaderProgram, GL_LINK_STATUS, &is_successful);
if(!is_successful)
{
glGetShaderInfoLog(shaderProgram, 512, NULL, infoLog);
printf("Shader program compilation failed. Error log is as follows:\n%s", infoLog);
handle_error(true, true); // clean up, and the error was fatal
return FAIL;
}
return SUCCESS;
}
window.c
#include "main.h"
// Hours that the rectangle has been gone. It's just black. Darkness.
GLFWwindow* createWindow()
{
GLFWwindow* window = glfwCreateWindow(1920, 1080, "Badpa", NULL, NULL);
if(!window)
{
print_glfw_error();
handle_error(true, true); // clean up, and the error was fatal
return NULL;
}
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwMakeContextCurrent(window);
return window;
}
main.h
#pragma once
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#define SUCCESS 0
#define FAIL 1
void cleanup();
void handle_error(bool is_cleanup, bool is_fatal);
void print_glfw_error();
void print_glew_error(GLenum error);
bool initialize_glew();
typedef struct{
float* vertices;
unsigned int* indices;
} Shape;
window.h
#pragma once
GLFWwindow* createWindow();
shaders.h
#pragma once
bool compileVertexShader(unsigned int* vertexShaderInput, const char* vertexShaderSourceInput);
bool compileFragmentShader(unsigned int* fragmentShaderInput, const char* fragmentShaderSourceInput);
bool checkShaderProgramSuccess(unsigned int shaderProgram);
display.h
#pragma once
bool windowRender(GLFWwindow* window, unsigned int shaderProgram, unsigned int VAO, unsigned int EBO);