From 4081e0e8f0f391aa25d67b73c45e73ccacff0f00 Mon Sep 17 00:00:00 2001 From: Eleni Maria Stea Date: Wed, 12 Jul 2017 11:46:05 +0300 Subject: [PATCH] backup (realized that the shader files weren't added to git) --- src/opengl/shader-gl.cc | 169 +++++++++++++++++++++++++++++++++++++++++++++++ src/opengl/shader-gl.h | 34 ++++++++++ src/scene.cc | 2 +- src/shader.cc | 53 ++++++++++++++- src/shader.h | 21 +++--- 5 files changed, 267 insertions(+), 12 deletions(-) create mode 100644 src/opengl/shader-gl.cc create mode 100644 src/opengl/shader-gl.h diff --git a/src/opengl/shader-gl.cc b/src/opengl/shader-gl.cc new file mode 100644 index 0000000..334a1cf --- /dev/null +++ b/src/opengl/shader-gl.cc @@ -0,0 +1,169 @@ +#include +#include +#include + +#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 index 0000000..a147c5d --- /dev/null +++ b/src/opengl/shader-gl.h @@ -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 diff --git a/src/scene.cc b/src/scene.cc index 2dc20bc..08689f6 100644 --- a/src/scene.cc +++ b/src/scene.cc @@ -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) */ diff --git a/src/shader.cc b/src/shader.cc index bd80cfe..8fa50ae 100644 --- a/src/shader.cc +++ b/src/shader.cc @@ -1,31 +1,78 @@ +#include #include #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; itype < sizeof shaders / sizeof *shaders); + shaders[sdr->type] = sdr; } \ No newline at end of file diff --git a/src/shader.h b/src/shader.h index 204d053..1472fb3 100644 --- a/src/shader.h +++ b/src/shader.h @@ -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_ -- 1.7.10.4