Browse Source

Added shader support

Dalton Nell 9 years ago
parent
commit
437eccc73b

+ 10
- 0
CMakeLists.txt View File

79
      src/cmdline.c
79
      src/cmdline.c
80
      src/selectrectangle.cpp
80
      src/selectrectangle.cpp
81
      src/glselectrectangle.cpp
81
      src/glselectrectangle.cpp
82
+     src/shader.cpp
83
+     src/framebuffer.cpp
82
      src/resource.cpp
84
      src/resource.cpp
83
      src/xselectrectangle.cpp
85
      src/xselectrectangle.cpp
84
      src/x.cpp
86
      src/x.cpp
93
 find_package( XRender   REQUIRED )
95
 find_package( XRender   REQUIRED )
94
 find_package( XRandr    REQUIRED )
96
 find_package( XRandr    REQUIRED )
95
 find_package( DevIL     REQUIRED )
97
 find_package( DevIL     REQUIRED )
98
+find_package( GLEW      REQUIRED )
96
 # This library is needed only for Ubuntu it seems, some platforms don't even
99
 # This library is needed only for Ubuntu it seems, some platforms don't even
97
 # ship with it. I couldn't find a way to do a test compile to check if librt
100
 # ship with it. I couldn't find a way to do a test compile to check if librt
98
 # was needed, so instead I just didn't mark it as REQUIRED.
101
 # was needed, so instead I just didn't mark it as REQUIRED.
109
                          ${OPENGL_INCLUDE_DIR}
112
                          ${OPENGL_INCLUDE_DIR}
110
                          ${IL_INCLUDE_DIR}
113
                          ${IL_INCLUDE_DIR}
111
                          ${GLX_INCLUDE_DIR}
114
                          ${GLX_INCLUDE_DIR}
115
+                         ${GLEW_INCLUDE_DIRS}
112
                          ${XRENDER_INCLUDE_DIRS}
116
                          ${XRENDER_INCLUDE_DIRS}
113
                          ${RT_INCLUDE_DIR} )
117
                          ${RT_INCLUDE_DIR} )
114
 else()
118
 else()
115
     include_directories( ${X11_INCLUDE_DIR}
119
     include_directories( ${X11_INCLUDE_DIR}
116
                          ${OPENGL_INCLUDE_DIR}
120
                          ${OPENGL_INCLUDE_DIR}
117
                          ${IL_INCLUDE_DIR}
121
                          ${IL_INCLUDE_DIR}
122
+                         ${GLEW_INCLUDE_DIRS}
118
                          ${GLX_INCLUDE_DIR}
123
                          ${GLX_INCLUDE_DIR}
119
                          ${XEXT_INCLUDE_DIR} )
124
                          ${XEXT_INCLUDE_DIR} )
120
 endif()
125
 endif()
130
                            ${IL_LIBRARIES}
135
                            ${IL_LIBRARIES}
131
                            ${ILUT_LIBRARIES}
136
                            ${ILUT_LIBRARIES}
132
                            ${GLX_LIBRARIES}
137
                            ${GLX_LIBRARIES}
138
+                           ${GLEW_LIBRARIES}
133
                            ${XRENDER_LIBRARIES}
139
                            ${XRENDER_LIBRARIES}
134
                            "${XEXT_LIBRARY}"
140
                            "${XEXT_LIBRARY}"
135
                            "${XRANDR_LIBRARY}"
141
                            "${XRANDR_LIBRARY}"
139
                            ${OPENGL_LIBRARIES}
145
                            ${OPENGL_LIBRARIES}
140
                            ${IL_LIBRARIES}
146
                            ${IL_LIBRARIES}
141
                            ${ILUT_LIBRARIES}
147
                            ${ILUT_LIBRARIES}
148
+                           ${GLEW_LIBRARIES}
142
                            ${GLX_LIBRARIES}
149
                            ${GLX_LIBRARIES}
143
                            ${X11_LIBRARIES}
150
                            ${X11_LIBRARIES}
144
                            "${XEXT_LIBRARY}" )
151
                            "${XEXT_LIBRARY}" )
147
 install( TARGETS ${BIN_TARGET}
154
 install( TARGETS ${BIN_TARGET}
148
          DESTINATION "${CMAKE_INSTALL_PREFIX}/bin" )
155
          DESTINATION "${CMAKE_INSTALL_PREFIX}/bin" )
149
 
156
 
157
+install( DIRECTORY "${CMAKE_SOURCE_DIR}/share"
158
+         DESTINATION "${CMAKE_INSTALL_PREFIX}" )
159
+
150
 add_definitions(-DINSTALL_PREFIX="${CMAKE_INSTALL_PREFIX}")
160
 add_definitions(-DINSTALL_PREFIX="${CMAKE_INSTALL_PREFIX}")

+ 1
- 0
share/slop/gothic/corner_bl.png View File

1
+corner_tl.png

+ 1
- 0
share/slop/gothic/corner_br.png View File

1
+corner_tl.png

BIN
share/slop/gothic/corner_tl.png View File


+ 1
- 0
share/slop/gothic/corner_tr.png View File

1
+corner_tl.png

BIN
share/slop/gothic/straight.png View File


+ 89
- 0
share/slop/refract.frag View File

1
+#version 120
2
+
3
+uniform sampler2D texture;
4
+uniform sampler2D desktop;
5
+uniform int desktopWidth;
6
+uniform int desktopHeight;
7
+uniform float time;
8
+
9
+varying vec2 uvCoord;
10
+
11
+vec2 getDesktopUV( vec2 uv ) {
12
+    // Desktop image is upside-down, blame X11 lmao
13
+    uv.y = -uv.y;
14
+    return uv;
15
+}
16
+
17
+const float pi = 3.14159265f;
18
+
19
+void main() {
20
+    float sigma = 5;
21
+    float numBlurPixelsPerSide = 2.0f;
22
+    float blurMultiplier = 2.0f;
23
+
24
+    // Don't change anything below.
25
+    float blurSize = 1.f/desktopHeight*blurMultiplier;
26
+    vec2  blurMultiplyVec      = vec2(0.0f, 1.0f);
27
+    // Higher strength means bigger wobble
28
+    float strength = 8;
29
+    // Higher speed means faster wobble
30
+    float speed = 1;
31
+    float x = (sin( time*speed + uvCoord.y * desktopHeight/strength ) + 0.5)/desktopWidth*strength;
32
+    float y = (cos( time*speed + uvCoord.x * desktopWidth/strength ) + 0.5)/desktopHeight*strength;
33
+    x = x - (sin( time*speed*0.5 + uvCoord.y * desktopHeight/strength ) + 0.5)/desktopWidth*strength/2;
34
+    y = y - (cos( time*speed*0.5 + uvCoord.x * desktopWidth/strength ) + 0.5)/desktopHeight*strength/2;
35
+    vec2 offset = vec2(x,y);
36
+
37
+    // Incremental Gaussian Coefficent Calculation (See GPU Gems 3 pp. 877 - 889)
38
+    vec3 incrementalGaussian;
39
+    incrementalGaussian.x = 1.0f / (sqrt(2.0f * pi) * sigma);
40
+    incrementalGaussian.y = exp(-0.5f / (sigma * sigma));
41
+    incrementalGaussian.z = incrementalGaussian.y * incrementalGaussian.y;
42
+
43
+    vec4 avgValue = vec4(0.0f, 0.0f, 0.0f, 0.0f);
44
+    float coefficientSum = 0.0f;
45
+
46
+    // Take the central sample first...
47
+    vec4 color = texture2D( desktop, getDesktopUV( uvCoord.xy ) + offset );
48
+    color.a = texture2D( texture, uvCoord.xy ).a;
49
+    avgValue += color * incrementalGaussian.x;
50
+    coefficientSum += incrementalGaussian.x;
51
+    incrementalGaussian.xy *= incrementalGaussian.yz;
52
+
53
+    // Go through the remaining 8 vertical samples (4 on each side of the center)
54
+    for (float i = 1.0f; i <= numBlurPixelsPerSide; i++) {
55
+        vec2 uv = (uvCoord.xy - i * blurSize * blurMultiplyVec);
56
+        color = texture2D( desktop, getDesktopUV( uv ) + offset );
57
+        color.a = texture2D( texture, uv ).a;
58
+        avgValue += color * incrementalGaussian.x;
59
+        uv = (uvCoord.xy + i * blurSize * blurMultiplyVec);
60
+        color = texture2D( desktop, getDesktopUV( uv ) + offset );
61
+        color.a = texture2D( texture, uv ).a;
62
+        avgValue += color * incrementalGaussian.x;
63
+        coefficientSum += 2 * incrementalGaussian.x;
64
+        incrementalGaussian.xy *= incrementalGaussian.yz;
65
+    }
66
+
67
+    //Reset
68
+    blurSize = 1.f/desktopWidth*blurMultiplier;
69
+    blurMultiplyVec      = vec2(1.0f, 0.0f);
70
+    incrementalGaussian.x = 1.0f / (sqrt(2.0f * pi) * sigma);
71
+    incrementalGaussian.y = exp(-0.5f / (sigma * sigma));
72
+    incrementalGaussian.z = incrementalGaussian.y * incrementalGaussian.y;
73
+
74
+    // Go through the remaining 8 horizontal samples (4 on each side of the center)
75
+    for (float i = 1.0f; i <= numBlurPixelsPerSide; i++) {
76
+        vec2 uv = (uvCoord.xy - i * blurSize * blurMultiplyVec);
77
+        vec4 color = texture2D( desktop, getDesktopUV( uv ) + offset );
78
+        color.a = texture2D( texture, uv ).a;
79
+        avgValue += color * incrementalGaussian.x;
80
+        uv = (uvCoord.xy + i * blurSize * blurMultiplyVec);
81
+        color = texture2D( desktop, getDesktopUV( uv ) + offset );
82
+        color.a = texture2D( texture, uv ).a;
83
+        avgValue += color * incrementalGaussian.x;
84
+        coefficientSum += 2 * incrementalGaussian.x;
85
+        incrementalGaussian.xy *= incrementalGaussian.yz;
86
+    }
87
+
88
+    gl_FragColor = avgValue / coefficientSum;
89
+}

