Code cleanup

This commit is contained in:
Marcel Plch 2023-12-13 10:56:21 +01:00
parent 75cedfea0e
commit 29251ba60c
Signed by: dormouse
GPG key ID: 2CA77596BC4BDFFE
9 changed files with 178 additions and 184 deletions

View file

@ -13,20 +13,20 @@ include_directories(
) )
set(ALL_LIBS set(ALL_LIBS
${OPENGL_LIBRARY} ${OPENGL_LIBRARY}
glfw glfw
GLEW GLEW
m m
) )
set(CMAKE_C_FLAGS "-O0 -ggdb -Wall") set(CMAKE_C_FLAGS "-O0 -ggdb -Wall")
add_definitions( add_definitions(
-DTW_STATIC -DTW_STATIC
-DTW_NO_LIB_PRAGMA -DTW_NO_LIB_PRAGMA
-DTW_NO_DIRECT3D -DTW_NO_DIRECT3D
-DGLEW_STATIC -DGLEW_STATIC
-D_CRT_SECURE_NO_WARNINGS -D_CRT_SECURE_NO_WARNINGS
) )
add_executable( add_executable(

View file

@ -13,6 +13,7 @@
#include <GL/glew.h> #include <GL/glew.h>
// Include GLFW // Include GLFW
#define GLFW_INCLUDE_VULKAN
#include <GLFW/glfw3.h> #include <GLFW/glfw3.h>
// Include project headers // Include project headers

View file

@ -6,7 +6,8 @@ typedef struct _model {
size_t bufsize; size_t bufsize;
} Model; } Model;
Model * model_load(const char *); Model *model_load(const char *);
int model_free(Model *);
#endif #endif

View file

@ -1,12 +1,8 @@
#version 330 core #version 330 core
in float colorF;
out vec3 color; out vec3 color;
void main() { void main() {
if (colorF == 0) color = vec3(1, 1, 1);
color = vec3(1, 1, 1);
else
color = vec3(0, 0, 0);
} }

236
src/cx.c
View file

@ -1,54 +1,53 @@
#include <cx.h> #include <cx.h>
int cx_glinit(GLFWwindow **window) { int cx_glinit(GLFWwindow **window) {
// Initialise GLFW // Initialise GLFW
if(!glfwInit()) { if(!glfwInit()) {
fprintf(stderr, "Failed to initialize GLFW\n"); fprintf(stderr, "Failed to initialize GLFW\n");
getchar(); getchar();
return -1; return -1;
} }
glfwWindowHint(GLFW_SAMPLES, 4); glfwWindowHint(GLFW_SAMPLES, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // To make MacOS happy; should not be needed glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // To make MacOS happy; should not be needed
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
// Open a window and create its OpenGL context // Open a window and create its OpenGL context
*window = glfwCreateWindow(1280, 720, "OpenGL Clock", NULL, NULL); *window = glfwCreateWindow(1280, 720, "CONTROL-X", NULL, NULL);
if (*window == NULL) { if (*window == NULL) {
fprintf(stderr, "Failed to open GLFW window.\n"); fprintf(stderr, "Failed to open GLFW window.\n");
glfwTerminate(); glfwTerminate();
return -1; return -1;
} }
glfwMakeContextCurrent(*window); glfwMakeContextCurrent(*window);
// Initialize GLEW // Initialize GLEW
if (glewInit() != GLEW_OK) { if (glewInit() != GLEW_OK) {
fprintf(stderr, "Failed to initialize GLEW\n"); fprintf(stderr, "Failed to initialize GLEW\n");
glfwTerminate(); glfwTerminate();
return -1; return -1;
} }
// Ensure we can capture the escape key being pressed below // Ensure we can capture the escape key being pressed below
glfwSetInputMode(*window, GLFW_STICKY_KEYS, GL_TRUE); glfwSetInputMode(*window, GLFW_STICKY_KEYS, GL_TRUE);
// Dark grey background // Dark grey background
glClearColor(0.15f, 0.15f, 0.15f, 0.0f); glClearColor(0.15f, 0.15f, 0.15f, 0.0f);
return 0; return 0;
} }
int cx_glrun(GLFWwindow *window) { int cx_glrun(GLFWwindow *window) {
GLuint VertexArrayID; GLuint VertexArrayID;
GLuint programID; GLuint programID;
glGenVertexArrays(1, &VertexArrayID);
glBindVertexArray(VertexArrayID);
glGenVertexArrays(1, &VertexArrayID); // Create and compile our GLSL program from the shaders
glBindVertexArray(VertexArrayID);
// Create and compile our GLSL program from the shaders
if (LoadShaders(&programID, if (LoadShaders(&programID,
"../shaders/SimpleVertexShader.vertexshader", "../shaders/SimpleVertexShader.vertexshader",
"../shaders/SimpleFragmentShader.fragmentshader")) { "../shaders/SimpleFragmentShader.fragmentshader")) {
@ -56,118 +55,111 @@ int cx_glrun(GLFWwindow *window) {
return -1; return -1;
} }
// Load model to render from file
Model *model; Model *model;
model = model_load("../triangle.obj"); model = model_load("../triangle.obj");
GLuint vertexbuffer; // Allocate the render buffer
glGenBuffers(1, &vertexbuffer); // GL uses this to feed the GPU
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer); GLfloat *render_buffer;
glBufferData(GL_ARRAY_BUFFER, model->bufsize*4*sizeof(GLfloat), model->object, GL_STATIC_DRAW); render_buffer = malloc(model->bufsize * 4 * sizeof(GLfloat));
memcpy(render_buffer, model->object, model->bufsize * 4 * sizeof(GLfloat));
// Bind the render buffer to OpenGL
GLuint vertexbuffer;
glGenBuffers(1, &vertexbuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glBufferData(GL_ARRAY_BUFFER, model->bufsize*4*sizeof(GLfloat), render_buffer, GL_STATIC_DRAW);
// 1rst attribute buffer : vertices
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glVertexAttribPointer(
0, // attribute 0 in the pipeline
4, // size
GL_FLOAT, // type
GL_FALSE, // normalized?
0, // stride
NULL // array buffer offset
);
// Remainder from cursor experiments, might be useful later
double xpos, ypos; double xpos, ypos;
glfwGetCursorPos(window, &xpos, &ypos); glfwGetCursorPos(window, &xpos, &ypos);
GLfloat *matrix; GLfloat *rotation_matrix = matrix_new();
GLfloat *temp = matrix_new(); GLfloat *projection_matrix = matrix_new();
matrix = temp; // Temporary storage of transformation results
time_t t = time(NULL); GLfloat *temp_buffer;
GLfloat *projected_buffer;
temp = matrix_new(); projection_matrix[14] = -1.0f;
projection_matrix[0] = (GLfloat)9/16; // Widescreen FOV
temp[0] = cos(M_PI*2/60*(t%60));
temp[4] = -sin(M_PI*2/60*(t%60));
temp[1] = sin(M_PI*2/60*(t%60));
temp[5] = cos(M_PI*2/60*(t%60));
matrix = temp;
t /= 60;
GLfloat *projection = matrix_new(); do {
GLfloat *buffer; // Clear the screen. It's not mentioned before Tutorial 02,
projection[14] = -1.0f;
buffer = matrix_new();
buffer[0] = (GLfloat)9/16;
temp = matrix_multip(projection, buffer);
free(buffer);
free(projection);
projection = temp;
temp = malloc(model->bufsize * 4 * sizeof(GLfloat));
buffer = malloc(model->bufsize * 4 * sizeof(GLfloat));
memcpy(temp, model->object, model->bufsize * 4 * sizeof(GLfloat));
GLfloat *orig;
orig = malloc(model->bufsize * 4 * sizeof(GLfloat));
memcpy(orig, model->object, model->bufsize * 4 * sizeof(GLfloat));
do {
// Clear the screen. It's not mentioned before Tutorial 02,
// but it can cause flickering, so it's there nonetheless. // but it can cause flickering, so it's there nonetheless.
glClear(GL_COLOR_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT);
// Use our shader // Use our shader
glUseProgram(programID); glUseProgram(programID);
time_t t = time(NULL); time_t t = time(NULL);
GLfloat *temp_mat;
temp_mat = matrix_new();
temp_mat[0] = cos(M_PI*2/60*(t%60)); rotation_matrix[0] = cos(M_PI*2/60*(t%60));
temp_mat[4] = -sin(M_PI*2/60*(t%60)); rotation_matrix[4] = -sin(M_PI*2/60*(t%60));
temp_mat[1] = sin(M_PI*2/60*(t%60)); rotation_matrix[1] = sin(M_PI*2/60*(t%60));
temp_mat[5] = cos(M_PI*2/60*(t%60)); rotation_matrix[5] = cos(M_PI*2/60*(t%60));
matrix = temp_mat;
t /= 60;
for (int i = 2; i < 5; i++) {
GLfloat *slice;
slice = matrix_transform(orig, model->bufsize, matrix);
memcpy(temp, slice, model->bufsize* 4 * sizeof(GLfloat));
free(slice);
}
free(buffer);
buffer = matrix_transform(temp, model->bufsize, projection);
memcpy(model->object, buffer, model->bufsize * 4 * sizeof(GLfloat));
GLuint vertexbuffer;
glGenBuffers(1, &vertexbuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glBufferData(GL_ARRAY_BUFFER, model->bufsize * 4 * sizeof(GLfloat), model->object, GL_STATIC_DRAW);
// 1rst attribute buffer : vertices // BANANA, ROH-TAH-TEH
glEnableVertexAttribArray(0); temp_buffer = matrix_transform(model->object, model->bufsize, rotation_matrix);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glVertexAttribPointer( // Guess I'm just projecting.
0, // attribute 0. No particular reason for 0, but must match the layout in the shader. projected_buffer = matrix_transform(temp_buffer, model->bufsize, projection_matrix);
4, // size
GL_FLOAT, // type memcpy(render_buffer, projected_buffer, model->bufsize * 4 * sizeof(GLfloat));
GL_FALSE, // normalized? free(temp_buffer);
0, // stride free(projected_buffer);
NULL // array buffer offset
); glBufferData(GL_ARRAY_BUFFER, model->bufsize*4*sizeof(GLfloat), render_buffer, GL_STATIC_DRAW);
// 1rst attribute buffer : vertices
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
glVertexAttribPointer(
0, // attribute 0 in the pipeline
4, // size
GL_FLOAT, // type
GL_FALSE, // normalized?
0, // stride
NULL // array buffer offset
);
// Draw! // Draw!
glDrawArrays(GL_TRIANGLES, 0, model->bufsize); // 3 indices starting at 0 -> 1 triangle glDrawArrays(GL_TRIANGLES, 0, model->bufsize); // 3 indices starting at 0 -> 1 triangle
glDisableVertexAttribArray(0); glDisableVertexAttribArray(0);
// Swap buffers // Swap buffers
glfwSwapBuffers(window); glfwSwapBuffers(window);
glfwPollEvents(); glfwPollEvents();
// Check if the ESC key was pressed or the window was closed // Check if the ESC key was pressed or the window was closed
usleep(1000000/60); usleep(1000000/60);
} while(glfwGetKey(window, GLFW_KEY_ESCAPE) != GLFW_PRESS && } while(glfwGetKey(window, GLFW_KEY_ESCAPE) != GLFW_PRESS &&
!glfwWindowShouldClose(window)); !glfwWindowShouldClose(window));
// Close OpenGL window and terminate GLFW // Close OpenGL window and terminate GLFW
free(matrix); glfwTerminate();
glfwTerminate(); free(rotation_matrix);
free(projection_matrix);
model_free(model);
free(render_buffer);
return 0; return 0;
} }

View file

@ -14,5 +14,7 @@ main(void) {
return -1; return -1;
} }
return cx_glrun(window); int retval;
retval = cx_glrun(window);
return retval;
} }

View file

@ -8,11 +8,6 @@ model_new(size_t size) {
return model; return model;
} }
void
model_free(Model *self) {
free(self->object);
free(self);
}
Model * Model *
model_load(const char *path) { model_load(const char *path) {
@ -63,8 +58,16 @@ model_load(const char *path) {
} }
model->object[i*12+j*4+3] = 1; model->object[i*12+j*4+3] = 1;
} }
model->bufsize = facecount*3;
} }
free(vertices);
free(faces);
return model; return model;
} }
int
model_free(Model *self) {
free(self->object);
free(self);
return 0;
}

