aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authordrumsetmonkey <abelleisle@roadrunner.com>2016-05-06 08:04:37 -0400
committerdrumsetmonkey <abelleisle@roadrunner.com>2016-05-06 08:04:37 -0400
commitbc92962aff14805d5920f5a82628648d1c1fe4fd (patch)
tree6575a93032745a6493eef677c35996ed1119f6bb /src
parentaaf7a6bd286b0d200356ef54148791e2e91ff253 (diff)
Shadaersrsersdfsdf
Diffstat (limited to 'src')
-rw-r--r--src/shader_utils.cpp171
1 files changed, 171 insertions, 0 deletions
diff --git a/src/shader_utils.cpp b/src/shader_utils.cpp
new file mode 100644
index 0000000..13b2f74
--- /dev/null
+++ b/src/shader_utils.cpp
@@ -0,0 +1,171 @@
+/**
+ * From the OpenGL Programming wikibook: http://en.wikibooks.org/wiki/OpenGL_Programming
+ * This file is in the public domain.
+ * Contributors: Sylvain Beucler, Guus Sliepen
+ */
+
+#include <iostream>
+#include <vector>
+using namespace std;
+
+#include <shader_utils.hpp>
+//#include <SDL_opengles2.h>
+
+/**
+ * Store all the file's contents in memory, useful to pass shaders
+ * source code to OpenGL. Using SDL_RWops for Android asset support.
+ */
+char* file_read(const char* filename) {
+ SDL_RWops *rw = SDL_RWFromFile(filename, "rb");
+ if (rw == NULL) return NULL;
+
+ Sint64 res_size = SDL_RWsize(rw);
+ char* res = new char[res_size + 1];
+
+ Sint64 nb_read_total = 0, nb_read = 1;
+ char* buf = res;
+ while (nb_read_total < res_size && nb_read != 0) {
+ nb_read = SDL_RWread(rw, buf, 1, (res_size - nb_read_total));
+ nb_read_total += nb_read;
+ buf += nb_read;
+ }
+ SDL_RWclose(rw);
+ if (nb_read_total != res_size) {
+ delete[] res;
+ return NULL;
+ }
+
+ res[nb_read_total] = '\0';
+ return res;
+}
+
+/**
+ * Display compilation errors from the OpenGL shader compiler
+ */
+void print_log(GLuint object) {
+ GLint log_length = 0;
+ if (glIsShader(object)) {
+ glGetShaderiv(object, GL_INFO_LOG_LENGTH, &log_length);
+ } else if (glIsProgram(object)) {
+ glGetProgramiv(object, GL_INFO_LOG_LENGTH, &log_length);
+ } else {
+ SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_ERROR,
+ "printlog: Not a shader or a program");
+ return;
+ }
+
+
+ char *log = new char[log_length];
+
+ if (glIsShader(object))
+ glGetShaderInfoLog(object, log_length, NULL, log);
+ else if (glIsProgram(object))
+ glGetProgramInfoLog(object, log_length, NULL, log);
+
+ SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_ERROR, "%s\n", log);
+}
+
+/**
+ * Compile the shader from file 'filename', with error handling
+ */
+GLuint create_shader(const char* filename, GLenum type) {
+ const char* source = file_read(filename);
+ if (source == NULL) {
+ SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_ERROR,
+ "Error opening %s: %s", filename, SDL_GetError());
+ return 0;
+ }
+ GLuint res = glCreateShader(type);
+ const GLchar* sources[] = {
+ // Define GLSL version
+ "#version 130\n" // OpenGL 2.0
+ ,
+ // Define default float precision for fragment shaders:
+ (type == GL_FRAGMENT_SHADER) ?
+ "#ifdef GL_FRAGMENT_PRECISION_HIGH\n"
+ "precision highp float; \n"
+ "#else \n"
+ "precision mediump float; \n"
+ "#endif \n"
+ : ""
+ ,
+ source };
+ glShaderSource(res, 3, sources, NULL);
+ delete[] source;
+
+ glCompileShader(res);
+ GLint compile_ok = GL_FALSE;
+ glGetShaderiv(res, GL_COMPILE_STATUS, &compile_ok);
+ if (compile_ok == GL_FALSE) {
+ SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_ERROR, "%s:\n", filename);
+ print_log(res);
+ glDeleteShader(res);
+ return 0;
+ }
+
+ return res;
+}
+
+GLuint create_program(const char *vertexfile, const char *fragmentfile) {
+ GLuint program = glCreateProgram();
+ GLuint shader;
+
+ if(vertexfile) {
+ shader = create_shader(vertexfile, GL_VERTEX_SHADER);
+ if(!shader)
+ return 0;
+ glAttachShader(program, shader);
+ }
+
+ if(fragmentfile) {
+ shader = create_shader(fragmentfile, GL_FRAGMENT_SHADER);
+ if(!shader)
+ return 0;
+ glAttachShader(program, shader);
+ }
+
+ glLinkProgram(program);
+ GLint link_ok = GL_FALSE;
+ glGetProgramiv(program, GL_LINK_STATUS, &link_ok);
+ if (!link_ok) {
+ SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO, "glLinkProgram:");
+ print_log(program);
+ glDeleteProgram(program);
+ return 0;
+ }
+
+ return program;
+}
+
+GLint get_attrib(GLuint program, const char *name) {
+ GLint attribute = glGetAttribLocation(program, name);
+ if(attribute == -1)
+ SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_ERROR,
+ "Could not bind attribute %s", name);
+ return attribute;
+}
+
+GLint get_uniform(GLuint program, const char *name) {
+ GLint uniform = glGetUniformLocation(program, name);
+ if(uniform == -1)
+ SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_ERROR,
+ "Could not bind uniform %s", name);
+ return uniform;
+}
+
+void print_opengl_info() {
+ int major, minor, profile;
+ SDL_GL_GetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, &major);
+ SDL_GL_GetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, &minor);
+ SDL_GL_GetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, &profile);
+ const char* profile_str = "";
+ if (profile & SDL_GL_CONTEXT_PROFILE_CORE)
+ profile_str = "CORE";
+ if (profile & SDL_GL_CONTEXT_PROFILE_COMPATIBILITY)
+ profile_str = "COMPATIBILITY";
+ if (profile & SDL_GL_CONTEXT_PROFILE_ES)
+ profile_str = "ES";
+
+ SDL_LogMessage(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO,
+ "OpenGL %d.%d %s", major, minor, profile_str);
+}