+ 12
- 0
share/slop/refract.vert View File

1
+#version 120
2
+
3
+attribute vec2 vertex;
4
+attribute vec2 uv;
5
+
6
+varying vec2 uvCoord;
7
+
8
+void main()
9
+{
10
+    uvCoord = uv;
11
+	gl_Position = vec4(vertex,0,1);
12
+}

+ 12
- 0
share/slop/simple.frag View File

1
+#version 120
2
+
3
+uniform sampler2D texture;
4
+uniform sampler2D desktop;
5
+uniform float time;
6
+
7
+varying vec2 uvCoord;
8
+
9
+void main()
10
+{
11
+    gl_FragColor = texture2D( texture, uvCoord );
12
+}

+ 12
- 0
share/slop/simple.vert View File

1
+#version 120
2
+
3
+attribute vec2 vertex;
4
+attribute vec2 uv;
5
+
6
+varying vec2 uvCoord;
7
+
8
+void main()
9
+{
10
+    uvCoord = uv;
11
+	gl_Position = vec4(vertex,0,1);
12
+}

+ 20
- 0
share/slop/wiggle.frag View File

1
+#version 120
2
+
3
+uniform sampler2D texture;
4
+uniform sampler2D desktop;
5
+uniform int desktopWidth;
6
+uniform int desktopHeight;
7
+uniform float time;
8
+
9
+varying vec2 uvCoord;
10
+
11
+void main()
12
+{
13
+    // Higher strength means bigger wobble
14
+    float strength = 8;
15
+    // Higher speed means faster wobble
16
+    float speed = 2;
17
+    float x = uvCoord.x + (sin( time*speed + uvCoord.y * desktopHeight/strength ) + 0.5)/desktopWidth*strength;
18
+    float y = uvCoord.y + (cos( time*speed + uvCoord.x * desktopWidth/strength ) + 0.5)/desktopHeight*strength;
19
+    gl_FragColor = texture2D( texture, vec2( x, y ) );
20
+}

+ 12
- 0
share/slop/wiggle.vert View File

1
+#version 120
2
+
3
+attribute vec2 vertex;
4
+attribute vec2 uv;
5
+
6
+varying vec2 uvCoord;
7
+
8
+void main()
9
+{
10
+    uvCoord = uv;
11
+	gl_Position = vec4(vertex,0,1);
12
+}

+ 50
- 2
src/cmdline.c View File

52
   "      --magnify                 Display a magnifying glass when --opengl is\n                                  also enabled.  (default=off)",
52
   "      --magnify                 Display a magnifying glass when --opengl is\n                                  also enabled.  (default=off)",
53
   "      --magstrength=FLOAT       Sets how many times the magnification window\n                                  size is multiplied.  (default=`4')",
53
   "      --magstrength=FLOAT       Sets how many times the magnification window\n                                  size is multiplied.  (default=`4')",
54
   "      --magpixels=INT           Sets how many pixels are displayed in the\n                                  magnification. The less pixels the bigger the\n                                  magnification.  (default=`64')",
54
   "      --magpixels=INT           Sets how many pixels are displayed in the\n                                  magnification. The less pixels the bigger the\n                                  magnification.  (default=`64')",
55
+  "      --theme=STRING            Sets the theme of the selection, using textures\n                                  from ~/.config/slop/ or /usr/share/.\n                                  (default=`none')",
56
+  "      --shader=STRING           Sets the shader to load and use from\n                                  ~/.config/slop/ or /usr/share/.\n                                  (default=`simple')",
55
   "  -f, --format=STRING           Set the output format string. Format specifiers\n                                  are %x, %y, %w, %h, %i, %g, and %c.\n                                  (default=`X=%x\\nY=%y\\nW=%w\\nH=%h\\nG=%g\\nID=%i\\nCancel=%c\\n')",
57
   "  -f, --format=STRING           Set the output format string. Format specifiers\n                                  are %x, %y, %w, %h, %i, %g, and %c.\n                                  (default=`X=%x\\nY=%y\\nW=%w\\nH=%h\\nG=%g\\nID=%i\\nCancel=%c\\n')",
56
-  "\nExamples\n    $ # Gray, thick, transparent border for maximum visiblity.\n    $ slop -b 20 -c 0.5,0.5,0.5,0.8\n\n    $ # Remove window decorations.\n    $ slop --nodecorations\n\n    $ # Disable window selections. Useful for selecting individual pixels.\n    $ slop -t 0\n\n    $ # Classic Windows XP selection.\n    $ slop -l -c 0.3,0.4,0.6,0.4\n\n    $ # Change output format to use safer parsing\n    $ slopoutput=$(slop -f \"%x %y %w %h\")\n    $ X=$(echo $slopoutput | awk '{print $1}')\n    $ Y=$(echo $slopoutput | awk '{print $2}')\n    $ W=$(echo $slopoutput | awk '{print $3}')\n    $ H=$(echo $slopoutput | awk '{print $4}')\n\nTips\n    * You can use the arrow keys to move the starting point of a\ndrag-selection, just in case you missed it by a few pixels.\n    * If you don't like a selection: you can cancel it by right-clicking\nregardless of which options are enabled or disabled for slop.\n    * If slop doesn't seem to select a window accurately, the problem could be\nbecause of decorations getting in the way. Try enabling the --nodecorations\nflag.\n",
58
+  "\nExamples\n    $ # Gray, thick, transparent border for maximum visiblity.\n    $ slop -b 20 -c 0.5,0.5,0.5,0.8\n\n    $ # Remove window decorations.\n    $ slop --nodecorations\n\n    $ # Disable window selections. Useful for selecting individual pixels.\n    $ slop -t 0\n\n    $ # Classic Windows XP selection.\n    $ slop -l -c 0.3,0.4,0.6,0.4\n\n    $ # Wiggle wiggle!\n    $ slop --opengl --shader wiggle\n\n    $ # Edgy textures or something.\n    $ slop --opengl --theme gothic\n\n    $ # Change output format to use safer parsing\n    $ slopoutput=$(slop -f \"%x %y %w %h\")\n    $ X=$(echo $slopoutput | awk '{print $1}')\n    $ Y=$(echo $slopoutput | awk '{print $2}')\n    $ W=$(echo $slopoutput | awk '{print $3}')\n    $ H=$(echo $slopoutput | awk '{print $4}')\n\nTips\n    * You can use the arrow keys to move the starting point of a\ndrag-selection, just in case you missed it by a few pixels.\n    * If you don't like a selection: you can cancel it by right-clicking\nregardless of which options are enabled or disabled for slop.\n    * If slop doesn't seem to select a window accurately, the problem could be\nbecause of decorations getting in the way. Try enabling the --nodecorations\nflag.\n",
57
     0
59
     0
58
 };
60
 };
59
 
61
 
97
   args_info->magnify_given = 0 ;
99
   args_info->magnify_given = 0 ;
98
   args_info->magstrength_given = 0 ;
100
   args_info->magstrength_given = 0 ;
99
   args_info->magpixels_given = 0 ;
101
   args_info->magpixels_given = 0 ;
102
+  args_info->theme_given = 0 ;
103
+  args_info->shader_given = 0 ;
100
   args_info->format_given = 0 ;
104
   args_info->format_given = 0 ;
101
 }
105
 }
102
 
106
 
129
   args_info->magstrength_orig = NULL;
133
   args_info->magstrength_orig = NULL;
130
   args_info->magpixels_arg = 64;
134
   args_info->magpixels_arg = 64;
131
   args_info->magpixels_orig = NULL;
135
   args_info->magpixels_orig = NULL;
136
+  args_info->theme_arg = gengetopt_strdup ("none");
137
+  args_info->theme_orig = NULL;
138
+  args_info->shader_arg = gengetopt_strdup ("simple");
139
+  args_info->shader_orig = NULL;
132
   args_info->format_arg = gengetopt_strdup ("X=%x\nY=%y\nW=%w\nH=%h\nG=%g\nID=%i\nCancel=%c\n");
140
   args_info->format_arg = gengetopt_strdup ("X=%x\nY=%y\nW=%w\nH=%h\nG=%g\nID=%i\nCancel=%c\n");
133
   args_info->format_orig = NULL;
141
   args_info->format_orig = NULL;
134
   
142
   
156
   args_info->magnify_help = gengetopt_args_info_help[15] ;
164
   args_info->magnify_help = gengetopt_args_info_help[15] ;
157
   args_info->magstrength_help = gengetopt_args_info_help[16] ;
165
   args_info->magstrength_help = gengetopt_args_info_help[16] ;
158
   args_info->magpixels_help = gengetopt_args_info_help[17] ;
