backup (realized that the shader files weren't added to git)
authorEleni Maria Stea <estea@igalia.com>
Wed, 12 Jul 2017 08:46:05 +0000 (11:46 +0300)
committerEleni Maria Stea <estea@igalia.com>
Wed, 12 Jul 2017 08:46:05 +0000 (11:46 +0300)
src/opengl/shader-gl.cc [new file with mode: 0644]
src/opengl/shader-gl.h [new file with mode: 0644]
src/scene.cc
src/shader.cc
src/shader.h

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
diff --git a/src/opengl/shader-gl.h b/src/opengl/shader-gl.h
new file mode 100644 (file)
index 0000000..a147c5d
--- /dev/null
@@ -0,0 +1,34 @@
+#ifndef SHADER_GL_H_
+#define SHADER_GL_H_
+
+#include "shader.h"
+
+class ShaderGL : public Shader {
+protected:
+       /* bsz for vulkan, in opengl buf is 0 terminated */
+       unsigned int sdr;
+       virtual bool create(char *buf, unsigned int bsz, const char *fname);
+
+public:
+       ShaderGL();
+       virtual ~ShaderGL();
+
+       virtual void destroy();
+       virtual void attach(unsigned int prog);
+};
+
+class ShaderProgramGL : public ShaderProgram {
+protected:
+       unsigned int prog;
+
+public:
+       ShaderProgramGL();
+       virtual ~ShaderProgramGL();
+
+       void destroy();
+       void delete_shaders();
+       virtual bool link();
+       virtual bool load(const char *vfname, const char *ffname);
+};
+
+#endif // SHADER_GL_H_
\ No newline at end of file
index 2dc20bc..08689f6 100644 (file)
@@ -100,7 +100,7 @@ static void create_object(aiNode *node, Mat4 parent_transform, Scene *scene, con
           The 99% of the scenes have 1 mesh per node => for simplicity we only check the 1st one.
           Also: the 3D models we are going to use for this demo, have flat structure (no hierarchy)
           but just in case we need to replace them later, we calculate the transform by assuming that we
-          have a node hierarchy. This => that each object's modelling transformation is the 
+          have a node hierarchy. This => that each object's modelling transformation is the
           product of its local transformation (mTransformation) with the acc parent nodes transformations
           (parent_transform)
        */
index bd80cfe..8fa50ae 100644 (file)
@@ -1,31 +1,78 @@
+#include <assert.h>
 #include <stdio.h>
 #include "shader.h"
 
 Shader::Shader() {}
-Shader::~Shader() {}
+Shader::~Shader()
+{
+       type = SDR_UNKNOWN;
+}
 
 bool Shader::load(const char *fname, SType type)
 {
        switch(type) {
        case SDR_VERTEX:
        case SDR_FRAGMENT:
+               this->type = type;
                break;
        default:
                fprintf(stderr, "Invalid shader type used in loading.\n");
                return false;
        }
+
+       FILE *fp;
+       unsigned int fsz;
+
+       if(!(fp = fopen(fname, "rb"))) {
+               fprintf(stderr, "Failed to open shader: %s.\n", fname);
+
+               return false;
+       }
+       fseek(fp, 0, SEEK_END);
+       fsz = ftell(fp);
+       rewind(fp);
+
+       char *buf;
+       if(!(buf = new char[fsz + 1])) {
+               fprintf(stderr, "Failed to allocate %u buffers.\n", fsz + 1);
+               fclose(fp);
+
+               return false;
+       }
+
+       if(fread(buf, 1, fsz, fp) < fsz) {
+               fprintf(stderr, "Failed to read shader: %s.\n", fname);
+               delete buf;
+               fclose(fp);
+
+               return false;
+       }
+       buf[fsz] = '\0';
+       fclose(fp);
+
+       create(buf, fsz, fname);
        return true;
 }
 
 ShaderProgram::ShaderProgram()
 {
+       int len = sizeof shaders / sizeof *shaders;
+       for(int i=0; i<len; ++i) {
+               shaders[i] = 0;
+       }
 }
 
 ShaderProgram::~ShaderProgram()
 {
+       int len = sizeof shaders / sizeof *shaders;
+
+       for(int i=0; i<len; ++i) {
+               delete shaders[i];
+       }
 }
 
-void ShaderProgram::add_shader(Shader *sdr, SType type)
+void ShaderProgram::add_shader(Shader *sdr)
 {
-       shaders[type] = sdr;
+       assert(sdr->type < sizeof shaders / sizeof *shaders);
+       shaders[sdr->type] = sdr;
 }
\ No newline at end of file
index 204d053..1472fb3 100644 (file)
@@ -2,32 +2,37 @@
 #define SHADER_H_
 
 enum SType {
+       SDR_UNKNOWN,
        SDR_VERTEX,
        SDR_FRAGMENT
 };
 
 class Shader {
-private:
-       SType type;
+protected:
+       virtual bool create(char *buf, unsigned int bsz, const char *fname) = 0;
 
 public:
+       SType type;
+
        Shader();
-       ~Shader();
+       virtual ~Shader() = 0;
 
+       virtual void destroy() = 0;
        virtual bool load(const char *fname, SType type);
+       virtual void attach(unsigned int prog) = 0; // if vulkan -> leave empty
 };
 
 class ShaderProgram {
-private:
+protected:
        Shader *shaders[2];
 
 public:
        ShaderProgram();
-       virtual ~ShaderProgram() = 0;
+       virtual ~ShaderProgram();
 
-       void add_shader(Shader *sdr, SType type);
-       bool link();
-       void bind();
+       virtual void add_shader(Shader *sdr);
+       virtual bool link() = 0;
+       virtual bool load(const char *vfname, const char *ffname) = 0;
 };
 
 #endif // SHADER_H_