#include "utils.h" // Mostly inspired by CC0 https://gist.github.com/koute/7391344 void gl_mat4x4_ortho(t_mat4x4 out, float left, float right, float bottom, float top, float znear, float zfar) { #define T(a, b) (a * 4 + b) out[T(0,0)] = 2.0f / (right - left); out[T(0,1)] = 0.0f; out[T(0,2)] = 0.0f; out[T(0,3)] = 0.0f; out[T(1,1)] = 2.0f / (top - bottom); out[T(1,0)] = 0.0f; out[T(1,2)] = 0.0f; out[T(1,3)] = 0.0f; out[T(2,2)] = -2.0f / (zfar - znear); out[T(2,0)] = 0.0f; out[T(2,1)] = 0.0f; out[T(2,3)] = 0.0f; out[T(3,0)] = -(right + left) / (right - left); out[T(3,1)] = -(top + bottom) / (top - bottom); out[T(3,2)] = -(zfar + znear) / (zfar - znear); out[T(3,3)] = 1.0f; #undef T } // Mostly inspired from https://en.wikibooks.org/wiki/OpenGL_Programming/Modern_OpenGL_Tutorial_02 // Store all the file's contents in memory, useful to pass shaders source code to OpenGL. const GLchar* gl_shaderfile_read(const char* path, Sint64 *out_fsize) { GLchar *buf, *cursor; SDL_RWops *rw; Sint64 fsize; size_t read; rw = SDL_RWFromFile(path, "rb"); if (rw == NULL) return NULL; fsize = SDL_RWsize(rw); if (fsize == -1) return NULL; buf = malloc(fsize+1); if (buf == NULL) return NULL; cursor = buf; read = 0; do { cursor += read; // Read at most to the end of buf read = SDL_RWread(rw, cursor, 1, (fsize - (cursor-buf))); } while ( read > 0 ); *cursor = '\0'; // Where the +1 is used from malloc() call SDL_RWclose(rw); // Check if we have read the whole thing if ( (cursor-buf) != fsize) { free(buf); return NULL; } if (out_fsize != NULL) *out_fsize = fsize; return buf; } /** * Display compilation errors from the OpenGL shader compiler */ void gl_trace_shader_or_program_log(GLuint object) { GLint log_length = 0; char *log; if (glIsShader(object)) { glGetShaderiv(object, GL_INFO_LOG_LENGTH, &log_length); } else if (glIsProgram(object)) { glGetProgramiv(object, GL_INFO_LOG_LENGTH, &log_length); } else { TRACE("not a shader or a program"); return; } log = (char*)malloc(log_length); if ( log == NULL ) { TRACE("malloc failed"); return; } if (glIsShader(object)) glGetShaderInfoLog(object, log_length, NULL, log); else if (glIsProgram(object)) glGetProgramInfoLog(object, log_length, NULL, log); TRACE(log); free(log); } GLint gl_compile_shader_from_file(GLuint shader, const char* path) { Sint64 fsize; GLint gl_fsize, status; const GLchar *source = gl_shaderfile_read(path, &fsize); if (source == NULL) return 1; gl_fsize = (GLint) fsize; glShaderSource(shader, 1, &source, &gl_fsize); glCompileShader(shader); glGetShaderiv(shader, GL_COMPILE_STATUS, &status); if(status == GL_FALSE) { gl_trace_shader_or_program_log(shader); return 2; } return 0; }