166
   args_info->magpixels_help = gengetopt_args_info_help[17] ;
159
-  args_info->format_help = gengetopt_args_info_help[18] ;
167
+  args_info->theme_help = gengetopt_args_info_help[18] ;
168
+  args_info->shader_help = gengetopt_args_info_help[19] ;
169
+  args_info->format_help = gengetopt_args_info_help[20] ;
160
   
170
   
161
 }
171
 }
162
 
172
 
253
   free_string_field (&(args_info->max_orig));
263
   free_string_field (&(args_info->max_orig));
254
   free_string_field (&(args_info->magstrength_orig));
264
   free_string_field (&(args_info->magstrength_orig));
255
   free_string_field (&(args_info->magpixels_orig));
265
   free_string_field (&(args_info->magpixels_orig));
266
+  free_string_field (&(args_info->theme_arg));
267
+  free_string_field (&(args_info->theme_orig));
268
+  free_string_field (&(args_info->shader_arg));
269
+  free_string_field (&(args_info->shader_orig));
256
   free_string_field (&(args_info->format_arg));
270
   free_string_field (&(args_info->format_arg));
257
   free_string_field (&(args_info->format_orig));
271
   free_string_field (&(args_info->format_orig));
258
   
272
   
319
     write_into_file(outfile, "magstrength", args_info->magstrength_orig, 0);
333
     write_into_file(outfile, "magstrength", args_info->magstrength_orig, 0);
320
   if (args_info->magpixels_given)
334
   if (args_info->magpixels_given)
321
     write_into_file(outfile, "magpixels", args_info->magpixels_orig, 0);
335
     write_into_file(outfile, "magpixels", args_info->magpixels_orig, 0);
336
+  if (args_info->theme_given)
337
+    write_into_file(outfile, "theme", args_info->theme_orig, 0);
338
+  if (args_info->shader_given)
339
+    write_into_file(outfile, "shader", args_info->shader_orig, 0);
322
   if (args_info->format_given)
340
   if (args_info->format_given)
323
     write_into_file(outfile, "format", args_info->format_orig, 0);
341
     write_into_file(outfile, "format", args_info->format_orig, 0);
324
   
342
   
596
         { "magnify",	0, NULL, 0 },
614
         { "magnify",	0, NULL, 0 },
597
         { "magstrength",	1, NULL, 0 },
615
         { "magstrength",	1, NULL, 0 },
598
         { "magpixels",	1, NULL, 0 },
616
         { "magpixels",	1, NULL, 0 },
617
+        { "theme",	1, NULL, 0 },
618
+        { "shader",	1, NULL, 0 },
599
         { "format",	1, NULL, 'f' },
619
         { "format",	1, NULL, 'f' },
600
         { 0,  0, 0, 0 }
620
         { 0,  0, 0, 0 }
601
       };
621
       };
815
                 additional_error))
835
                 additional_error))
816
               goto failure;
836
               goto failure;
817
           
837
           
838
+          }
839
+          /* Sets the theme of the selection, using textures from ~/.config/slop/ or /usr/share/..  */
840
+          else if (strcmp (long_options[option_index].name, "theme") == 0)
841
+          {
842
+          
843
+          
844
+            if (update_arg( (void *)&(args_info->theme_arg), 
845
+                 &(args_info->theme_orig), &(args_info->theme_given),
846
+                &(local_args_info.theme_given), optarg, 0, "none", ARG_STRING,
847
+                check_ambiguity, override, 0, 0,
848
+                "theme", '-',
849
+                additional_error))
850
+              goto failure;
851
+          
852
+          }
853
+          /* Sets the shader to load and use from ~/.config/slop/ or /usr/share/..  */
854
+          else if (strcmp (long_options[option_index].name, "shader") == 0)
855
+          {
856
+          
857
+          
858
+            if (update_arg( (void *)&(args_info->shader_arg), 
859
+                 &(args_info->shader_orig), &(args_info->shader_given),
860
+                &(local_args_info.shader_given), optarg, 0, "simple", ARG_STRING,
861
+                check_ambiguity, override, 0, 0,
862
+                "shader", '-',
863
+                additional_error))
864
+              goto failure;
865
+          
818
           }
866
           }
819
           
867
           
820
           break;
868
           break;

+ 8
- 0
src/cmdline.in View File

79
   int magpixels_arg;	/**< @brief Sets how many pixels are displayed in the magnification. The less pixels the bigger the magnification. (default='64').  */
79
   int magpixels_arg;	/**< @brief Sets how many pixels are displayed in the magnification. The less pixels the bigger the magnification. (default='64').  */
80
   char * magpixels_orig;	/**< @brief Sets how many pixels are displayed in the magnification. The less pixels the bigger the magnification. original value given at command line.  */
80
   char * magpixels_orig;	/**< @brief Sets how many pixels are displayed in the magnification. The less pixels the bigger the magnification. original value given at command line.  */
81
   const char *magpixels_help; /**< @brief Sets how many pixels are displayed in the magnification. The less pixels the bigger the magnification. help description.  */
81
   const char *magpixels_help; /**< @brief Sets how many pixels are displayed in the magnification. The less pixels the bigger the magnification. help description.  */
82
+  char * theme_arg;	/**< @brief Sets the theme of the selection, using textures from ~/.config/slop/ or /usr/share/. (default='none').  */
83
+  char * theme_orig;	/**< @brief Sets the theme of the selection, using textures from ~/.config/slop/ or /usr/share/. original value given at command line.  */
84
+  const char *theme_help; /**< @brief Sets the theme of the selection, using textures from ~/.config/slop/ or /usr/share/. help description.  */
85
+  char * shader_arg;	/**< @brief Sets the shader to load and use from ~/.config/slop/ or /usr/share/. (default='simple').  */
86
+  char * shader_orig;	/**< @brief Sets the shader to load and use from ~/.config/slop/ or /usr/share/. original value given at command line.  */
87
+  const char *shader_help; /**< @brief Sets the shader to load and use from ~/.config/slop/ or /usr/share/. help description.  */
82
   char * format_arg;	/**< @brief Set the output format string. Format specifiers are %x, %y, %w, %h, %i, %g, and %c. (default='REPLACEME').  */
88
   char * format_arg;	/**< @brief Set the output format string. Format specifiers are %x, %y, %w, %h, %i, %g, and %c. (default='REPLACEME').  */
83
   char * format_orig;	/**< @brief Set the output format string. Format specifiers are %x, %y, %w, %h, %i, %g, and %c. original value given at command line.  */
89
   char * format_orig;	/**< @brief Set the output format string. Format specifiers are %x, %y, %w, %h, %i, %g, and %c. original value given at command line.  */
84
   const char *format_help; /**< @brief Set the output format string. Format specifiers are %x, %y, %w, %h, %i, %g, and %c. help description.  */
90
   const char *format_help; /**< @brief Set the output format string. Format specifiers are %x, %y, %w, %h, %i, %g, and %c. help description.  */
100
   unsigned int magnify_given ;	/**< @brief Whether magnify was given.  */
106
   unsigned int magnify_given ;	/**< @brief Whether magnify was given.  */
101
   unsigned int magstrength_given ;	/**< @brief Whether magstrength was given.  */
107
   unsigned int magstrength_given ;	/**< @brief Whether magstrength was given.  */
102
   unsigned int magpixels_given ;	/**< @brief Whether magpixels was given.  */
108
   unsigned int magpixels_given ;	/**< @brief Whether magpixels was given.  */
109
+  unsigned int theme_given ;	/**< @brief Whether theme was given.  */
110
+  unsigned int shader_given ;	/**< @brief Whether shader was given.  */
103
   unsigned int format_given ;	/**< @brief Whether format was given.  */
111
   unsigned int format_given ;	/**< @brief Whether format was given.  */
104
 
112
 
105
 } ;
113
 } ;

+ 444
- 0
src/framebuffer.cpp View File

