backup (realized that the shader files weren't added to git)
[demo] / src / opengl / shader-gl.cc
diff --git a/src/opengl/shader-gl.cc b/src/opengl/shader-gl.cc
new file mode 100644 (file)
index 0000000..334a1cf
--- /dev/null
@@ -0,0 +1,169 @@
+#include <GL/glew.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "opengl/shader-gl.h"
+
+ShaderGL::ShaderGL()
+{
+       sdr = 0;
+}
+
+ShaderGL::~ShaderGL()
+{
+       destroy();
+}
+
+bool ShaderGL::create(char *buf, unsigned int bsz, const char *fname)
+{
+       /* find shader type and create shader */
+       unsigned int stype;
+       switch(type) {
+       case SDR_VERTEX:
+               stype = GL_VERTEX_SHADER;
+               break;
+       case SDR_FRAGMENT:
+               stype = GL_FRAGMENT_SHADER;
+               break;
+       default:
+               fprintf(stderr, "Unknown shader type.\n");
+               return false;
+       }
+       sdr = glCreateShader(stype);
+
+       /* compile */
+       glShaderSource(sdr, 1, (const char **)&buf, 0);
+       glCompileShader(sdr);
+
+       delete [] buf;
+
+       /* check compile status */
+       int status;
+       glGetShaderiv(sdr, GL_COMPILE_STATUS, &status);
+       if(status)
+               printf("Successfully compiled shader: %s\n", fname);
+       else
+               fprintf(stderr, "Failed to compile %s shader.\n", fname);
+
+       /* print the info log */
+       int loglen;
+       glGetShaderiv(sdr, GL_INFO_LOG_LENGTH, &loglen);
+       if(loglen > 0 && (buf = new char[loglen + 1])) {
+               glGetShaderInfoLog(sdr, loglen, 0, buf);
+               buf[loglen] = 0;
+               printf("%s\n", buf);
+
+               delete [] buf;
+       }
+
+       if(!status) {
+               destroy();
+               return false;
+       }
+
+       return true;
+}
+
+void ShaderGL::destroy()
+{
+       if(sdr) {
+               glDeleteShader(sdr);
+       }
+       sdr = 0;
+       type = SDR_UNKNOWN;
+}
+
+void ShaderGL::attach(unsigned int prog)
+{
+       glAttachShader(prog, sdr);
+}
+
+/* Shader Program */
+
+ShaderProgramGL::ShaderProgramGL()
+{
+       prog = 0;
+       memset(shaders, 0, sizeof shaders / sizeof *shaders);
+}
+
+ShaderProgramGL::~ShaderProgramGL()
+{
+       destroy();
+}
+
+void ShaderProgramGL::destroy()
+{
+       glDeleteProgram(prog);
+       prog = 0;
+
+       delete_shaders();
+}
+
+void ShaderProgramGL::delete_shaders()
+{
+       for(unsigned int i=0; i<(sizeof shaders) / (sizeof *shaders); ++i) {
+               delete shaders[i];
+       }
+}
+
+bool ShaderProgramGL::link()
+{
+       glLinkProgram(prog);
+
+       int status;
+       glGetProgramiv(prog, GL_LINK_STATUS, &status);
+       if(status)
+               printf("Successfully linked shader program.\n");
+       else
+               printf("Failed to link shader program.\n");
+
+       int loglen;
+       glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &loglen);
+
+       char *buf;
+       if(loglen > 0 && (buf = new char[loglen + 1])) {
+               glGetProgramInfoLog(prog, loglen, 0, buf);
+               buf[loglen] = 0;
+               printf("%s\n", buf);
+               delete [] buf;
+       }
+
+       return status ? true : false;
+}
+
+bool ShaderProgramGL::load(const char *vfname, const char *ffname)
+{
+       Shader *vsdr = new ShaderGL;
+       if(!vsdr->load(vfname, SDR_VERTEX)) {
+               delete vsdr;
+               return false;
+       }
+
+       Shader *fsdr = new ShaderGL;
+       if(!fsdr->load(ffname, SDR_FRAGMENT)) {
+               delete vsdr;
+               delete fsdr;
+               return false;
+       }
+
+       prog = glCreateProgram();
+
+       vsdr->attach(prog);
+       fsdr->attach(prog);
+
+       if(!link()) {
+               delete vsdr;
+               delete fsdr;
+               glDeleteProgram(prog);
+               return false;
+       }
+
+       /* the order of shaders in the array is the order they have in
+       enum Type, so atm it goes like: VS, FS, ... because we have SDR_VERTEX,
+       SDR_FRAGMENT, ... */
+
+       shaders[0] = vsdr;
+       shaders[1] = fsdr;
+
+       return true;
+}
\ No newline at end of file