]> git.lizzy.rs Git - dragonblocks_alpha.git/commitdiff
Implement shader management
authorElias Fleckenstein <eliasfleckenstein@web.de>
Sat, 27 Mar 2021 17:32:16 +0000 (18:32 +0100)
committerElias Fleckenstein <eliasfleckenstein@web.de>
Sat, 27 Mar 2021 17:32:16 +0000 (18:32 +0100)
src/Makefile
src/client.c
src/shaders.c
src/shaders.h

index d54dd19681c5e462e48ba0bc5896d3a3e771975b..e7c5ca7492c44684f0280aa6d3b505932c6f75db 100644 (file)
@@ -1,6 +1,6 @@
 COMMON = array.o list.o map.o signal.o util.o types.o
 SERVER = $(COMMON) server.o servercommands.o mapgen.o
-CLIENT = $(COMMON) client.o clientcommands.o mesh.o scene.o mapblock_meshgen.o
+CLIENT = $(COMMON) client.o clientcommands.o mesh.o scene.o mapblock_meshgen.o shaders.o
 LIBRARIES = -lpthread -lm
 CLIENT_LIBRARIES = -lGL -lGLEW -lglfw
 FLAGS = -g -fmax-errors=4
index 4be4783e12e027f0ba4d114451e79f772c9b67df..a25cbedf169b7c9d46a51f0aa054146642f12748 100644 (file)
@@ -45,12 +45,6 @@ static void *reciever_thread(void *unused)
        return NULL;
 }
 