1
+#include "framebuffer.hpp"
2
+
3
+slop::Framebuffer::Framebuffer() {
4
+    m_shader = new slop::Shader( "simple", resource->getRealPath( "simple.vert" ), resource->getRealPath( "simple.frag" ) );
5
+    generatedBuffers = false;
6
+    m_width = 0;
7
+    m_height = 0;
8
+    m_flags = (slop::Framebuffer::buffers)0;
9
+    m_depth = 0;
10
+    m_stencil = 0;
11
+    m_frame = 0;
12
+    m_buffers[0] = 0;
13
+    m_buffers[1] = 0;
14
+    m_texture = 0;
15
+}
16
+
17
+void slop::Framebuffer::setShader( std::string shader ) {
18
+    delete m_shader;
19
+    m_shader = new slop::Shader( shader, resource->getRealPath( shader + ".vert" ), resource->getRealPath( shader + ".frag" ) );
20
+}
21
+
22
+slop::Framebuffer::Framebuffer( unsigned int width, unsigned int height, unsigned char flags, std::string shader ) {
23
+    m_shader = new slop::Shader( shader, resource->getRealPath( shader + ".vert" ), resource->getRealPath( shader + ".frag" ) );
24
+    generatedBuffers = false;
25
+    m_width = width;
26
+    m_height = height;
27
+    m_flags = flags;
28
+    if ( m_flags & stencil && m_flags & depth ) {
29
+        fprintf( stderr, "Most hardware doesn't support using a FBO with a depth and stencil attached! Condensing them to one render buffer..." );
30
+    }
31
+    if ( GLEW_VERSION_3_0 ) {
32
+        glGenFramebuffers( 1, &m_frame );
33
+        glBindFramebuffer( GL_FRAMEBUFFER, m_frame );
34
+        if ( m_flags & color ) {
35
+            glGenTextures( 1, &m_texture );
36
+            glBindTexture( GL_TEXTURE_2D, m_texture );
37
+            glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, m_width, m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0 );
38
+            glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
39
+            glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
40
+            glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_texture, 0 );
41
+        }
42
+
43
+        if ( m_flags & depth && !( m_flags & stencil ) ) {
44
+            glGenRenderbuffers( 1, &m_depth );
45
+            glBindRenderbuffer( GL_RENDERBUFFER, m_depth );
46
+            glRenderbufferStorage( GL_RENDERBUFFER, GL_DEPTH_COMPONENT, m_width, m_height );
47
+            glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_depth );
48
+        }
49
+
50
+        //This is the only way I could get a proper stencil buffer, by making a GL_DEPTH_STENCIL attachment to both points.
51
+        if ( m_flags & stencil ) {
52
+            glGenRenderbuffers( 1, &m_stencil );
53
+            glBindRenderbuffer( GL_RENDERBUFFER, m_stencil );
54
+            glRenderbufferStorage( GL_RENDERBUFFER, GL_DEPTH_STENCIL, m_width, m_height );
55
+            glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_stencil );
56
+            glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_stencil );
57
+        }
58
+        check();
59
+        //Make sure we unbind when we're done.
60
+        glBindFramebuffer( GL_FRAMEBUFFER, 0 );
61
+    } else if ( GLEW_EXT_framebuffer_object ) {
62
+        glGenFramebuffersEXT( 1, &m_frame );
63
+        glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, m_frame );
64
+
65
+        if ( m_flags & color ) {
66
+            glGenTextures( 1, &m_texture );
67
+            glBindTexture( GL_TEXTURE_2D, m_texture );
68
+            glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, m_width, m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0 );
69
+            glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
70
+            glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
71
+            glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, m_texture, 0 );
72
+        }
73
+
74
+        if ( m_flags & depth && !( m_flags & stencil ) ) {
75
+            glGenRenderbuffersEXT( 1, &m_depth );
76
+            glBindRenderbufferEXT( GL_RENDERBUFFER_EXT, m_depth );
77
+            glRenderbufferStorageEXT( GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, m_width, m_height );
78
+            glFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_depth );
79
+        }
80
+
81
+        //This is the only way I could get a proper stencil buffer, by making a GL_DEPTH_STENCIL attachment to both points.
82
+        if ( m_flags & stencil ) {
83
+            glGenRenderbuffersEXT( 1, &m_stencil );
84
+            glBindRenderbufferEXT( GL_RENDERBUFFER_EXT, m_stencil );
85
+            glRenderbufferStorageEXT( GL_RENDERBUFFER_EXT, GL_DEPTH_STENCIL_EXT, m_width, m_height );
86
+            glFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_stencil );
87
+            glFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_stencil );
88
+        }
89
+        check();
90
+        //Make sure we unbind when we're done.
91
+        glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 );
92
+    } else {
93
+        fprintf( stderr, "Error: Failed to create framebuffer! You need OpenGL 3.0 or the GL_EXT_framebuffer_object extension!\n" );
94
+    }
95
+}
96
+
97
+slop::Framebuffer::~Framebuffer() {
98
+    if ( GLEW_VERSION_3_0 ) {
99
+        glDeleteFramebuffers( 1, &m_frame );
100
+        if ( m_flags & color ) {
101
+            glDeleteTextures( 1, &m_texture );
102
+        }
103
+        if ( m_flags & depth && !( m_flags & stencil ) ) {
104
+            glDeleteRenderbuffers( 1, &m_depth );
105
+        }
106
+        if ( m_flags & stencil ) {
107
+            glDeleteRenderbuffers( 1, &m_stencil );
108
+        }
109
+    } else if ( GLEW_EXT_framebuffer_object ) {
110
+        glDeleteFramebuffersEXT( 1, &m_frame );
111
+        if ( m_flags & color ) {
112
+            glDeleteTextures( 1, &m_texture );
113
+        }
114
+        if ( m_flags & depth && !( m_flags & stencil ) ) {
115
+            glDeleteRenderbuffersEXT( 1, &m_depth );
116
+        }
117
+        if ( m_flags & stencil ) {
118
+            glDeleteRenderbuffersEXT( 1, &m_stencil );
119
+        }
120
+    }
121
+    if ( generatedBuffers ) {
122
+        glDeleteBuffers( 2, m_buffers );
123
+    }
124
+    delete m_shader;
125
+}
126
+
127
+void slop::Framebuffer::bind() {
128
+    if ( GLEW_VERSION_3_0 ) {
129
+        glBindFramebuffer( GL_FRAMEBUFFER, m_frame );
130
+    } else if ( GLEW_EXT_framebuffer_object ) {
131
+        glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, m_frame );
132
+    }
133
+}
134
+
135
+void slop::Framebuffer::unbind() {
136
+    if ( GLEW_VERSION_3_0 ) {
137
+        glBindFramebuffer( GL_FRAMEBUFFER, 0 );
138
+    } else if ( GLEW_EXT_framebuffer_object ) {
139
+        glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 );
140
+    }
141
+}
142
+
143
+void slop::Framebuffer::createFromTexture( unsigned int texture, std::string shader ) {
144
+    // First make sure we're empty.
145
+    if ( GLEW_VERSION_3_0 ) {
146
+        glDeleteFramebuffers( 1, &m_frame );
147
+        if ( m_flags & color ) {
148
+            glDeleteTextures( 1, &m_texture );
149
+        }
150
+        if ( m_flags & depth && !( m_flags & stencil ) ) {
151
+            glDeleteRenderbuffers( 1, &m_depth );
152
+        }
153
+        if ( m_flags & stencil ) {
154
+            glDeleteRenderbuffers( 1, &m_stencil );
155
+        }
156
+    } else if ( GLEW_EXT_framebuffer_object ) {
157
+        glDeleteFramebuffersEXT( 1, &m_frame );
158
+        if ( m_flags & color ) {
159
+            glDeleteTextures( 1, &m_texture );
160
+        }
161
+        if ( m_flags & depth && !( m_flags & stencil ) ) {
162
+            glDeleteRenderbuffersEXT( 1, &m_depth );
163
+        }
164
+        if ( m_flags & stencil ) {
165
+            glDeleteRenderbuffersEXT( 1, &m_stencil );
166
+        }
167
+    }
168
+    delete m_shader;
169
+    m_shader = new slop::Shader( shader, resource->getRealPath( shader + ".vert" ), resource->getRealPath( shader + ".frag" ) );
170
+    // Set flags to 0 so we don't delete the texture on deconstruction.
171
+    m_flags = 0;
172
+    m_texture = texture;
173
+    if ( GLEW_VERSION_3_0 ) {
174
+        glGenFramebuffers( 1, &m_frame );
175
+        glBindFramebuffer( GL_FRAMEBUFFER, m_frame );
176
+        glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_texture, 0 );
177
+    } else if ( GLEW_EXT_framebuffer_object ) {
178
+        glGenFramebuffersEXT( 1, &m_frame );
179
+        glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, m_frame );
180
+        glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, m_texture, 0 );
181
+    }
182
+    check();
183
+    glBindFramebuffer( GL_FRAMEBUFFER, 0 );
184
+}
185
+
186
+void slop::Framebuffer::create( unsigned int width, unsigned int height, unsigned char flags, std::string shader ) {
187
+    if ( m_width == width && m_height == height && m_flags == flags ) {
188
+        return;
189
+    }
190
+    delete m_shader;
191
+    m_shader = new slop::Shader( shader, resource->getRealPath( shader + ".vert" ), resource->getRealPath( shader + ".frag" ) );
192
+    if ( GLEW_VERSION_3_0 ) {
193
+        glDeleteFramebuffers( 1, &m_frame );
194
+        if ( m_flags & color ) {
195
+            glDeleteTextures( 1, &m_texture );
196
+        }
197
+        if ( m_flags & depth && !( m_flags & stencil ) ) {
198
+            glDeleteRenderbuffers( 1, &m_depth );
199
+        }
200
+        if ( m_flags & stencil ) {
201
+            glDeleteRenderbuffers( 1, &m_stencil );
202
+        }
203
+    } else if ( GLEW_EXT_framebuffer_object ) {
204
+        glDeleteFramebuffersEXT( 1, &m_frame );
205
+        if ( m_flags & color ) {
206
+            glDeleteTextures( 1, &m_texture );
207
+        }
208
+        if ( m_flags & depth && !( m_flags & stencil ) ) {
209
+            glDeleteRenderbuffersEXT( 1, &m_depth );
210
+        }
211
+        if ( m_flags & stencil ) {
212
+            glDeleteRenderbuffersEXT( 1, &m_stencil );
213
+        }
214
+    }
215
+    m_flags = flags;
216
+    m_width = width;
217
+    m_height = height;
218
+    if ( GLEW_VERSION_3_0 ) {
219
+        glGenFramebuffers( 1, &m_frame );
220
+        glBindFramebuffer( GL_FRAMEBUFFER, m_frame );
221
+
222
+        if ( m_flags & color ) {
223
+            glGenTextures( 1, &m_texture );
224
+            glBindTexture( GL_TEXTURE_2D, m_texture );
225
+            glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, m_width, m_height, 0, GL_RGB, GL_UNSIGNED_BYTE, 0 );
226
+            glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
227
+            glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
228
+            glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_texture, 0 );
229
+        }
230
+
231
+        if ( m_flags & depth && !( m_flags & stencil ) ) {
232
+            glGenRenderbuffers( 1, &m_depth );
233
+            glBindRenderbuffer( GL_RENDERBUFFER, m_depth );
234
+            glRenderbufferStorage( GL_RENDERBUFFER, GL_DEPTH_COMPONENT, m_width, m_height );
235
+            glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_depth );
236
+        }
237
+
238
+        //This is the only way I could get a proper stencil buffer, by making a GL_DEPTH_STENCIL attachment to both points.
239
+        if ( m_flags & stencil ) {
240
+            glGenRenderbuffers( 1, &m_stencil );
241
+            glBindRenderbuffer( GL_RENDERBUFFER, m_stencil );
242
+            glRenderbufferStorage( GL_RENDERBUFFER, GL_DEPTH_STENCIL, m_width, m_height );
243
+            glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_stencil );
244
+            glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_stencil );
245
+        }
246
+        //Make sure we unbind when we're done.
247
+        glBindFramebuffer( GL_FRAMEBUFFER, 0 );
248
+    } else if ( GLEW_EXT_framebuffer_object ) {
249
+        glGenFramebuffersEXT( 1, &m_frame );
250
+        glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, m_frame );
251
+
252
+        if ( m_flags & color ) {
253
+            glGenTextures( 1, &m_texture );
254
+            glBindTexture( GL_TEXTURE_2D, m_texture );
255
+            glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, m_width, m_height, 0, GL_RGB, GL_UNSIGNED_BYTE, 0 );
256
+           glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
257
+            glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
258
+            glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, m_texture, 0 );
259
+        }
260
+
261
+        if ( m_flags & depth && !( m_flags & stencil ) ) {
262
+            glGenRenderbuffersEXT( 1, &m_depth );
263
+            glBindRenderbufferEXT( GL_RENDERBUFFER_EXT, m_depth );
264
+            glRenderbufferStorageEXT( GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, m_width, m_height );
265
+            glFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_depth );
266
+        }
267
+
268
+        //This is the only way I could get a proper stencil buffer, by making a GL_DEPTH_STENCIL attachment to both points.
269
+        if ( m_flags & stencil ) {
270
+            glGenRenderbuffersEXT( 1, &m_stencil );
271
+            glBindRenderbufferEXT( GL_RENDERBUFFER_EXT, m_stencil );
272
+            glRenderbufferStorageEXT( GL_RENDERBUFFER_EXT, GL_DEPTH_STENCIL_EXT, m_width, m_height );
273
+            glFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_stencil );
274
+            glFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_stencil );
275
+        }
276
+        //Make sure we unbind when we're done.
277
+        glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 );
278
+    }
279
+}
280
+
281
+void slop::Framebuffer::check()
282
+{
283
+    if ( GLEW_VERSION_3_0 ) {
284
+        glBindFramebuffer( GL_FRAMEBUFFER, m_frame );
285
+        unsigned int err = glCheckFramebufferStatus( GL_FRAMEBUFFER );
286
+        if ( err == GL_FRAMEBUFFER_COMPLETE ) {
287
+            return;
288
+        }
289
+        fprintf( stderr, "Error: Framebuffer failed a check procedure for reason: " );
290
+        switch ( err ) {
291
+            case GL_FRAMEBUFFER_UNDEFINED: {
292
+                fprintf( stderr, "GL_FRAMEBUFFER_UNDEFINED\n" );
293
+                break;
294
+            }
295
+            case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: {
296
+                fprintf( stderr, "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT\n" );
297
+                break;
298
+            }
299
+            case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: {
300
+                fprintf( stderr, "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT\n" );
301
+                break;
302
+            }
303
+            case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER: {
304
+                fprintf( stderr, "GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER\n" );
305
+                break;
306
+            }
307
+            case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER: {
308
+                fprintf( stderr, "GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER\n" );
309
+                break;
310
+            }
311
+            case GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS: {
312
+                fprintf( stderr, "GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS\n" );
313
+                break;
314
+            }
315
+            case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE: {
316
+                fprintf( stderr, "GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE\n" );
317
+                break;
318
+            }
319
+            case GL_FRAMEBUFFER_UNSUPPORTED: {
320
+                fprintf( stderr, "GL_FRAMEBUFFER_UNSUPPORTED\n" );
321
+                break;
322
+            }
323
+            default: {
324
+                fprintf( stderr, "UNKNOWN\n" );
325
+                break;
326
+            }
327
+        }
328
+        glBindFramebuffer( GL_FRAMEBUFFER, 0 );
329
+    } else if ( GLEW_EXT_framebuffer_object ) {
330
+        glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, m_frame );
331
+        unsigned int err = glCheckFramebufferStatusEXT( GL_FRAMEBUFFER_EXT );
332
+        if ( err == GL_FRAMEBUFFER_COMPLETE_EXT ) {
333
+            return;
334
+        }
335
+        switch ( err ) {
336
+            /* Apparently doesn't exist as an extension.
337
+               case GL_FRAMEBUFFER_UNDEFINED_EXT: {
338
+                fprintf( stderr, "GL_FRAMEBUFFER_UNDEFINED_EXT\n" );
339
+                break;
340
+            }*/
341
+            case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT: {
342
+                fprintf( stderr, "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT\n" );
343
+                break;
344
+            }
345
+            case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT: {
346
+                fprintf( stderr, "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT\n" );
347
+                break;
348
+            }
349
+            case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT: {
350
+                fprintf( stderr, "GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT\n" );
351
+                break;
352
+            }
353
+            case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT: {
354
+                fprintf( stderr, "GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT\n" );
355
+                break;
356
+            }
357
+            case GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT: {
358
+                fprintf( stderr, "GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT\n" );
359
+                break;
360
+            }
361
+            case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT: {
362
+                fprintf( stderr, "GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT\n" );
363
+                break;
364
+            }
365
+            case GL_FRAMEBUFFER_UNSUPPORTED_EXT: {
366
+                fprintf( stderr, "GL_FRAMEBUFFER_UNSUPPORTED_EXT\n" );
367
+                break;
368
+            }
369
+            default: {
370
+                fprintf( stderr, "Unknown framebuffer error!\n" );
371
+                break;
372
+            }
373
+        }
374
+        glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 );
375
+    }
376
+}
377
+
378
+void slop::Framebuffer::generateBuffers() {
379
+    if ( generatedBuffers ) {
380
+        return;
381
+    }
382
+    std::vector<glm::vec2> verts;
383
+    std::vector<glm::vec2> uvs;
384
+    verts.push_back( glm::vec2( -1, -1 ) );
385
+    verts.push_back( glm::vec2( 1, -1 ) );
386
+    verts.push_back( glm::vec2( 1, 1 ) );
387
+    verts.push_back( glm::vec2( -1, 1 ) );
388
+    uvs.push_back( glm::vec2( 0, 0 ) );
389
+    uvs.push_back( glm::vec2( 1, 0 ) );
390
+    uvs.push_back( glm::vec2( 1, 1 ) );
391
+    uvs.push_back( glm::vec2( 0, 1 ) );
392
+
393
+    glGenBuffers( 2, m_buffers );
394
+    glBindBuffer( GL_ARRAY_BUFFER, m_buffers[0] );
395
+    glBufferData( GL_ARRAY_BUFFER, verts.size() * sizeof( glm::vec2 ), &verts[0], GL_STATIC_DRAW );
396
+    glBindBuffer( GL_ARRAY_BUFFER, m_buffers[1] );
397
+    glBufferData( GL_ARRAY_BUFFER, uvs.size() * sizeof( glm::vec2 ), &uvs[0], GL_STATIC_DRAW );
398
+    generatedBuffers = true;
399
+}
400
+
401
+void slop::Framebuffer::clear( glm::vec4 clearcolor, unsigned char flags ) {
402
+    // FIXME: This should auto-bind and unbind, but I was too lazy to find out how to push and pop gl states.
403
+    unsigned int colorbit = 0;
404
+    if ( flags & color ) {
405
+        colorbit = colorbit | GL_COLOR_BUFFER_BIT;
406
+    }
407
+    if ( m_flags & depth && flags & depth ) {
408
+        colorbit = colorbit | GL_DEPTH_BUFFER_BIT;
409
+    }
410
+    if ( m_flags & stencil && flags & stencil) {
411
+        colorbit = colorbit | GL_STENCIL_BUFFER_BIT;
412
+    }
413
+    glClearColor( clearcolor.x, clearcolor.y, clearcolor.z, clearcolor.w );
414
+    glClear( colorbit );
415
+}
416
+
417
+void slop::Framebuffer::draw( float time, unsigned int desktop ) {
418
+    if ( !( m_flags & color ) ) {
419
+        return;
420
+    }
421
+
422
+    generateBuffers();
423
+
424
+    //slop::Shader* shader = shaders->get( "simple" );
425
+    m_shader->bind();
426
+    m_shader->setParameter( "texture", 0 );
427
+    m_shader->setParameter( "desktop", 1 );
428
+    m_shader->setParameter( "time", time );
429
+    m_shader->setParameter( "desktopWidth", (int)xengine->getWidth() );
430
+    m_shader->setParameter( "desktopHeight", (int)xengine->getHeight() );
431
+    m_shader->setAttribute( "vertex", m_buffers[0], 2 );
432
+    m_shader->setAttribute( "uv", m_buffers[1], 2 );
433
+
434
+    glActiveTexture(GL_TEXTURE0 + 0);
435
+    glBindTexture( GL_TEXTURE_2D, m_texture );
436
+    glActiveTexture(GL_TEXTURE0 + 1);
437
+    glBindTexture( GL_TEXTURE_2D, desktop );
438
+    glActiveTexture(GL_TEXTURE0 + 0);
439
+    glEnable( GL_TEXTURE_2D );
440
+    glDrawArrays( GL_QUADS, 0, 4 );
441
+    glDisable( GL_TEXTURE_2D );
442
+
443
+    m_shader->unbind();
444
+}