View file

@ -12,7 +12,7 @@ load_code(const char *filepath, char **code) {
return 1; return 1;
} }
*code = malloc(256 * sizeof(char)); *code = malloc(1024 * sizeof(char));
if (code == NULL) { if (code == NULL) {
fprintf(stderr, "Out of memory"); fprintf(stderr, "Out of memory");
return 1; return 1;
@ -31,22 +31,22 @@ load_code(const char *filepath, char **code) {
static int static int
compile_code(const char *filepath, const char *code, compile_code(const char *filepath, const char *code,
GLuint ShaderID, GLint *Result) { GLuint ShaderID, GLint *Result) {
int InfoLogLength; int InfoLogLength;
// Compile Shader // Compile Shader
printf("Compiling shader : %s\n", filepath); printf("Compiling shader : %s\n", filepath);
glShaderSource(ShaderID, 1, (const char **)&code, NULL); glShaderSource(ShaderID, 1, (const char **)&code, NULL);
glCompileShader(ShaderID); glCompileShader(ShaderID);
// Check Shader // Check Shader
glGetShaderiv(ShaderID, GL_COMPILE_STATUS, Result); glGetShaderiv(ShaderID, GL_COMPILE_STATUS, Result);
glGetShaderiv(ShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength); glGetShaderiv(ShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
if (InfoLogLength > 0) { if (InfoLogLength > 0) {
char *ShaderErrorMessage = malloc(InfoLogLength+1); char *ShaderErrorMessage = malloc(InfoLogLength+1);
glGetShaderInfoLog(ShaderID, InfoLogLength, NULL, ShaderErrorMessage); glGetShaderInfoLog(ShaderID, InfoLogLength, NULL, ShaderErrorMessage);
printf("%s\n", ShaderErrorMessage); printf("%s\n", ShaderErrorMessage);
free(ShaderErrorMessage); free(ShaderErrorMessage);
return -1; return -1;
} }
return 0; return 0;
} }
@ -57,58 +57,58 @@ LoadShaders(GLuint *programID, const char *vertex_file_path,
char *vertex_code = NULL; char *vertex_code = NULL;
char *fragment_code = NULL; char *fragment_code = NULL;
// Create the shaders // Create the shaders
GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER); GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER);
GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER); GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
// Read the Vertex Shader code from the file // Read the Vertex Shader code from the file
if (load_code(vertex_file_path, (char **)&vertex_code)) { if (load_code(vertex_file_path, (char **)&vertex_code)) {
goto end; goto end;
} }
// Read the Fragment Shader code from the file // Read the Fragment Shader code from the file
if (load_code(fragment_file_path, (char **)&fragment_code)) { if (load_code(fragment_file_path, (char **)&fragment_code)) {
goto end; goto end;
} }
GLint Result = GL_FALSE; GLint Result = GL_FALSE;
// Compile Vertex Shader // Compile Vertex Shader
if (compile_code(vertex_file_path, vertex_code, VertexShaderID, &Result)) { if (compile_code(vertex_file_path, vertex_code, VertexShaderID, &Result)) {
goto end; goto end;
} }
// Compile Fragment Shader // Compile Fragment Shader
if (compile_code(fragment_file_path, fragment_code, FragmentShaderID, &Result)) { if (compile_code(fragment_file_path, fragment_code, FragmentShaderID, &Result)) {
goto end; goto end;
} }
// Link the program // Link the program
printf("Linking program\n"); printf("Linking program\n");
*programID = glCreateProgram(); *programID = glCreateProgram();
glAttachShader(*programID, VertexShaderID); glAttachShader(*programID, VertexShaderID);
glAttachShader(*programID, FragmentShaderID); glAttachShader(*programID, FragmentShaderID);
glLinkProgram(*programID); glLinkProgram(*programID);
GLint InfoLogLength; GLint InfoLogLength;
// Check the program // Check the program
glGetProgramiv(*programID, GL_LINK_STATUS, &Result); glGetProgramiv(*programID, GL_LINK_STATUS, &Result);
glGetProgramiv(*programID, GL_INFO_LOG_LENGTH, &InfoLogLength); glGetProgramiv(*programID, GL_INFO_LOG_LENGTH, &InfoLogLength);
if (InfoLogLength > 0) { if (InfoLogLength > 0) {
char *ProgramErrorMessage = malloc(InfoLogLength+1); char *ProgramErrorMessage = malloc(InfoLogLength+1);
glGetProgramInfoLog(*programID, InfoLogLength, NULL, ProgramErrorMessage); glGetProgramInfoLog(*programID, InfoLogLength, NULL, ProgramErrorMessage);
printf("%s\n", ProgramErrorMessage); printf("%s\n", ProgramErrorMessage);
} }
glDetachShader(*programID, VertexShaderID); glDetachShader(*programID, VertexShaderID);
glDetachShader(*programID, FragmentShaderID); glDetachShader(*programID, FragmentShaderID);
glDeleteShader(VertexShaderID); glDeleteShader(VertexShaderID);
glDeleteShader(FragmentShaderID); glDeleteShader(FragmentShaderID);
// If code got here, it means it was successful // If code got here, it means it was successful
retval = 0; retval = 0;
end: end:
free(vertex_code); free(vertex_code);

View file

@ -42,7 +42,6 @@ matrix_transform(GLfloat *vects, int vectcount,
result = calloc(vectcount*4, sizeof(GLfloat)); result = calloc(vectcount*4, sizeof(GLfloat));
for (int k = 0; k < vectcount; k++) { for (int k = 0; k < vectcount; k++) {
for (int j = 0; j < 4; j++) { for (int j = 0; j < 4; j++) {
dot_prod = 0; dot_prod = 0;