GLSL Shaders -> Files (instead of #define)
authorSam Moore <matches@ucc.asn.au>
Mon, 16 Jun 2014 03:13:16 +0000 (11:13 +0800)
committerSam Moore <matches@ucc.asn.au>
Mon, 16 Jun 2014 03:13:16 +0000 (11:13 +0800)
So we can edit them without going insane.

18 files changed:
bin/ipdf
src/log.h
src/screen.cpp
src/shaderprogram.cpp
src/shaderprogram.h
src/shaders/basictex_frag.glsl [new file with mode: 0644]
src/shaders/basictex_vert.glsl [new file with mode: 0644]
src/shaders/circle_filled_geom.glsl [new file with mode: 0644]
src/shaders/circle_frag.glsl [new file with mode: 0644]
src/shaders/rect_filled_geom.glsl [new file with mode: 0644]
src/shaders/rect_frag.glsl [new file with mode: 0644]
src/shaders/rect_outline_geom.glsl [new file with mode: 0644]
src/shaders/rect_vert.glsl [new file with mode: 0644]
src/tests/bezier.cpp
src/tests/lines.cpp [new file with mode: 0644]
src/tests/pointstobitmap.h
src/tests/represent.cpp
src/view.cpp

index bb1314c..a5f1124 100755 (executable)
Binary files a/bin/ipdf and b/bin/ipdf differ
index a98a8cc..fdf30a7 100644 (file)
--- a/src/log.h
+++ b/src/log.h
@@ -9,6 +9,7 @@
 #include <cstdio>
 #include <cstdlib>
 #include <string>
+#include <cstring> // for strerror etc
 
 inline std::string methodName(const std::string& prettyFunction)
 {
index 6d67820..5bca554 100644 (file)
@@ -8,47 +8,8 @@
 #include "bufferbuilder.h"
 #include "shaderprogram.h"
 
-#define BASICTEX_VERT \
-       "#version 140\n"\
-       "#extension GL_ARB_shading_language_420pack : require\n"\
-       "#extension GL_ARB_explicit_attrib_location : require\n"\
-       "\n"\
-       "layout(std140, binding=0) uniform Viewport\n"\
-       "{\n"\
-       "\tfloat width;\n"\
-       "\tfloat height;\n"\
-       "};\n"\
-       "\n"\
-       "layout(location = 0) in vec2 position;\n"\
-       "layout(location = 1) in vec2 tex_coord;\n"\
-       "\n"\
-       "out vec2 fp_tex_coord;\n"\
-       "\n"\
-       "void main()\n"\
-       "{\n"\
-       "\t// Transform to clip coordinates (-1,1, -1,1).\n"\
-       "\tgl_Position.x = (position.x*2/width) - 1;\n"\
-       "\tgl_Position.y = 1 - (position.y*2/height);\n"\
-       "\tgl_Position.z = 0.0;\n"\
-       "\tgl_Position.w = 1.0;\n"\
-       "\tfp_tex_coord = tex_coord;\n"\
-       "}\n"
-
-#define BASICTEX_FRAG \
-       "#version 140\n"\
-       "\n"\
-       "in vec2 fp_tex_coord;\n"\
-       "\n"\
-       "out vec4 output_colour;\n"\
-       "\n"\
-       "uniform sampler2D tex;\n"\
-       "uniform vec4 colour;\n"\
-       "\n"\
-       "void main()\n"\
-       "{\n"\
-       "\toutput_colour = colour;\n"\
-       "\toutput_colour.a = texture(tex, fp_tex_coord).r;\n"\
-       "}\n"
+#define BASICTEX_VERT "shaders/basictex_vert.glsl"
+#define BASICTEX_FRAG "shaders/basictex_frag.glsl"
 
 using namespace IPDF;
 using namespace std;
index eb7a82d..1f5e9e2 100644 (file)
@@ -15,6 +15,9 @@ ShaderProgram::~ShaderProgram()
                glDeleteProgram(m_program);
 }
 
+/**
+ * This is only called once, does it need a function?
+ */
 void ShaderProgram::LazyCreateProgram()
 {
        if (!m_program)
@@ -23,42 +26,81 @@ void ShaderProgram::LazyCreateProgram()
        }
 }
 