-#ifdef RELEASE
-#define SHADER_PATH "shaders/"
-#else
-#define SHADER_PATH "../shaders/"
-#endif
-
 static void client_loop()
 {
        if(! glfwInit()) {
@@ -70,27 +64,39 @@ static void client_loop()
        GLFWwindow *window = glfwCreateWindow(width, height, "Dragonblocks", NULL, NULL);
 
        if (! window) {
-               printf("Failed to create window\n");
+               fprintf(stderr, "Failed to create window\n");
                glfwTerminate();
                return;
        }
 
        glfwMakeContextCurrent(window);
        if (glewInit() != GLEW_OK) {
-               printf("Failed to initialize GLEW\n");
+               fprintf(stderr, "Failed to initialize GLEW\n");
                return;
        }
 
-       ShaderProgram *prog = create_shader_program(SHADER_PATH);
+       const char *shader_path;
+
+#ifdef RELEASE
+       shader_path = "shaders";
+#else
+       shader_path = "../shaders";
+#endif
+
+       ShaderProgram *prog = create_shader_program(shader_path);
+       if (! prog) {
+               fprintf(stderr, "Failed to create shader program\n");
+               return;
+       }
 
-       mat4x4 view, proj;
+       mat4x4 view, projection;
 
        mat4x4_identity(view);  // ToDo: camera
-       mat4x4_perspective(proj, 86.1f / 180.0f * M_PI, (float) width / (float) height, 0.01f, 100.0f);
+       mat4x4_perspective(projection, 86.1f / 180.0f * M_PI, (float) width / (float) height, 0.01f, 100.0f);
 
        glUseProgram(prog->id);
        glUniformMatrix4fv(prog->loc_view, 1, GL_FALSE, view[0]);
-       glUniformMatrix4fv(prog->loc_proj, 1, GL_FALSE, proj[0]);
+       glUniformMatrix4fv(prog->loc_projection, 1, GL_FALSE, projection[0]);
 
        while (! glfwWindowShouldClose(window) && client.state != CS_DISCONNECTED && ! interrupted) {
                glClear(GL_COLOR_BUFFER_BIT);
index e4d9753ec5fd8d035a3a7f228f6eb26179a49f6c..d0981a63dc0c4edafed9176ef0be93fb49687986 100644 (file)
@@ -1 +1,117 @@
+#include <string.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
 #include "shaders.h"
+
+static GLuint compile_and_attach_shader(GLenum type, const char *path, const char *name, GLuint program)
+{
+       char full_path[strlen(path) + 1 + strlen(name) + 1 + 4 + 1];
+       sprintf(full_path, "%s/%s.glsl", path, name);
+
+       FILE *file = fopen(full_path, "r");
+       if (! file) {
+               perror("fopen");
+               return 0;
+       }
+
+       if (fseek(file, 0, SEEK_END) == -1) {
+               perror("fseek");
+               fclose(file);
+               return 0;
+       }
+
+       long size = ftell(file);
+
+       if (size == 1) {
+               perror("ftell");
+               fclose(file);
+               return 0;
+       }
+
+       if (fseek(file, 0, SEEK_SET) == -1) {
+               perror("fseek");
+               fclose(file);
+               return 0;
+       }
+
+       char code[size];
+
+       if (fread(code, 1, size, file) != (size_t) size) {
+               perror("fread");
+               fclose(file);
+               return 0;
+       }
+
+       fclose(file);
+
+       GLuint id = glCreateShader(type);
+
+       char const *codeptr = code;
+       const int isize = (int) size;
+       glShaderSource(id, 1, &codeptr, &isize);
+
+       glCompileShader(id);
+
+       GLint success;
+       glGetShaderiv(id, GL_COMPILE_STATUS, &success);
+       if (! success) {
+               char errbuf[BUFSIZ];
+               glGetShaderInfoLog(id, BUFSIZ, NULL, errbuf);
+               fprintf(stderr, "Failed to compile %s shader: %s\n", name, errbuf);
+               glDeleteShader(id);
+               return 0;
+       }
+
+       glAttachShader(program, id);
+
+       return id;
+}
+
+
+ShaderProgram *create_shader_program(const char *path)
+{
+       GLuint id = glCreateProgram();
+
+       GLuint vert, frag;
+
+       if (! (vert = compile_and_attach_shader(GL_VERTEX_SHADER, path, "vertex", id))) {
+               glDeleteProgram(id);
+               return NULL;
+       }
+
+       if (! (frag = compile_and_attach_shader(GL_FRAGMENT_SHADER, path, "fragment", id))) {
+               glDeleteShader(vert);
+               glDeleteProgram(id);
+               return NULL;
+       }
+
+       glLinkProgram(id);
+       glDeleteShader(vert);
+       glDeleteShader(frag);
+
+       GLint success;
+       glGetProgramiv(id, GL_LINK_STATUS, &success);
+       if (! success) {
+               char errbuf[BUFSIZ];
+               glGetProgramInfoLog(id, BUFSIZ, NULL, errbuf);
+               fprintf(stderr, "Failed to link shader program: %s\n", errbuf);
+               glDeleteProgram(id);
+               return NULL;
+       }
+
+       ShaderProgram *prog = malloc(sizeof(ShaderProgram));
+       prog->id = id;
+       prog->loc_model = glGetUniformLocation(id, "model");
+       prog->loc_view = glGetUniformLocation(id, "view");
+       prog->loc_projection = glGetUniformLocation(id, "projection");
+
+       return prog;
+}
+
+void delete_shader_program(ShaderProgram *prog)
+{
+       glDeleteProgram(prog->id);
+       free(prog);
+}
+
index 6344625395b936faafd125d8a11b2a2d81532f11..d7941052b0736d65f88878dc1d6637d514c20050 100644 (file)
@@ -1,15 +1,18 @@
 #ifndef _SHADERS_H_
 #define _SHADERS_H_
 
+#include <GL/glew.h>
+#include <GL/gl.h>
+
 typedef struct
 {
        GLuint id;
        GLint loc_model;
        GLint loc_view;
-       GLint loc_proj;
+       GLint loc_projection;
 } ShaderProgram;
 
 ShaderProgram *create_shader_program(const char *path);        // ToDo
-void delete_shader_program(ShaderProgram *);
+void delete_shader_program(ShaderProgram *prog);
 
 #endif