summaryrefslogtreecommitdiff
path: root/shader.cpp
diff options
context:
space:
mode:
authorJon Bergli Heier <snakebite@jvnv.net>2011-04-01 23:07:56 +0200
committerJon Bergli Heier <snakebite@jvnv.net>2011-04-01 23:07:56 +0200
commite172cde8c082fa3e338b3eb11079b36952874936 (patch)
tree90f65a54ce7b6a663ead31496549e0b9338c81d8 /shader.cpp
parent3b360c21777aad02394a643b32be2ab25362bba1 (diff)
Terrain shader lighting - work in progress.
Diffstat (limited to 'shader.cpp')
-rw-r--r--shader.cpp94
1 files changed, 94 insertions, 0 deletions
diff --git a/shader.cpp b/shader.cpp
new file mode 100644
index 0000000..8d3493e
--- /dev/null
+++ b/shader.cpp
@@ -0,0 +1,94 @@
+#include <fstream>
+#include <stdexcept>
+
+#include <boost/format.hpp>
+
+#include "shader.h"
+
+inline void gl_check_error(const char *msg) {
+ GLenum error = glGetError();
+ if(error != GL_NO_ERROR) {
+ throw(std::runtime_error((boost::format("%s:\n%s") % msg % gluErrorString(error)).str()));
+ }
+}
+
+void GLBaseShader::shader_source(const char *filename) {
+ std::ifstream inf(filename, std::ios_base::in);
+ if(!inf.is_open()) {
+ throw(std::runtime_error((boost::format("Failed to load shader from file %s") % filename).str()));
+ }
+ inf.seekg(0, std::ios_base::end);
+ int length = inf.tellg();
+ inf.seekg(0, std::ios_base::beg);
+ char *buffer = new char[length];
+ inf.read(buffer, length);
+ inf.close();
+
+ glShaderSource(shader, 1, (const GLchar**)&buffer, &length);
+ gl_check_error("Failed to set shader source");
+ delete[] buffer;
+ glCompileShader(shader);
+ int p;
+ glGetShaderiv(shader, GL_COMPILE_STATUS, &p);
+ if(p == 0) {
+ char log[0xffff];
+ int size;
+ glGetShaderInfoLog(shader, 0xffff, &size, (GLchar*)&log);
+ throw(std::runtime_error((boost::format("Failed to compile shader:\n%s") % log).str()));
+ }
+}
+
+void GLBaseShader::shader_source(std::string& filename) {
+ shader_source(filename.c_str());
+}
+
+GLBaseShader::GLBaseShader(GLenum type) {
+ shader = glCreateShader(type);
+}
+
+GLBaseShader::~GLBaseShader() {
+ glDeleteShader(shader);
+}
+
+/**
+ * GLShaderProgram
+ */
+GLShaderProgram::GLShaderProgram() {
+ program = glCreateProgram();
+}
+
+GLShaderProgram::~GLShaderProgram() {
+ glDeleteProgram(program);
+}
+
+void GLShaderProgram::attach(GLBaseShader& shader) {
+ glAttachShader(program, shader.shader);
+
+ gl_check_error("Failed to attach shader to program");
+}
+
+void GLShaderProgram::detach(GLBaseShader& shader) {
+ glDetachShader(program, shader.shader);
+
+ gl_check_error("Failed to detach shader from program");
+}
+
+void GLShaderProgram::link() {
+ glLinkProgram(program);
+ gl_check_error("linkage");
+
+ int p;
+ glGetProgramiv(program, GL_LINK_STATUS, &p);
+ if(p == 0) {
+ char log[0xffff];
+ int size;
+ glGetProgramInfoLog(program, 0xffff, &size, (GLchar*)&log);
+ throw(std::runtime_error((boost::format("Failed to link program:\n%s") % log).str()));
+ }
+}
+
+void GLShaderProgram::use() {
+ glUseProgram(program);
+
+ gl_check_error("Failed to use program");
+}