-bool ShaderProgram::AttachShader(const char *src, GLenum type)
+/**
+ * Get GLSL shader source from a file as a string
+ * @param src_file filename to get the shader source from
+ * @returns a char* string allocated with new[] (remember to delete[] it)
+ */
+char * ShaderProgram::GetShaderSource(const char * src_file) const
+{
+       char * src = NULL;
+       FILE * file = fopen(src_file, "r");
+       if (file == NULL)
+       {
+               Error("Could not open shader source file \"%s\": %s", src_file, strerror(errno));
+               return NULL;
+       }
+       long start = ftell(file);
+
+       if (fseek(file, 0, SEEK_END) != 0)
+       {
+               Error("Couldn't seek to end of file \"%s\": %s", src_file, strerror(errno));
+               return NULL;
+       }
+       long end = ftell(file);
+       if (start < 0 || end < 0 || end < start)
+       {
+               // I bet that now I've put this message here, it will occur at least once in the life of this code
+               Error("Insane results from ftell(3) on file \"%s\"", src_file);
+               return NULL;
+       }
+       size_t size = end - start;
+       src = new char[size+1]; // Warning! Allocation of memory occuring! We might all die!
+       rewind(file);
+       if (fread(src, 1,size, file) != size)
+       {
+               Error("Error in fread on \"%s\": %s", src_file, strerror(errno));
+               fclose(file);
+               delete [] src;
+               return NULL;
+       }
+       src[size] = '\0';
+       fclose(file);
+       return src;
+       
+}
+
+bool ShaderProgram::AttachShader(const char * src_file, GLenum type)
 {
        GLuint shader_obj = glCreateShader(type);
+       char * src = GetShaderSource(src_file);
+       if (src == NULL)
+       {
+               Error("Couldn't get shader source.");
+               return false;
+       }
+       
+
        glShaderSource(shader_obj, 1, &src, 0);
        glCompileShader(shader_obj);
        int did_compile = 0;
        glGetShaderiv(shader_obj, GL_COMPILE_STATUS, &did_compile);
+       delete [] src; // Oh my goodness memory management is hard guys
        if (!did_compile)
        {
                char info_log[2048];
 
                glGetShaderInfoLog(shader_obj, 2048, nullptr, info_log);
-               Error("Shader compile error: %s\n", info_log);
+               Error("Shader compile error (file \"%s\"): %s (type %d)", src_file, info_log, type);
                return false;
        }
 
        m_shaders.push_back(Shader{type, shader_obj});
-       LazyCreateProgram();
+       LazyCreateProgram(); // um... why?
        glAttachShader(m_program, shader_obj);
        return true;
 }
 
