|
@@ -41,7 +41,7 @@ slop::SlopOptions::SlopOptions() {
|
41
|
41
|
nodecorations = false;
|
42
|
42
|
tolerance = 2;
|
43
|
43
|
padding = 0;
|
44
|
|
- shader = "textured";
|
|
44
|
+ shaders.push_back("textured");
|
45
|
45
|
highlight = false;
|
46
|
46
|
r = 0.5;
|
47
|
47
|
g = 0.5;
|
|
@@ -167,14 +167,28 @@ slop::SlopSelection slop::XShapeSlopSelect( slop::SlopOptions* options, bool* ca
|
167
|
167
|
slop::SlopSelection slop::GLSlopSelect( slop::SlopOptions* options, bool* cancelled, SlopWindow* window ) {
|
168
|
168
|
slop::mouse = new slop::Mouse( x11, options->nodecorations, window->window );
|
169
|
169
|
|
170
|
|
- if ( options->shader != "textured" ) {
|
171
|
|
- window->framebuffer->setShader( options->shader );
|
|
170
|
+ std::string vert = "#version 130\nattribute vec2 position;\nattribute vec2 uv;\nvarying vec2 uvCoord;\nvoid main()\n{\nuvCoord = uv;\ngl_Position = vec4(position,0,1);\n}\n";
|
|
171
|
+ std::string frag = "#version 130\n uniform sampler2D texture;\n varying vec2 uvCoord;\n out vec4 outColor;\n void main()\n {\n outColor = texture2D( texture, uvCoord );\n }\n";
|
|
172
|
+ slop::Shader* textured = new slop::Shader( vert, frag, false );
|
|
173
|
+ std::vector<slop::Shader*> shaders;
|
|
174
|
+ for( int i=0;i<options->shaders.size();i++ ) {
|
|
175
|
+ std::string sn = options->shaders[i];
|
|
176
|
+ if ( sn != "textured" ) {
|
|
177
|
+ shaders.push_back( new slop::Shader( sn + ".vert", sn + ".frag" ) );
|
|
178
|
+ } else {
|
|
179
|
+ shaders.push_back( textured );
|
|
180
|
+ }
|
172
|
181
|
}
|
173
|
|
-
|
174
|
182
|
// Init our little state machine, memory is a tad of a misnomer
|
175
|
183
|
slop::SlopMemory memory( options, new GLRectangle(glm::vec2(0,0), glm::vec2(0,0), options->borderSize, options->padding, glm::vec4( options->r, options->g, options->b, options->a ), options->highlight) );
|
176
|
184
|
|
|
185
|
+ slop::Framebuffer* pingpong;
|
|
186
|
+ if ( shaders.size() > 1 ) {
|
|
187
|
+ pingpong = new slop::Framebuffer(WidthOfScreen(x11->screen), HeightOfScreen(x11->screen));
|
|
188
|
+ }
|
|
189
|
+
|
177
|
190
|
// This is where we'll run through all of our stuffs
|
|
191
|
+ auto start = std::chrono::high_resolution_clock::now();
|
178
|
192
|
while( memory.running ) {
|
179
|
193
|
slop::mouse->update();
|
180
|
194
|
if ( !options->nokeyboard ) {
|
|
@@ -184,18 +198,63 @@ slop::SlopSelection slop::GLSlopSelect( slop::SlopOptions* options, bool* cancel
|
184
|
198
|
memory.update( 1 );
|
185
|
199
|
|
186
|
200
|
// Then we draw our junk to a framebuffer.
|
|
201
|
+ window->framebuffer->setShader( textured );
|
187
|
202
|
window->framebuffer->bind();
|
188
|
203
|
glClearColor (0.0, 0.0, 0.0, 0.0);
|
189
|
204
|
glClear (GL_COLOR_BUFFER_BIT);
|
190
|
205
|
memory.draw( window->camera );
|
191
|
206
|
window->framebuffer->unbind();
|
192
|
207
|
|
193
|
|
- // Then we draw the framebuffer to the screen
|
194
|
|
- window->framebuffer->draw();
|
|
208
|
+ auto end = std::chrono::high_resolution_clock::now();
|
|
209
|
+ std::chrono::duration<double, std::milli> elapsed = end-start;
|
|
210
|
+ if ( shaders.size() > 1 ) {
|
|
211
|
+ int i;
|
|
212
|
+ // We have our clean buffer, now to slather it with some juicy shader chains.
|
|
213
|
+ for (i=0;i<=(int)shaders.size()-2;i+=2) {
|
|
214
|
+ pingpong->bind();
|
|
215
|
+ glClearColor (0.0, 0.0, 0.0, 0.0);
|
|
216
|
+ glClear (GL_COLOR_BUFFER_BIT);
|
|
217
|
+ window->framebuffer->setShader( shaders[i] );
|
|
218
|
+ window->framebuffer->draw(slop::mouse->getMousePos(), elapsed.count()/1000.f, glm::vec4( options->r, options->g, options->b, options->a ) );
|
|
219
|
+ pingpong->unbind();
|
|
220
|
+
|
|
221
|
+ window->framebuffer->bind();
|
|
222
|
+ glClearColor (0.0, 0.0, 0.0, 0.0);
|
|
223
|
+ glClear (GL_COLOR_BUFFER_BIT);
|
|
224
|
+ pingpong->setShader( shaders[i+1] );
|
|
225
|
+ pingpong->draw(slop::mouse->getMousePos(), elapsed.count()/1000.f, glm::vec4( options->r, options->g, options->b, options->a ) );
|
|
226
|
+ window->framebuffer->unbind();
|
|
227
|
+ }
|
|
228
|
+ for (;i<shaders.size();i++) {
|
|
229
|
+ pingpong->bind();
|
|
230
|
+ glClearColor (0.0, 0.0, 0.0, 0.0);
|
|
231
|
+ glClear (GL_COLOR_BUFFER_BIT);
|
|
232
|
+ window->framebuffer->setShader( shaders[i] );
|
|
233
|
+ window->framebuffer->draw(slop::mouse->getMousePos(), elapsed.count()/1000.f, glm::vec4( options->r, options->g, options->b, options->a ) );
|
|
234
|
+ pingpong->unbind();
|
|
235
|
+ }
|
|
236
|
+ if ( i%2 != 0 ) {
|
|
237
|
+ window->framebuffer->draw(slop::mouse->getMousePos(), elapsed.count()/1000.f, glm::vec4( options->r, options->g, options->b, options->a ) );
|
|
238
|
+ } else {
|
|
239
|
+ pingpong->draw(slop::mouse->getMousePos(), elapsed.count()/1000.f, glm::vec4( options->r, options->g, options->b, options->a ) );
|
|
240
|
+ }
|
|
241
|
+ } else {
|
|
242
|
+ window->framebuffer->setShader( shaders[0] );
|
|
243
|
+ window->framebuffer->draw(slop::mouse->getMousePos(), elapsed.count()/1000.f, glm::vec4( options->r, options->g, options->b, options->a ) );
|
|
244
|
+ }
|
|
245
|
+
|
195
|
246
|
window->display();
|
196
|
247
|
GLenum err = glGetError();
|
197
|
248
|
if ( err != GL_NO_ERROR ) {
|
198
|
|
- throw err;
|
|
249
|
+ std::string error;
|
|
250
|
+ switch(err) {
|
|
251
|
+ case GL_INVALID_OPERATION: error="INVALID_OPERATION"; break;
|
|
252
|
+ case GL_INVALID_ENUM: error="INVALID_ENUM"; break;
|
|
253
|
+ case GL_INVALID_VALUE: error="INVALID_VALUE"; break;
|
|
254
|
+ case GL_OUT_OF_MEMORY: error="OUT_OF_MEMORY"; break;
|
|
255
|
+ case GL_INVALID_FRAMEBUFFER_OPERATION: error="INVALID_FRAMEBUFFER_OPERATION"; break;
|
|
256
|
+ }
|
|
257
|
+ throw new std::runtime_error( "OpenGL threw an error: " + error );
|
199
|
258
|
}
|
200
|
259
|
if ( (!options->nokeyboard && slop::keyboard->anyKeyDown()) || slop::mouse->getButton( 3 ) ) {
|
201
|
260
|
memory.running = false;
|