+ 50
- 0
src/framebuffer.hpp View File

1
+#ifndef IS_FRAMEBUFFER_H_
2
+#define IS_FRAMEBUFFER_H_
3
+
4
+#include <GL/glew.h>
5
+#include <GL/gl.h>
6
+#include <glm/glm.hpp>
7
+
8
+#include "x.hpp"
9
+#include "shader.hpp"
10
+#include "resource.hpp"
11
+
12
+namespace slop {
13
+
14
+class Framebuffer
15
+{
16
+public:
17
+    enum buffers
18
+    {
19
+        color = 0x01,
20
+        depth = 0x02,
21
+        stencil = 0x04
22
+    };
23
+    Framebuffer();
24
+    Framebuffer( unsigned int width, unsigned int height, unsigned char flags = color, std::string shader = "simple" );
25
+    ~Framebuffer();
26
+    void create( unsigned int width, unsigned int height, unsigned char flags = color, std::string shader = "simple" );
27
+    void createFromTexture( unsigned int texture, std::string shader = "simple" );
28
+    void setShader( std::string shader = "simple" );
29
+    void clear( glm::vec4 color = glm::vec4( 0, 0, 0, 1 ), unsigned char flags = color | depth | stencil );
30
+    void bind();
31
+    void unbind();
32
+    void draw( float time, unsigned int image );
33
+    unsigned int m_texture;
34
+    unsigned int m_depth;
35
+    unsigned int m_stencil;
36
+    slop::Shader* m_shader;
37
+private:
38
+    unsigned int m_width;
39
+    unsigned int m_height;
40
+    void check();
41
+    void generateBuffers();
42
+    unsigned char m_flags;
43
+    bool generatedBuffers;
44
+    unsigned int m_frame;
45
+    unsigned int m_buffers[2];
46
+};
47
+
48
+}
49
+
50
+#endif //IS_FRAMEBUFFER_H_

