From 523d8de33f2e0e139b60db23ac17165d8497e2da Mon Sep 17 00:00:00 2001 From: Joshua Moerman Date: Sun, 10 Jul 2011 18:28:53 +0200 Subject: [PATCH] nice shader effects (blurlike shit), codebase for video 5 --- App.h | 99 ++++++++++++++++++++--------- GlutTest.cbp | 7 ++ fbo.h | 113 ++++++++++++++++++++------------- globals.h | 7 ++ main.cpp | 7 +- pngwriter/pngwriter.h | 2 +- resources/myHBlurShader.frag | 12 ++++ resources/myHBlurShader.vert | 5 ++ resources/myTeaShader.frag | 2 +- resources/myTeaShader.vert | 3 +- resources/myTextureShader.frag | 8 +++ resources/myTextureShader.vert | 5 ++ resources/myVBlurShader.frag | 12 ++++ resources/myVBlurShader.vert | 5 ++ shader.h | 9 ++- 15 files changed, 215 insertions(+), 81 deletions(-) create mode 100644 globals.h create mode 100644 resources/myHBlurShader.frag create mode 100644 resources/myHBlurShader.vert create mode 100644 resources/myTextureShader.frag create mode 100644 resources/myTextureShader.vert create mode 100644 resources/myVBlurShader.frag create mode 100644 resources/myVBlurShader.vert diff --git a/App.h b/App.h index d115d20..d8a0e3c 100644 --- a/App.h +++ b/App.h @@ -21,15 +21,31 @@ static const std::string filenames[] = { "resources/attractor_2011-04-29_04-34-41-9.stf", "resources/attractor_2011-04-29_15-19-03-9.stf" }; +static const GLfloat quad[] = { + 1.0, 1.0, + 1.0, -1.0, + -1.0, -1.0, + -1.0, 1.0 }; + +static const GLfloat tex_quad[] = { + 1.0, 1.0, + 1.0, 0.0, + 0.0, 0.0, + 0.0, 1.0 }; + class App { int counter; unsigned int width, height; shader mshader; shader clear_shader; - fbo mfbo; + shader texture_shader; + shader blur_shader1; + shader blur_shader2; + fbo fbo1; + fbo fbo2; - static constexpr size_t number_of_lines = 6*50000; + static constexpr size_t number_of_lines = 40000; static constexpr size_t number_of_vertices = 2*number_of_lines; std::array lines; std::array parameters; @@ -42,12 +58,19 @@ public: height(h), mshader("resources/myTeaShader.vert", "resources/myTeaShader.frag"), clear_shader("resources/myClearShader.vert", "resources/myClearShader.frag"), - mfbo(width, height) { + texture_shader("resources/myTextureShader.vert", "resources/myTextureShader.frag"), + blur_shader1("resources/myHBlurShader.vert", "resources/myHBlurShader.frag"), + blur_shader2("resources/myVBlurShader.vert", "resources/myVBlurShader.frag"), + fbo1(width, height), + fbo2(width, height), + lines(), + parameters(), + random_parameters() { set_points(); //glEnable(GL_DEPTH_TEST); glEnable(GL_BLEND); - glPointSize(1.0); + glEnable(GL_TEXTURE_2D); std::string filename = filenames[3]; set_parameters(filename); @@ -57,63 +80,79 @@ public: } void resize(int w, int h) { + std::cout << w << "x" << h << std::endl; } void update() { ++counter; iterate(); - if(counter % 500 == 0) { + if(counter % 5000 == 0) { set_parameters(filenames[rand() % 4]); set_points(); } } void draw() { - clear_shader.begin(); - clear_shader.set_uniform("fade", .5f); - if( counter < 5 ) - clear_shader.set_uniform("fade", 1.0f); - fade(); - + fbo & read_fbo = (counter % 2) ? fbo1 : fbo2; + fbo & draw_fbo = (counter % 2) ? fbo2 : fbo1; + shader & blur_shader = (counter % 2) ? blur_shader1 : blur_shader2; + + glClearColor(0.0, 0.0, 0.0, 0.0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + draw_fbo.begin(); + glClearColor(0.0, 0.0, 0.0, 0.0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + blur_shader.begin(); + texture(read_fbo); mshader.begin(); - mshader.set_uniform("steps", counter); + scene(); + draw_fbo.end(); - glRotatef(0.5, std::sin(counter/1337.0), 1.0, 0.0); + texture_shader.begin(); + texture(draw_fbo); - scene(); + //save_screen(); } void fade() { glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - static const GLfloat quad[] = { - 1.0, 1.0, - 1.0, -1.0, - -1.0, -1.0, - -1.0, 1.0 }; glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(2, GL_FLOAT, 0, &quad[0]); - - // draw a cube glDrawArrays(GL_QUADS, 0, 4); + glDisableClientState(GL_VERTEX_ARRAY); + } - // deactivate vertex arrays after drawing + void texture(fbo const & read_fbo) { + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + texture_shader.set_texture("tex", GL_TEXTURE_2D, read_fbo.texture_id, 0); + + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glVertexPointer(2, GL_FLOAT, 0, &quad[0]); + glTexCoordPointer(2, GL_FLOAT, 0, &tex_quad[0]); + glDrawArrays(GL_QUADS, 0, 4); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisableClientState(GL_VERTEX_ARRAY); } void scene() { glBlendFunc(GL_ONE, GL_ONE); - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(3, GL_FLOAT, 0, &lines[0]); - // draw a cube - glDrawArrays(GL_POINTS, 0, number_of_vertices); + mshader.set_uniform("steps", counter/10); + glRotatef(0.05, std::sin(counter/13370.0), 1.0, 0.0); - // deactivate vertex arrays after drawing - glDisableClientState(GL_VERTEX_ARRAY); + const unsigned int part = 8; - //save_screen(); + glEnableClientState(GL_VERTEX_ARRAY); + glVertexPointer(3, GL_FLOAT, 0, &lines[0]); + glPointSize(3.0); + glDrawArrays(GL_POINTS, 0, number_of_vertices/part); + glPointSize(1.0); + glDrawArrays(GL_POINTS, number_of_vertices/part, (part-1)*number_of_vertices/part); + glDisableClientState(GL_VERTEX_ARRAY); } void iterate() { @@ -159,7 +198,7 @@ public: for(unsigned int i = 0; i < 7; ++i) { stfu::node const attractorParameters = file.getChild("AttractorKernel").getChild("parameters"); parameters[i] = atof(attractorParameters.getValue(i).c_str()); - random_parameters[i] = (rand() / (double)RAND_MAX - 0.5) * counter / 500000.0; + random_parameters[i] = (rand() / (double)RAND_MAX - 0.5) * counter / 5000000.0; } } diff --git a/GlutTest.cbp b/GlutTest.cbp index 567aee9..744edd7 100644 --- a/GlutTest.cbp +++ b/GlutTest.cbp @@ -40,13 +40,20 @@ + + + + + + + diff --git a/fbo.h b/fbo.h index df90f20..85c4998 100644 --- a/fbo.h +++ b/fbo.h @@ -6,18 +6,17 @@ #include #include - class fbo { +public: int width, height; GLuint fbo_number; std::map renderbuffers; GLuint texture_id; public: - fbo(int width, int height) : width(width), height(height) { - check_status(); - glGenBuffers(1, &fbo_number); - begin(); + fbo(int width, int height) : width(width), height(height), fbo_number(0), renderbuffers(), texture_id(0) { + glGenFramebuffers(1, &fbo_number); + bind(); // generate texture glGenTextures(1, &texture_id); @@ -30,9 +29,14 @@ public: create_attach_renderbuffer(GL_DEPTH_COMPONENT, GL_DEPTH_ATTACHMENT); // attach stencil - create_attach_renderbuffer(GL_STENCIL_INDEX, GL_STENCIL_ATTACHMENT); + //create_attach_renderbuffer(GL_STENCIL_INDEX, GL_STENCIL_ATTACHMENT); check_status(); + + glClearColor(0.0, 0.0, 0.0, 0.0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + unbind(); } ~fbo() { end(); @@ -47,14 +51,33 @@ public: } void begin(){ - glBindFramebuffer(GL_FRAMEBUFFER, fbo_number); + bind(); + //glPushAttrib(GL_VIEWPORT); + //glViewport(0, 0, width, height); + + /*GLint savedFramebuffer = -1; + glGetIntegerv(GL_FRAMEBUFFER_BINDING, &savedFramebuffer); + std::cout << "sfb: " << savedFramebuffer << ", fbo: " << fbo_number << std::endl;*/ } void end(){ - glBindFramebuffer(GL_FRAMEBUFFER, 0); + unbind(); + //glPopAttrib(); } private: + void bind(){ + glBindFramebuffer(GL_FRAMEBUFFER, fbo_number); + + GLenum status = glGetError(); + if(status != GL_NO_ERROR) + throw std::runtime_error("i has error" + std::to_string(status) + "with fbo: " + std::to_string(fbo_number)); + } + + void unbind(){ + glBindFramebuffer(GL_FRAMEBUFFER, 0); + } + void create_attach_renderbuffer(GLenum format, GLenum attachment_point) { GLuint buffer; glGenRenderbuffers(1, &buffer); @@ -66,42 +89,46 @@ private: } void check_status() { + GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); + switch(status) { + case GL_FRAMEBUFFER_COMPLETE: + std::cout << "FRAMEBUFFER_COMPLETE - OK" << std::endl; + return; + case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: + std::cout << "FRAMEBUFFER_INCOMPLETE_ATTACHMENT" << std::endl; + break; + case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: + std::cout << "FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT" << std::endl; + break; + /*case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS: + std::cout << "FRAMEBUFFER_INCOMPLETE_DIMENSIONS" << std::endl; + break; + case GL_FRAMEBUFFER_INCOMPLETE_FORMATS: + std::cout << "FRAMEBUFFER_INCOMPLETE_FORMATS" << std::endl; + break;*/ + case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER: + std::cout << "FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER" << std::endl; + break; + case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER: + std::cout << "FRAMEBUFFER_INCOMPLETE_READ_BUFFER" << std::endl; + break; + case GL_FRAMEBUFFER_UNSUPPORTED: + std::cout << "FRAMEBUFFER_UNSUPPORTED" << std::endl; + break; + case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE: + std::cout << "GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE" << std::endl; + break; + default: + std::cout << "UNKNOWN FRAMEBUFFER ERROR" << std::endl; + break; + } + //throw std::runtime_error("I will not continu.."); + } + + void check_error(){ GLenum status = glGetError(); - if(status != GL_NO_ERROR) { - status = glCheckFramebufferStatus(GL_FRAMEBUFFER); - switch(status) { - case GL_FRAMEBUFFER_COMPLETE: - std::cout << "FRAMEBUFFER_COMPLETE - OK" << std::endl; - return; - case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: - std::cout << "FRAMEBUFFER_INCOMPLETE_ATTACHMENT" << std::endl; - break; - case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: - std::cout << "FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT" << std::endl; - break; - /*case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS: - std::cout << "FRAMEBUFFER_INCOMPLETE_DIMENSIONS" << std::endl; - break; - case GL_FRAMEBUFFER_INCOMPLETE_FORMATS: - std::cout << "FRAMEBUFFER_INCOMPLETE_FORMATS" << std::endl; - break;*/ - case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER: - std::cout << "FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER" << std::endl; - break; - case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER: - std::cout << "FRAMEBUFFER_INCOMPLETE_READ_BUFFER" << std::endl; - break; - case GL_FRAMEBUFFER_UNSUPPORTED: - std::cout << "FRAMEBUFFER_UNSUPPORTED" << std::endl; - break; - case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE: - std::cout << "GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE" << std::endl; - break; - default: - std::cout << "UNKNOWN FRAMEBUFFER ERROR" << std::endl; - break; - } - throw std::runtime_error("I will not continu.."); + if(status != GL_NO_ERROR){ + throw std::runtime_error("GL Error: " + std::to_string(status)); } } diff --git a/globals.h b/globals.h new file mode 100644 index 0000000..0da3080 --- /dev/null +++ b/globals.h @@ -0,0 +1,7 @@ +#ifndef globals_h +#define globals_h + +#define kWindowWidth 800 +#define kWindowHeight 600 + +#endif // globals_h diff --git a/main.cpp b/main.cpp index 1a3c37c..64ba0d2 100644 --- a/main.cpp +++ b/main.cpp @@ -7,13 +7,11 @@ #include #include "App.h" - -#define kWindowWidth 1280 -#define kWindowHeight 700 +#include "globals.h" App* app_ptr = 0; -unsigned int const frames_per_second = 100.0; +unsigned int const frames_per_second = 60.0; typedef std::chrono::high_resolution_clock clock_type; @@ -64,6 +62,7 @@ int main(int argc, char** argv) { //glFlush(); ++frame_count; + if(frame_count == 7400) exit(0); previous_timepoint = current_timepoint-(difference%time_step); } else { diff --git a/pngwriter/pngwriter.h b/pngwriter/pngwriter.h index 6b5b83c..e42587c 100644 --- a/pngwriter/pngwriter.h +++ b/pngwriter/pngwriter.h @@ -88,7 +88,7 @@ using namespace std; #define PNG_BYTES_TO_CHECK (4) -#define PNGWRITER_DEFAULT_COMPRESSION (6) +#define PNGWRITER_DEFAULT_COMPRESSION (0) class pngwriter { private: diff --git a/resources/myHBlurShader.frag b/resources/myHBlurShader.frag new file mode 100644 index 0000000..f369015 --- /dev/null +++ b/resources/myHBlurShader.frag @@ -0,0 +1,12 @@ +uniform sampler2D tex; + +vec2 offset = vec2(0.0, 1.0/600.0); + +void main( void ) { + gl_FragColor = texture2D(tex, gl_TexCoord[0].st + offset); + gl_FragColor += texture2D(tex, gl_TexCoord[0].st - offset); + gl_FragColor = normalize(gl_FragColor) + 0.5*gl_FragColor; + gl_FragColor *= 0.56; + //gl_FragColor = sin(gl_FragColor*3.0); + gl_FragColor.a = 1.0; +} diff --git a/resources/myHBlurShader.vert b/resources/myHBlurShader.vert new file mode 100644 index 0000000..9e4d3bc --- /dev/null +++ b/resources/myHBlurShader.vert @@ -0,0 +1,5 @@ + +void main( void ) { + gl_TexCoord[0] = gl_MultiTexCoord0; + gl_Position = gl_Vertex; +} diff --git a/resources/myTeaShader.frag b/resources/myTeaShader.frag index ed6f047..5fbdf67 100644 --- a/resources/myTeaShader.frag +++ b/resources/myTeaShader.frag @@ -4,6 +4,6 @@ uniform int steps; void main( void ) { gl_FragColor.rgb = sin(3.0*sin(normalize(color.rgb) + vec3(steps)*vec3(0.01, 0.017, 0.0093)))*0.5+0.5; - gl_FragColor.rgb *= 0.1; + gl_FragColor.rgb *= 0.05; gl_FragColor.a = 1.0; } diff --git a/resources/myTeaShader.vert b/resources/myTeaShader.vert index a05c7b4..b5fdf42 100644 --- a/resources/myTeaShader.vert +++ b/resources/myTeaShader.vert @@ -2,6 +2,7 @@ varying vec4 color; void main( void ) { gl_Position = ftransform(); - gl_Position.xyz = gl_Position.xyz*0.6 - vec3(0.0, 0.0, 0.0); + gl_Position.xyz = gl_Position.xyz*0.6; + gl_Position.x *= 600.0/800.0; color = gl_Vertex; } diff --git a/resources/myTextureShader.frag b/resources/myTextureShader.frag new file mode 100644 index 0000000..2a3b49a --- /dev/null +++ b/resources/myTextureShader.frag @@ -0,0 +1,8 @@ + +uniform sampler2D tex; + +void main( void ) { + gl_FragColor = texture2D(tex, gl_TexCoord[0].st); + //gl_FragColor = sin(gl_FragColor*3.0); + gl_FragColor.a = 1.0; +} diff --git a/resources/myTextureShader.vert b/resources/myTextureShader.vert new file mode 100644 index 0000000..9e4d3bc --- /dev/null +++ b/resources/myTextureShader.vert @@ -0,0 +1,5 @@ + +void main( void ) { + gl_TexCoord[0] = gl_MultiTexCoord0; + gl_Position = gl_Vertex; +} diff --git a/resources/myVBlurShader.frag b/resources/myVBlurShader.frag new file mode 100644 index 0000000..f62e68d --- /dev/null +++ b/resources/myVBlurShader.frag @@ -0,0 +1,12 @@ +uniform sampler2D tex; + +vec2 offset = vec2(1.0/800.0, 0.0); + +void main( void ) { + gl_FragColor = texture2D(tex, gl_TexCoord[0].st + offset); + gl_FragColor += texture2D(tex, gl_TexCoord[0].st - offset); + gl_FragColor = normalize(gl_FragColor) + 0.5*gl_FragColor; + gl_FragColor *= 0.56; + //gl_FragColor = sin(gl_FragColor*3.0); + gl_FragColor.a = 1.0; +} diff --git a/resources/myVBlurShader.vert b/resources/myVBlurShader.vert new file mode 100644 index 0000000..9e4d3bc --- /dev/null +++ b/resources/myVBlurShader.vert @@ -0,0 +1,5 @@ + +void main( void ) { + gl_TexCoord[0] = gl_MultiTexCoord0; + gl_Position = gl_Vertex; +} diff --git a/shader.h b/shader.h index 9687771..462ccf7 100644 --- a/shader.h +++ b/shader.h @@ -16,7 +16,8 @@ class shader { public: - shader(std::string vertex_shader_filename, std::string fragment_shader_filename) { + shader(std::string vertex_shader_filename, std::string fragment_shader_filename) : + program(0), shaders() { program = glCreateProgram(); if(program == 0) { throw std::runtime_error("Program couldn't be created"); @@ -91,6 +92,12 @@ public: glUniform4i(glGetUniformLocation(program, name), x, y, z, w); } + void set_texture(const char* name, GLenum target, GLuint tex, int textureLocation) { + glActiveTexture(GL_TEXTURE0 + textureLocation); + glBindTexture(target, tex); + set_uniform(name, textureLocation); + } + private: void read_shader(std::istream& file, GLenum type) {