return NULL;
}
-#ifdef RELEASE
-#define SHADER_PATH "shaders/"
-#else
-#define SHADER_PATH "../shaders/"
-#endif
-
static void client_loop()
{
if(! glfwInit()) {
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);
+#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);
+}
+