+ 38
- 0
src/glselectrectangle.cpp View File

27
     if ( m_window == None ) {
27
     if ( m_window == None ) {
28
         return;
28
         return;
29
     }
29
     }
30
+    delete m_framebuffer;
30
     // Try to erase the window before destroying it.
31
     // Try to erase the window before destroying it.
31
     glClearColor( 0, 0, 0, 0 );
32
     glClearColor( 0, 0, 0, 0 );
32
     glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
33
     glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
78
     m_offseth *= m_glassSize;
79
     m_offseth *= m_glassSize;
79
 }
80
 }
80
 
81
 
82
+void slop::GLSelectRectangle::setShader( std::string shader ) {
83
+    m_shader = shader;
84
+    m_framebuffer->setShader( shader );
85
+}
86
+
81
 void slop::GLSelectRectangle::setMagnifySettings( bool on, float magstrength, unsigned int pixels ) {
87
 void slop::GLSelectRectangle::setMagnifySettings( bool on, float magstrength, unsigned int pixels ) {
82
     m_glassSize = magstrength;
88
     m_glassSize = magstrength;
83
     m_glassPixels = pixels;
89
     m_glassPixels = pixels;
286
     m_glassBorder = 1;
292
     m_glassBorder = 1;
287
     m_monitors = xengine->getCRTCS();
293
     m_monitors = xengine->getCRTCS();
288
     m_themed = false;
294
     m_themed = false;
295
+    m_shader = "simple";
296
+    m_time = 0;
289
 
297
 
290
     // If we don't have a border, we don't exist, so just die.
298
     // If we don't have a border, we don't exist, so just die.
291
     if ( m_border == 0 ) {
299
     if ( m_border == 0 ) {
396
     if ( !glXMakeContextCurrent( xengine->m_display, m_glxWindow, m_glxWindow, m_renderContext ) ) {
404
     if ( !glXMakeContextCurrent( xengine->m_display, m_glxWindow, m_glxWindow, m_renderContext ) ) {
397
         fprintf( stderr, "Failed to attach GL context to window!\n" );
405
         fprintf( stderr, "Failed to attach GL context to window!\n" );
398
     }
406
     }
407
+    GLenum err = glewInit();
408
+    if ( GLEW_OK != err ) {
409
+        /* Problem: glewInit failed, something is seriously wrong. */
410
+        fprintf(stderr, "Error: %s\n", glewGetErrorString(err));
411
+    }
412
+
413
+    // Get an image of the entire desktop for use in shaders.
414
+    XImage* image = XGetImage( xengine->m_display, xengine->m_root, 0, 0, xengine->getWidth(), xengine->getHeight(), 0xffffffff, ZPixmap );
415
+    glEnable(GL_TEXTURE_2D);
416
+    glGenTextures(1, &m_desktop);
417
+    glBindTexture(GL_TEXTURE_2D, m_desktop);
418
+    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
419
+    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
420
+    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
421
+    glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, xengine->getWidth(), xengine->getHeight(), 0, GL_BGRA, GL_UNSIGNED_BYTE, (void*)(&(image->data[0])));
422
+    XDestroyImage( image );
423
+
424
+    glDisable(GL_TEXTURE_2D);
425
+    m_framebuffer = new slop::Framebuffer( xengine->getWidth(), xengine->getHeight(), slop::Framebuffer::color, m_shader );
426
+    m_framebuffer->bind();
399
     glEnable( GL_BLEND );
427
     glEnable( GL_BLEND );
400
     glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
428
     glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
401
     glClearColor( 0, 0, 0, 0 );
429
     glClearColor( 0, 0, 0, 0 );
402
     glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
430
     glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
403
     glXSwapBuffers( xengine->m_display, m_glxWindow );
431
     glXSwapBuffers( xengine->m_display, m_glxWindow );
432
+    m_framebuffer->unbind();
404
 }
433
 }
405
 
434
 
406
 void slop::GLSelectRectangle::setGeo( int sx, int sy, int ex, int ey ) {
435
 void slop::GLSelectRectangle::setGeo( int sx, int sy, int ex, int ey ) {
416
 }
445
 }
417
 
446
 
418
 void slop::GLSelectRectangle::update( double dt ) {
447
 void slop::GLSelectRectangle::update( double dt ) {
448
+    m_time += dt;
449
+    m_framebuffer->bind();
419
     glViewport( 0, 0, xengine->getWidth(), xengine->getHeight() );
450
     glViewport( 0, 0, xengine->getWidth(), xengine->getHeight() );
420
 
451
 
421
     glClearColor( 0, 0, 0, 0 );
452
     glClearColor( 0, 0, 0, 0 );
498
         glEnd();
529
         glEnd();
499
     }
530
     }
500
 
531
 
532
+    m_framebuffer->unbind();
533
+
534
+    glClearColor( 0, 0, 0, 0 );
535
+    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
536
+
537
+    m_framebuffer->draw( (float) m_time, m_desktop );
538
+
501
     if ( m_glassEnabled ) {
539
     if ( m_glassEnabled ) {
502
         generateMagnifyingGlass();
540
         generateMagnifyingGlass();
503
         findOptimalGlassPosition();
541
         findOptimalGlassPosition();

+ 7
- 0
src/glselectrectangle.hpp View File

24
 #include "x.hpp"
24
 #include "x.hpp"
25
 #include "selectrectangle.hpp"
25
 #include "selectrectangle.hpp"
26
 #include "resource.hpp"
26
 #include "resource.hpp"
27
+#include "framebuffer.hpp"
27
 
28
 
28
 #include <unistd.h>
29
 #include <unistd.h>
29
 
30
 
30
 #include <GL/gl.h>
31
 #include <GL/gl.h>
31
 #include <GL/glx.h>
32
 #include <GL/glx.h>
33
+#include <GL/glew.h>
32
 #include <GL/glxext.h>
34
 #include <GL/glxext.h>
33
 #define ILUT_USE_OPENGL
35
 #define ILUT_USE_OPENGL
34
 #include <IL/il.h>
36
 #include <IL/il.h>
59
     void                findOptimalGlassPosition();
61
     void                findOptimalGlassPosition();
60
     void                constrainWithinMonitor( int* x, int* y, int* w, int* h );
62
     void                constrainWithinMonitor( int* x, int* y, int* w, int* h );
61
     void                setTheme( bool on, std::string name );
63
     void                setTheme( bool on, std::string name );
64
+    void                setShader( std::string name );
62
     float               m_r;
65
     float               m_r;
63
     float               m_g;
66
     float               m_g;
64
     float               m_b;
67
     float               m_b;
79
     int                 m_offsety;
82
     int                 m_offsety;
80
     int                 m_offsetw;
83
     int                 m_offsetw;
81
     int                 m_offseth;
84
     int                 m_offseth;
85
+    unsigned int        m_desktop;
82
     unsigned int        m_glassPixels;
86
     unsigned int        m_glassPixels;
83
     float               m_glassSize;
87
     float               m_glassSize;
84
     int                 m_glassBorder;
88
     int                 m_glassBorder;
87
     int                 m_glassx;
91
     int                 m_glassx;
88
     int                 m_glassy;
92
     int                 m_glassy;
89
     bool                m_glassEnabled;
93
     bool                m_glassEnabled;
94
+    double              m_time;
95
+    std::string         m_shader;
90
     std::vector<XRRCrtcInfo*> m_monitors;
96
     std::vector<XRRCrtcInfo*> m_monitors;
97
+    slop::Framebuffer*  m_framebuffer;
91
 };
98
 };
92
 
99
 
93
 }