-bool ShaderProgram::AttachVertexProgram(const char *src)
-{
-       return AttachShader(src, GL_VERTEX_SHADER);
-}
-
-bool ShaderProgram::AttachFragmentProgram(const char *src)
-{
-       return AttachShader(src, GL_FRAGMENT_SHADER);
-}
-
-bool ShaderProgram::AttachGeometryProgram(const char *src)
-{
-       return AttachShader(src, GL_GEOMETRY_SHADER);
-}
 
 bool ShaderProgram::Link()
 {
index c052566..9cedab6 100644 (file)
@@ -7,18 +7,27 @@
 
 namespace IPDF
 {
-       /*
-        * The "Shader" class represents a GLSL program made from shaders. 
+       /**
+        * The "Shader" class represents a GLSL program made from shaders.
         */
        class ShaderProgram
        {
        public:
                ShaderProgram() : m_program(0) {}
                ~ShaderProgram();
-               bool AttachVertexProgram(const char *src);
-               bool AttachFragmentProgram(const char *src);
-               bool AttachGeometryProgram(const char *src);
-               bool Link();
+
+               inline bool AttachGeometryProgram(const char * geometry_file) {return AttachShader(geometry_file, GL_GEOMETRY_SHADER);}
+               inline bool AttachVertexProgram(const char * vertex_file) {return AttachShader(vertex_file, GL_VERTEX_SHADER);}
+               inline bool AttachFragmentProgram(const char * fragment_file) {return AttachShader(fragment_file, GL_FRAGMENT_SHADER);}
+
+               /** Read shaders from files and attach them
+                * @returns false if any of the shaders cannot be attached
+                */
+               inline bool AttachShaderPrograms(const char * geometry_file, const char * vertex_file, const char * fragment_file)
+               {
+                       return AttachGeometryProgram(geometry_file) && AttachVertexProgram(vertex_file) && AttachFragmentProgram(fragment_file);
+               }
+               bool Link(); // currently always returns true?
                const void Use() const;
                // Unfortunately, we don't require GL 4.3/ARB_explicit_uniform_location
                // which would make this obsolete. One uday Mesa will support it.
@@ -26,9 +35,12 @@ namespace IPDF
                // Mesa supports ARB_shading_language_420pack, but that'd be a bit more
                // work right with the way some of our uniforms are laid out at the moment.
                const GLint GetUniformLocation(const char *uniform_name) const;
+
        private:
                void LazyCreateProgram();
-               bool AttachShader(const char *src, GLenum type);
+               /** Read shader source from src_file and attach it as type **/
+               bool AttachShader(const char * src_file, GLenum type);
+               char * GetShaderSource(const char * src_file) const;
                GLuint m_program;
                struct Shader
                {
diff --git a/src/shaders/basictex_frag.glsl b/src/shaders/basictex_frag.glsl
new file mode 100644 (file)
index 0000000..534ff02
--- /dev/null
@@ -0,0 +1,15 @@
+#version 140
+
+in vec2 fp_tex_coord;
+
+out vec4 output_colour;
+
+uniform sampler2D tex;
+uniform vec4 colour;
+
+void main()
+{
+       output_colour = colour;
+       output_colour.a = texture(tex, fp_tex_coord).r;
+}
+
diff --git a/src/shaders/basictex_vert.glsl b/src/shaders/basictex_vert.glsl
new file mode 100644 (file)
index 0000000..1b65864
--- /dev/null
@@ -0,0 +1,25 @@
+#version 140
+#extension GL_ARB_shading_language_420pack : require
+#extension GL_ARB_explicit_attrib_location : require
+
+layout(std140, binding=0) uniform Viewport
+{
+       float width;
+       float height;
+};
+
+layout(location = 0) in vec2 position;
+layout(location = 1) in vec2 tex_coord;
+
+out vec2 fp_tex_coord;
+
+void main()
+{
+       // Transform to clip coordinates (-1,1, -1,1).
+       gl_Position.x = (position.x*2/width) - 1;
+       gl_Position.y = 1 - (position.y*2/height);
+       gl_Position.z = 0.0;
+       gl_Position.w = 1.0;
+       fp_tex_coord = tex_coord;
+}
+
diff --git a/src/shaders/circle_filled_geom.glsl b/src/shaders/circle_filled_geom.glsl
new file mode 100644 (file)
index 0000000..c9f54da
--- /dev/null
@@ -0,0 +1,22 @@
+#version 150
+
+layout(lines) in;
+layout(triangle_strip, max_vertices = 4) out;
+out vec2 objcoords;
+
+void main()
+{
+       gl_Position = gl_in[0].gl_Position;
+       objcoords = vec2(-1.0, -1.0);
+       EmitVertex();
+       gl_Position = vec4(gl_in[0].gl_Position.x, gl_in[1].gl_Position.y, 0.0, 1.0);
+       objcoords = vec2(-1.0, 1.0);
+       EmitVertex();
+       gl_Position = vec4(gl_in[1].gl_Position.x, gl_in[0].gl_Position.y, 0.0, 1.0);
+       objcoords = vec2(1.0, -1.0);
+       EmitVertex();
+       gl_Position = gl_in[1].gl_Position;
+       objcoords = vec2(1.0, 1.0);
+       EmitVertex();
+       EndPrimitive();
+}
diff --git a/src/shaders/circle_frag.glsl b/src/shaders/circle_frag.glsl
new file mode 100644 (file)
index 0000000..b4fab10
Binary files /dev/null and b/src/shaders/circle_frag.glsl differ
diff --git a/src/shaders/rect_filled_geom.glsl b/src/shaders/rect_filled_geom.glsl
new file mode 100644 (file)
index 0000000..2793ab7
--- /dev/null
@@ -0,0 +1,17 @@
+#version 150
+
+layout(lines) in;
+layout(triangle_strip, max_vertices = 4) out;
+
+void main()
+{
+       gl_Position = gl_in[0].gl_Position;
+       EmitVertex();
+       gl_Position = vec4(gl_in[0].gl_Position.x, gl_in[1].gl_Position.y, 0.0, 1.0);
+       EmitVertex();
+       gl_Position = vec4(gl_in[1].gl_Position.x, gl_in[0].gl_Position.y, 0.0, 1.0);
+       EmitVertex();
+       gl_Position = gl_in[1].gl_Position;
+       EmitVertex();
+       EndPrimitive();
+}
diff --git a/src/shaders/rect_frag.glsl b/src/shaders/rect_frag.glsl
new file mode 100644 (file)
index 0000000..649805f
--- /dev/null
@@ -0,0 +1,10 @@
+#version 140
+
+out vec4 output_colour;
+
+uniform vec4 colour;
+
+void main()
+{
+       output_colour = colour;
+}
diff --git a/src/shaders/rect_outline_geom.glsl b/src/shaders/rect_outline_geom.glsl
new file mode 100644 (file)
index 0000000..20ad319
--- /dev/null
@@ -0,0 +1,20 @@
+#version 150
+
+layout(lines) in;
+layout(line_strip, max_vertices = 5) out;
+
+void main()
+{
+       gl_Position = gl_in[0].gl_Position;
+       EmitVertex();
+       gl_Position = vec4(gl_in[0].gl_Position.x, gl_in[1].gl_Position.y, 0.0, 1.0);
+       EmitVertex();
+       gl_Position = gl_in[1].gl_Position;
+       EmitVertex();
+       gl_Position = vec4(gl_in[1].gl_Position.x, gl_in[0].gl_Position.y, 0.0, 1.0);
+       EmitVertex();
+       gl_Position = gl_in[0].gl_Position;
+       EmitVertex();
+       EndPrimitive();
+}
+
diff --git a/src/shaders/rect_vert.glsl b/src/shaders/rect_vert.glsl
new file mode 100644 (file)
index 0000000..cc15e56
--- /dev/null
@@ -0,0 +1,25 @@
+#version 140
+#extension GL_ARB_shading_language_420pack : require
+#extension GL_ARB_explicit_attrib_location : require
+
+layout(std140, binding=0) uniform ViewBounds
+{
+       float bounds_x;
+       float bounds_y;
+       float bounds_w;
+       float bounds_h;
+};
+
+layout(location = 0) in vec2 position;
+
+void main()
+{
+       vec2 transformed_position;
+       transformed_position.x = (position.x - bounds_x) / bounds_w;
+       transformed_position.y = (position.y - bounds_y) / bounds_h;
+       // Transform to clip coordinates (-1,1, -1,1).
+       gl_Position.x = (transformed_position.x*2) - 1;
+       gl_Position.y = 1 - (transformed_position.y*2);
+       gl_Position.z = 0.0;
+       gl_Position.w = 1.0;
+}
index 1e68ec2..ea0389c 100644 (file)
@@ -8,7 +8,7 @@
 #include <unordered_map> // hashtable
 #include <map>
 #include "screen.h"
-#include <algorithm>
+
 #include "pointstobitmap.h"
 
 using namespace std;
diff --git a/src/tests/lines.cpp b/src/tests/lines.cpp
new file mode 100644 (file)
index 0000000..b15d218
--- /dev/null
@@ -0,0 +1,76 @@
+#include "main.h"
+
+#include "pointstobitmap.h"
+
+using namespace std;
+
+/**
+ * NOTE: I am using vector<pair<T,T> > because it is convenient; don't have to round to pixels, can print to stdout and gnuplot, etc
+ *             vector<pair<T,T> > should obviously not be used in a practical implementation; directly access the pixel buffer
+ */
+
+template <class T> vector<pair<T, T> > LineDDA(const T & x1, const T & y1, const T & x2, const T & y2)
+{
+       T dx = x2 - x1;
+       T dy = y2 - y1;
+       uint64_t steps = lround(max(abs(dx), abs(dy)));
+       T xInc = T(dx)/T(steps);
+       T yInc = T(dy)/T(steps);
+       T x = x1; T y = y1;
+       vector<pair<T,T> > result(steps);
+       for (uint64_t k = 0; k <= steps; ++k)
+       {
+               result[k] = pair<T,T>(round(x), round(y));
+               x += xInc;
+               y += yInc;
+       }
+       return result;
+}
+/**
+ * Only works for 0 < m < 1
+ */
+template <class T> vector<pair<T, T> > LineBresenham(const T & x1, const T & y1, const T & x2, const T & y2)
+{
+       T dx = abs(x2 - x1);
+       T dy = abs(y2 - y1);
+       T p = 2*dy - dx;
+       T two_dy = 2*dy;
+       T two_dxdy = 2*(dy-dx);
+
+       T x; T y; T xEnd;
+       if (x1 > x2)
+       {
+               x = x2;
+               y = y2;
+               xEnd = x1;
+       }
+       else
+       {
+               x = x1;
+               y = y1;
+               xEnd = x2;
+       }
+       vector<pair<T,T> > result;
+       while (x < xEnd)
+       {
+               x += 1;
+               if (p < 0)
+                       p += two_dy;
+               else
+               {
+                       y += 1;
+                       p += two_dxdy;
+               }
+               result.emplace_back(pair<T,T>(x,y));
+       }
+       return result;
+}
+
+int main(int argc, char ** argv)
+{
+       auto f = LineDDA<float>(0,0,400,200);
+       PointsToBitmap<float>(f, 1, 0,0,0,"lines.bmp");
+       auto i = LineBresenham<int>(0,100,400,300);
+       i.push_back(pair<int,int>(0,0));
+       PointsToBitmap<int>(i, 1, 255,0,0,"lines.bmp", true);
+}
index 90bfbdb..36db365 100644 (file)
@@ -2,6 +2,22 @@
 #define _POINTSTOBITMAP_H
 
 #include <SDL.h>
+#include <algorithm> // for min/max_element
+
+void AntiAlias(unsigned char * pixels, uint64_t w, uint64_t h, uint8_t stride = 4)
+{
+       int ri = (SDL_BYTEORDER == SDL_LIL_ENDIAN) ? 0 : 3;
+       int gi = (SDL_BYTEORDER == SDL_LIL_ENDIAN) ? 1 : 2;
+       int bi = (SDL_BYTEORDER == SDL_LIL_ENDIAN) ? 2 : 1;
+       for (uint64_t x = 1; x < w-1; ++x)
+       {
+               for (uint64_t y = 1; y < h-1; ++y)
+               {
+                       uint64_t index = stride*(y*w + x);
+                       
+               }
+       }
+}
 
 /**
  * Map vector of points onto a Bitmap
@@ -60,7 +76,16 @@ template <class T> void PointsToBitmap(const vector<pair<T, T> > & points, const
 
        pair<LD,LD> min(left.first, bottom.second);
        pair<LD,LD> max(right.first, top.second);
-
+       // Force to be square
+       if (max.first - min.first > max.second - min.second)
+       {
+               max.second = min.second + (max.first - min.first);
+       }
+       else
+       {
+               max.first = min.first + (max.second - min.second);
+       }
+       Debug("Bitmap: %llf %llf -> %llf %llf", min.first, min.second, max.first, max.second);
        // Alternately, just do this:
        /* 
        pair<LD,LD> min(-scale, -scale);
index c576802..b893f97 100644 (file)
@@ -242,14 +242,14 @@ int main(int argc, char ** argv)
        printf("# Convert custom floats to a Real\n");
        printf("# a\thex(a)\tReal(a)\tdelta(last2)\n");
 
-       typedef uint16_t Bits;
+       typedef uint8_t Bits;
        typedef pair<Bits, Real> Pear;
-       const uint8_t E = 5;
-       const uint8_t P = 10;
+       const uint8_t E = 3;
+       const uint8_t P = 4;
        
        list<Pear> space;
-       Bits a0 = 0x0000;
-       for (Bits a = a0; a < 0xFFFF; ++a)
+       Bits a0 = 0x00;
+       for (Bits a = a0; a < 0xFF; ++a)
        {
                Real x = BitsToReal<E,P>(&a);
                Bits b = 0; BitsFromReal<E,P>(x, &b);
@@ -274,4 +274,4 @@ int main(int argc, char ** argv)
 
 //0|011 11|00 0000 0001 
 
-//0|000 01|00 0000 0000
\ No newline at end of file
+//0|000 01|00 0000 0000
index a92da9b..fd26b13 100644 (file)
 
 using namespace IPDF;
 using namespace std;
-#define RECT_VERT \
-       "#version 140\n"\
-       "#extension GL_ARB_shading_language_420pack : require\n"\
-       "#extension GL_ARB_explicit_attrib_location : require\n"\
-       "\n"\
-       "layout(std140, binding=0) uniform ViewBounds\n"\
-       "{\n"\
-       "\tfloat bounds_x;\n"\
-       "\tfloat bounds_y;\n"\
-       "\tfloat bounds_w;\n"\
-       "\tfloat bounds_h;\n"\
-       "};\n"\
-       "\n"\
-       "layout(location = 0) in vec2 position;\n"\
-       "\n"\
-       "void main()\n"\
-       "{\n"\
-       "\tvec2 transformed_position;\n"\
-       "\ttransformed_position.x = (position.x - bounds_x) / bounds_w;\n"\
-       "\ttransformed_position.y = (position.y - bounds_y) / bounds_h;\n"\
-       "\t// Transform to clip coordinates (-1,1, -1,1).\n"\
-       "\tgl_Position.x = (transformed_position.x*2) - 1;\n"\
-       "\tgl_Position.y = 1 - (transformed_position.y*2);\n"\
-       "\tgl_Position.z = 0.0;\n"\
-       "\tgl_Position.w = 1.0;\n"\
-       "}\n"
-
-#define RECT_FRAG \
-       "#version 140\n"\
-       "\n"\
-       "out vec4 output_colour;\n"\
-       "\n"\
-       "uniform vec4 colour;\n"\
-       "\n"\
-       "void main()\n"\
-       "{\n"\
-       "\toutput_colour = colour;\n"\
-       "}\n"
-
-#define RECT_OUTLINE_GEOM \
-       "#version 150\n"\
-       "\n"\
-       "layout(lines) in;\n"\
-       "layout(line_strip, max_vertices = 5) out;\n"\
-       "\n"\
-       "void main()\n"\
-       "{\n"\
-       "\tgl_Position = gl_in[0].gl_Position;\n"\
-       "\tEmitVertex();\n"\
-       "\tgl_Position = vec4(gl_in[0].gl_Position.x, gl_in[1].gl_Position.y, 0.0, 1.0);\n"\
-       "\tEmitVertex();\n"\
-       "\tgl_Position = gl_in[1].gl_Position;\n"\
-       "\tEmitVertex();\n"\
-       "\tgl_Position = vec4(gl_in[1].gl_Position.x, gl_in[0].gl_Position.y, 0.0, 1.0);\n"\
-       "\tEmitVertex();\n"\
-       "\tgl_Position = gl_in[0].gl_Position;\n"\
-       "\tEmitVertex();\n"\
-       "\tEndPrimitive();\n"\
-       "}\n"
-
-#define RECT_FILLED_GEOM \
-       "#version 150\n"\
-       "\n"\
-       "layout(lines) in;\n"\
-       "layout(triangle_strip, max_vertices = 4) out;\n"\
-       "\n"\
-       "void main()\n"\
-       "{\n"\
-       "\tgl_Position = gl_in[0].gl_Position;\n"\
-       "\tEmitVertex();\n"\
-       "\tgl_Position = vec4(gl_in[0].gl_Position.x, gl_in[1].gl_Position.y, 0.0, 1.0);\n"\
-       "\tEmitVertex();\n"\
-       "\tgl_Position = vec4(gl_in[1].gl_Position.x, gl_in[0].gl_Position.y, 0.0, 1.0);\n"\
-       "\tEmitVertex();\n"\
-       "\tgl_Position = gl_in[1].gl_Position;\n"\
-       "\tEmitVertex();\n"\
-       "\tEndPrimitive();\n"\
-       "}\n"
-
-#define CIRCLE_FILLED_GEOM \
-       "#version 150\n"\
-       "\n"\
-       "layout(lines) in;\n"\
-       "layout(triangle_strip, max_vertices = 4) out;\n"\
-       "out vec2 objcoords;\n"\
-       "\n"\
-       "void main()\n"\
-       "{\n"\
-       "\tgl_Position = gl_in[0].gl_Position;\n"\
-       "\tobjcoords = vec2(-1.0, -1.0);\n"\
-       "\tEmitVertex();\n"\
-       "\tgl_Position = vec4(gl_in[0].gl_Position.x, gl_in[1].gl_Position.y, 0.0, 1.0);\n"\
-       "\tobjcoords = vec2(-1.0, 1.0);\n"\
-       "\tEmitVertex();\n"\
-       "\tgl_Position = vec4(gl_in[1].gl_Position.x, gl_in[0].gl_Position.y, 0.0, 1.0);\n"\
-       "\tobjcoords = vec2(1.0, -1.0);\n"\
-       "\tEmitVertex();\n"\
-       "\tgl_Position = gl_in[1].gl_Position;\n"\
-       "\tobjcoords = vec2(1.0, 1.0);\n"\
-       "\tEmitVertex();\n"\
-       "\tEndPrimitive();\n"\
-       "}\n"
-
-#define CIRCLE_FRAG \
-       "#version 140\n"\
-       "\n"\
-       "in vec2 objcoords;\n"\
-       "out vec4 output_colour;\n"\
-       "\n"\
-       "uniform vec4 colour;\n"\
-       "\n"\
-       "void main()\n"\
-       "{\n"\
-       "\tif ((objcoords.x)*(objcoords.x) + (objcoords.y)*(objcoords.y) > 1.0)\n"\
-       "\t{\n"\
-       "\t\tdiscard;\n"\
-       "\t}\n"\
-       "\toutput_colour = colour;\n"\
-       "}\n"
+#define RECT_VERT "shaders/rect_vert.glsl"
+#define RECT_FRAG "shaders/rect_frag.glsl"
+#define RECT_OUTLINE_GEOM "shaders/rect_outline_geom.glsl"
+#define RECT_FILLED_GEOM "shaders/rect_filled_geom.glsl"
+#define CIRCLE_FILLED_GEOM "shaders/circle_filled_geom.glsl"
+#define CIRCLE_FRAG "shaders/circle_frag.glsl"
 
 void View::Translate(Real x, Real y)
 {
@@ -327,23 +214,18 @@ void View::UpdateObjBoundsVBO()
 void View::PrepareRender()
 {
        // TODO: Error check here.
-       m_rect_outline_shader.AttachGeometryProgram(RECT_OUTLINE_GEOM);
-       m_rect_outline_shader.AttachVertexProgram(RECT_VERT);
-       m_rect_outline_shader.AttachFragmentProgram(RECT_FRAG);
+
+       m_rect_outline_shader.AttachShaderPrograms(RECT_OUTLINE_GEOM, RECT_VERT, RECT_FRAG);
        m_rect_outline_shader.Link();
        m_rect_outline_shader.Use();
        glUniform4f(m_rect_outline_shader.GetUniformLocation("colour"), m_colour.r, m_colour.g, m_colour.b, m_colour.a);
 
-       m_rect_filled_shader.AttachGeometryProgram(RECT_FILLED_GEOM);
-       m_rect_filled_shader.AttachVertexProgram(RECT_VERT);
-       m_rect_filled_shader.AttachFragmentProgram(RECT_FRAG);
+       m_rect_filled_shader.AttachShaderPrograms(RECT_FILLED_GEOM, RECT_VERT, RECT_FRAG);
        m_rect_filled_shader.Link();
        m_rect_filled_shader.Use();
        glUniform4f(m_rect_filled_shader.GetUniformLocation("colour"), m_colour.r, m_colour.g, m_colour.b, m_colour.a);
 
-       m_circle_filled_shader.AttachGeometryProgram(CIRCLE_FILLED_GEOM);
-       m_circle_filled_shader.AttachVertexProgram(RECT_VERT);
-       m_circle_filled_shader.AttachFragmentProgram(CIRCLE_FRAG);
+       m_circle_filled_shader.AttachShaderPrograms(CIRCLE_FILLED_GEOM, RECT_VERT, CIRCLE_FRAG);
        m_circle_filled_shader.Link();
        m_circle_filled_shader.Use();
        glUniform4f(m_circle_filled_shader.GetUniformLocation("colour"), m_colour.r, m_colour.g, m_colour.b, m_colour.a);

UCC git Repository :: git.ucc.asn.au