diff options
author | Ludovic Pouzenc <ludovic@pouzenc.fr> | 2019-09-15 14:21:43 +0200 |
---|---|---|
committer | Ludovic Pouzenc <ludovic@pouzenc.fr> | 2019-09-15 14:21:43 +0200 |
commit | 00ff773ea10dba1fd4c1a2bb09c1ec811a798af3 (patch) | |
tree | 9c000214d6b2d2b0cc93f598341aa51c45a7d32f /src/utils.c | |
parent | b6ab2f2c62e593edb50508e0b911a01fe773122f (diff) | |
download | demoscene-eo-master.tar.gz demoscene-eo-master.tar.bz2 demoscene-eo-master.zip |
For now, it display nothing, shaders changed without updating client code.
Diffstat (limited to 'src/utils.c')
-rw-r--r-- | src/utils.c | 114 |
1 files changed, 114 insertions, 0 deletions
diff --git a/src/utils.c b/src/utils.c new file mode 100644 index 0000000..a3c878e --- /dev/null +++ b/src/utils.c @@ -0,0 +1,114 @@ +#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; +} + |