100
 }

+ 11
- 5
src/main.cpp View File

21
 #include <time.h>
21
 #include <time.h>
22
 #include <cstdio>
22
 #include <cstdio>
23
 #include <sstream>
23
 #include <sstream>
24
+#include <execinfo.h>
24
 
25
 
25
 #ifdef __MACH__
26
 #ifdef __MACH__
26
 #include <mach/clock.h>
27
 #include <mach/clock.h>
248
     bool highlight = options.highlight_flag;
249
     bool highlight = options.highlight_flag;
249
     bool keyboard = !options.nokeyboard_flag;
250
     bool keyboard = !options.nokeyboard_flag;
250
     bool decorations = !options.nodecorations_flag;
251
     bool decorations = !options.nodecorations_flag;
252
+    bool themeon = (bool)options.theme_given;
253
+    std::string theme = options.theme_arg;
254
+    std::string shader = options.shader_arg;
251
     struct timespec start, time;
255
     struct timespec start, time;
252
     int xoffset = 0;
256
     int xoffset = 0;
253
     int yoffset = 0;
257
     int yoffset = 0;
369
                                                                      r, g, b, a );
373
                                                                      r, g, b, a );
370
                             // Haha why is this so hard to cast?
374
                             // Haha why is this so hard to cast?
371
                             ((slop::GLSelectRectangle*)(selection))->setMagnifySettings( magenabled, magstrength, magpixels );
375
                             ((slop::GLSelectRectangle*)(selection))->setMagnifySettings( magenabled, magstrength, magpixels );
372
-                            ((slop::GLSelectRectangle*)(selection))->setTheme( true, "gothic" );
376
+                            ((slop::GLSelectRectangle*)(selection))->setTheme( themeon, theme );
377
+                            ((slop::GLSelectRectangle*)(selection))->setShader( shader );
373
                         } else {
378
                         } else {
374
                             selection = new slop::XSelectRectangle( t.m_x, t.m_y,
379
                             selection = new slop::XSelectRectangle( t.m_x, t.m_y,
375
                                                                     t.m_x + t.m_width,
380
                                                                     t.m_x + t.m_width,
427
                                                                  r, g, b, a );
432
                                                                  r, g, b, a );
428
                         // Haha why is this so hard to cast?
433
                         // Haha why is this so hard to cast?
429
                         ((slop::GLSelectRectangle*)(selection))->setMagnifySettings( magenabled, magstrength, magpixels );
434
                         ((slop::GLSelectRectangle*)(selection))->setMagnifySettings( magenabled, magstrength, magpixels );
430
-                        ((slop::GLSelectRectangle*)(selection))->setTheme( true, "gothic" );
435
+                        ((slop::GLSelectRectangle*)(selection))->setTheme( themeon, theme );
436
+                        ((slop::GLSelectRectangle*)(selection))->setShader( shader );
431
                     } else {
437
                     } else {
432
                         selection = new slop::XSelectRectangle( sx, sy,
438
                         selection = new slop::XSelectRectangle( sx, sy,
433
                                                                 ex, ey,
439
                                                                 ex, ey,
527
         return app( argc, argv );
533
         return app( argc, argv );
528
     } catch( std::bad_alloc const& exception ) {
534
     } catch( std::bad_alloc const& exception ) {
529
         fprintf( stderr, "Couldn't allocate enough memory! No space left in RAM." );
535
         fprintf( stderr, "Couldn't allocate enough memory! No space left in RAM." );
530
-        return EXIT_FAILURE;
531
     } catch( std::exception const& exception ) {
536
     } catch( std::exception const& exception ) {
532
         fprintf( stderr, "Unhandled Exception Thrown: %s\n", exception.what() );
537
         fprintf( stderr, "Unhandled Exception Thrown: %s\n", exception.what() );
533
-        return EXIT_FAILURE;
538
+    } catch( std::string err ) {
539
+        fprintf( stderr, "Unhandled Exception Thrown: %s\n", err.c_str() );
534
     } catch( ... ) {
540
     } catch( ... ) {
535
         fprintf( stderr, "Unknown Exception Thrown!\n" );
541
         fprintf( stderr, "Unknown Exception Thrown!\n" );
536
-        return EXIT_FAILURE;
537
     }
542
     }
543
+    return EXIT_FAILURE;
538
 }
544
 }

+ 16
- 0
src/options.ggo View File

78
     default="64"
78
     default="64"
79
     optional
79
     optional
80
 
80
 
81
+option "theme" - "Sets the theme of the selection, using textures from ~/.config/slop/ or /usr/share/."
82
+    string
83
+    default="none"
84
+    optional
85
+
86
+option "shader" - "Sets the shader to load and use from ~/.config/slop/ or /usr/share/."
87
+    string
88
+    default="simple"
89
+    optional
90
+
81
 option "format" f "Set the output format string. Format specifiers are %x, %y, %w, %h, %i, %g, and %c."
91
 option "format" f "Set the output format string. Format specifiers are %x, %y, %w, %h, %i, %g, and %c."
82
     string
92
     string
83
     default="REPLACEME"
93
     default="REPLACEME"
96
 text "    $ # Classic Windows XP selection.\n"
106
 text "    $ # Classic Windows XP selection.\n"
97
 text "    $ slop -l -c 0.3,0.4,0.6,0.4\n"
107
 text "    $ slop -l -c 0.3,0.4,0.6,0.4\n"
98
 text "\n"
108
 text "\n"
109
+text "    $ # Wiggle wiggle!\n"
110
+text "    $ slop --opengl --shader wiggle\n"
111
+text "\n"
112
+text "    $ # Edgy textures or something.\n"
113
+text "    $ slop --opengl --theme gothic\n"
114
+text "\n"
99
 text "    $ # Change output format to use safer parsing\n"
115
 text "    $ # Change output format to use safer parsing\n"
100
 text "    $ slopoutput=$(slop -f \"%x %y %w %h\")\n"
116
 text "    $ slopoutput=$(slop -f \"%x %y %w %h\")\n"
101
 text "    $ X=$(echo $slopoutput | awk '{print $1}')\n"
117
 text "    $ X=$(echo $slopoutput | awk '{print $1}')\n"

+ 10
- 6
src/resource.cpp View File

30
         char* home = getpwuid(getuid())->pw_dir;
30
         char* home = getpwuid(getuid())->pw_dir;
31
         m_usrconfig += home;
31
         m_usrconfig += home;
32
         m_usrconfig += "/.config/slop/";
32
         m_usrconfig += "/.config/slop/";
33
+        m_sysconfig = INSTALL_PREFIX;
34
+        m_sysconfig += "/share/slop/";
33
         return;
35
         return;
34
     }
36
     }
35
     m_usrconfig += config;
37
     m_usrconfig += config;
36
     m_usrconfig += "/slop/";
38
     m_usrconfig += "/slop/";
37
     m_sysconfig = INSTALL_PREFIX;
39
     m_sysconfig = INSTALL_PREFIX;
38
-    m_sysconfig += "/share/slop";
40
+    m_sysconfig += "/share/slop/";
39
 }
41
 }
40
 
42
 
41
 std::string slop::Resource::getRealPath( std::string localpath ) {
43
 std::string slop::Resource::getRealPath( std::string localpath ) {
42
-    if ( !validatePath( m_usrconfig + localpath ) ) {
43
-        if ( !validatePath( m_sysconfig + localpath ) ) {
44
-            fprintf( stderr, "Failed to find directory %s in %s or %s...\n", localpath.c_str(), m_usrconfig.c_str(), m_sysconfig.c_str() );
45
-        }
44
+    if ( validatePath( m_usrconfig + localpath ) ) {
45
+        return m_usrconfig + localpath;
46
+    }
47
+    if ( validatePath( m_sysconfig + localpath ) ) {
46
         return m_sysconfig + localpath;
48
         return m_sysconfig + localpath;
47
     }
49
     }
48
-    return m_usrconfig + localpath;
50
+    std::string err = "The file or folder " + localpath + " was not found in either " + m_sysconfig + " or " + m_usrconfig + "\n";
51
+    throw err;
52
+    return localpath;
49
 }
53
 }
50
 
54
 
51
 bool slop::Resource::validatePath( std::string path ) {
55
 bool slop::Resource::validatePath( std::string path ) {

+ 1
- 0
src/resource.hpp View File

22
 #define IS_RESOURCE_H_
22
 #define IS_RESOURCE_H_
23
 
23
 
24
 #include <stdlib.h>
24
 #include <stdlib.h>
25
+#include <cassert>
25
 #include <cstdio>
26
 #include <cstdio>
26
 #include <string>
27
 #include <string>
27
 #include <unistd.h>
28
 #include <unistd.h>

+ 1
- 0
src/selectrectangle.hpp View File

23
 
23
 
24
 #include "x.hpp"
24
 #include "x.hpp"
25
 #include "selectrectangle.hpp"
25
 #include "selectrectangle.hpp"
26
+#include "shader.hpp"
26
 
27
 
27
 #include <unistd.h>
28
 #include <unistd.h>
28
 
29
 

+ 172
- 0
src/shader.cpp View File

1
+#include "shader.hpp"
2
+
3
+slop::Shader::Shader( std::string name, std::string vert, std::string frag, std::string type ) {
4
+    m_name = name;
5
+    // Set up the type of the shader, this is read by render to know what kind of matricies it needs.
6
+    if ( type == "perspective" ) {
7
+        m_type = 0;
8
+    } else if ( type == "orthographic" ) {
9
+        m_type = 1;
10
+    } else {
11
+        m_type = -1;
12
+    }
13
+    m_good = false;
14
+    // Create the program to link to.
15
+    m_program = glCreateProgram();
16
+
17
+    std::ifstream v( vert.c_str() );
18
+    std::string vert_contents((std::istreambuf_iterator<char>(v)),
19
+                               std::istreambuf_iterator<char>());
20
+    std::ifstream f( frag.c_str() );
21
+    std::string frag_contents((std::istreambuf_iterator<char>(f)),
22
+                              std::istreambuf_iterator<char>());
23
+
24
+    const char* vertsrc = vert_contents.c_str();
25
+    const char* fragsrc = frag_contents.c_str();
26
+
27
+    // Compile both shaders.
28
+    unsigned int vertShader = glCreateShader( GL_VERTEX_SHADER );
29
+    glShaderSource( vertShader, 1, &vertsrc , NULL );
30
+    int err = compile( vertShader );
31
+
32
+    if ( err ) {
33
+        fprintf( stderr, "Failed to compile shader %s.\n", vert.c_str() );
34
+        glDeleteShader( vertShader );
35
+        return;
36
+    }
37
+
38
+    unsigned int fragShader = glCreateShader( GL_FRAGMENT_SHADER );
39
+    glShaderSource( fragShader, 1, &fragsrc, NULL );
40
+    err = compile( fragShader );
41
+    if ( err ) {
42
+        fprintf( stderr, "Failed to compile shader %s.\n", frag.c_str() );
43
+        glDeleteShader( vertShader );
44
+        glDeleteShader( fragShader );
45
+        return;
46
+    }
47
+
48
+
49
+    // Then attempt to link them to this shader.
50
+    err = link( vertShader, fragShader );
51
+    if ( err ) {
52
+        fprintf( stderr, "Failed to link shader %s.\n", name.c_str() );
53
+        glDeleteShader( vertShader );
54
+        glDeleteShader( fragShader );
55
+        return;
56
+    }
57
+
58
+    // Clean up :)
59
+    glDeleteShader( vertShader );
60
+    glDeleteShader( fragShader );
61
+    m_good = true;
62
+    glUseProgram( 0 );
63
+}
64
+
65
+slop::Shader::~Shader() {
66
+    glDeleteProgram( m_program );
67
+}
68
+
69
+unsigned int slop::Shader::getProgram() {
70
+    return m_program;
71
+}
72
+
73
+void slop::Shader::bind() {
74
+    glUseProgram( m_program );
75
+}
76
+
77
+int slop::Shader::compile( unsigned int shader ) {
78
+    glCompileShader( shader );
79
+
80
+    // Compiling the shader is the easy part, all this junk down here is for printing the error it might generate.
81
+    int result;
82
+    int logLength;
83
+    glGetShaderiv( shader, GL_COMPILE_STATUS, &result );
84
+    glGetShaderiv( shader, GL_INFO_LOG_LENGTH, &logLength );
85
+    if ( result == GL_FALSE ) {
86
+        char* errormsg = new char[ logLength ];
87
+        glGetShaderInfoLog( shader, logLength, NULL, errormsg );
88
+        fprintf( stderr, "%s\n", errormsg );
89
+        delete[] errormsg;
90
+        return 1;
91
+    }
92
+    return 0;
93
+}
94
+
95
+int slop::Shader::link( unsigned int vertshader, unsigned int fragshader ) {
96
+    glAttachShader( m_program, vertshader );
97
+    glAttachShader( m_program, fragshader );
98
+    glLinkProgram( m_program );
99
+
100
+    // Linking the shader is the easy part, all this junk down here is for printing the error it might generate.
101
+    int result;
102
+    int logLength;
103
+    glGetProgramiv( m_program, GL_LINK_STATUS, &result);
104
+    glGetProgramiv( m_program, GL_INFO_LOG_LENGTH, &logLength);
105
+    if ( result == GL_FALSE ) {
106
+        char* errormsg = new char[ logLength ];
107
+        glGetProgramInfoLog( m_program, logLength, NULL, errormsg );
108
+        fprintf( stderr, "%s\n", errormsg );
109
+        delete[] errormsg;
110
+        return 1;
111
+    }
112
+    return 0;
113
+}
114
+
115
+unsigned int slop::Shader::getUniformLocation( std::string name ) {
116
+    if ( !m_good ) {
117
+        return 0;
118
+    }
119
+    glUseProgram( m_program );
120
+    return glGetUniformLocation( m_program, name.c_str() );
121
+}
122
+
123
+void slop::Shader::setParameter( std::string name, int foo ) {
124
+    if ( !m_good ) {
125
+        return;
126
+    }
127
+    glUniform1i( getUniformLocation( name ), foo );
128
+}
129
+
130
+void slop::Shader::setParameter( std::string name, float foo ) {
131
+    if ( !m_good ) {
132
+        return;
133
+    }
134
+    glUniform1f( getUniformLocation( name ), foo );
135
+}
136
+
137
+void slop::Shader::setParameter( std::string name, glm::mat4 foo ) {
138
+    if ( !m_good ) {
139
+        return;
140
+    }
141
+    glUniformMatrix4fv( getUniformLocation( name ), 1, GL_FALSE, glm::value_ptr( foo ) );
142
+}
143
+
144
+void slop::Shader::setParameter( std::string name, glm::vec4 foo ) {
145
+    if ( !m_good ) {
146
+        return;
147
+    }
148
+    glUniform4f( getUniformLocation( name ), foo.x, foo.y, foo.z, foo.w );
149
+}
150
+
151
+void slop::Shader::setParameter( std::string name, glm::vec2 foo ) {
152
+    if ( !m_good ) {
153
+        return;
154
+    }
155
+    glUniform2f( getUniformLocation( name ), foo.x, foo.y );
156
+}
157
+
158
+void slop::Shader::setAttribute( std::string name, unsigned int buffer, unsigned int stepsize ) {
159
+    unsigned int a = glGetAttribLocation( m_program, name.c_str() );
160
+    glEnableVertexAttribArray( a );
161
+    glBindBuffer( GL_ARRAY_BUFFER, buffer );
162
+    glVertexAttribPointer( a, stepsize, GL_FLOAT, GL_FALSE, 0, NULL );
163
+    m_activeattribs.push_back( a );
164
+}
165
+
166
+void slop::Shader::unbind() {
167
+    for ( unsigned int i=0; i<m_activeattribs.size(); i++ ) {
168
+        glDisableVertexAttribArray( m_activeattribs[i] );
169
+    }
170
+    m_activeattribs.clear();
171
+    glUseProgram( 0 );
172
+}

+ 44
- 0
src/shader.hpp View File

1
+// shader.hpp: Loads shaders into opengl
2
+
3
+#ifndef IS_SHADER_H_
4
+#define IS_SHADER_H_
5
+
6
+#include <string>
7
+#include <cstdio>
8
+#include <vector>
9
+#include <glm/glm.hpp>
10
+#include <glm/gtc/type_ptr.hpp>
11
+#include <GL/glew.h>
12
+#include <string>
13
+#include <fstream>
14
+#include <streambuf>
15
+
16
+namespace slop {
17
+
18
+class Shader {
19
+public:
20
+    Shader( std::string name, std::string vert, std::string frag, std::string shadertype = "other" );
21
+    ~Shader();
22
+    unsigned int    getProgram();
23
+    std::string     m_name;
24
+    void            bind();
25
+    void            unbind();
26
+    void            setParameter( std::string name, int foo );
27
+    void            setParameter( std::string name, float foo );
28
+    void            setParameter( std::string name, glm::mat4 foo );
29
+    void            setParameter( std::string name, glm::vec4 foo );
30
+    void            setParameter( std::string name, glm::vec2 foo );
31
+    void            setAttribute( std::string name, unsigned int buffer, unsigned int stepsize );
32
+    int             m_type;
33
+private:
34
+    std::vector<unsigned int>   m_activeattribs;
35
+    bool                        m_good;
36
+    unsigned int                getUniformLocation( std::string );
37
+    int                         compile( unsigned int shader );
38
+    int                         link( unsigned int vert, unsigned int frag );
39
+    unsigned int                m_program;
40
+};
41
+
42
+};
43
+
44
+#endif // IS_SHADER_H_