#ifndef APP_H #define APP_H #include #include #include #include #include #include #include #include "stfu/stf.hpp" #include "pngwriter/pngwriter.h" #include "bmp.h" #include "shader.h" #include "fbo.h" static const unsigned int colors = 7; static const GLfloat color_transformations[][16] = { { 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 }, { -0.1, -2.0, -0.9, 0.0, -0.4, -0.5, -0.9, 0.0, -2.0, -0.1, -0.9, 0.0, 0.0, 0.0, 0.0, 1.0 }, { 0.1, 0.0, -0.9, 0.0, 0.4, 1.0, 0.0, 0.0, 0.0, 0.1, 0.3, 0.0, 0.0, 0.0, 0.0, 1.0 }, { 0.5, -0.3, -0.5, 0.0, 0.5, 0.0, -0.5, 0.0, 0.5, 1.0, -0.5, 0.0, 0.0, 0.0, 0.0, 1.0 }, { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0 }, { 5.0, -1.0, -5.0, 0.0, -5.0, 5.0, -1.0, 0.0, -1.0, -5.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0 }, { 1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.8, 0.0, 0.0, 0.0, 0.0, 1.0 } }; static const GLfloat background_colors[][4] = { { 0.0, 0.0, 0.0, 0.0 }, { 1.0, 1.0, 1.0, 0.0 }, { 0.4, 0.0, 0.0, 0.0 }, { 0.5, 0.5, 0.5, 0.0 }, { 0.0, 0.5, 0.1, 0.0 }, { -0.5, -0.5, -0.5, 0.0}, { 0.1, 0.0, 0.2, 0.0} }; 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 }; static const GLfloat heart[] = { 0.0, 0.3, 0.06, 0.45, 0.16, 0.5, 0.3, 0.4, 0.33, 0.25, 0.0, -0.5, -0.33, 0.25, -0.3, 0.4, -0.16, 0.5, -0.06, 0.45, -0.0, 0.3 }; class App { public: int counter, counter2; unsigned int width, height; unsigned int color_scheme; shader mshader; shader clear_shader; shader texture_shader; shader blur_shader; fbo fbo1; fbo fbo2; std::array mouse_buttons; std::array mouse; std::array color_transformation; std::array background_color; App(unsigned int w, unsigned int h) : counter(0), counter2(0), width(w), height(h), color_scheme(6), mshader("resources/myTeaShader.vert", "resources/myTeaShader.frag"), clear_shader("resources/myClearShader.vert", "resources/myClearShader.frag"), texture_shader("resources/myTextureShader.vert", "resources/myTextureShader.frag"), blur_shader("resources/myHBlurShader.vert", "resources/myHBlurShader.frag"), fbo1(width, height), fbo2(width, height), mouse_buttons{{false, false, false}}, mouse{{0.0f, 0.0f}}, color_transformation(), background_color(){ //glEnable(GL_DEPTH_TEST); glEnable(GL_BLEND); glEnable(GL_TEXTURE_2D); } ~App() { } void resize(int w, int h) { std::cout << w << "x" << h << std::endl; } void pressed(char x){ switch(x){ case ' ': save_bmp(); break; case 'z': ++color_scheme %= colors; break; default: break; } } void update() { ++counter; if(counter % 100 == 0){ std::cout << counter << std::endl; } const float fade_speed = 0.1; for(unsigned int i = 0; i < color_transformation.size(); ++i) color_transformation[i] = (1.0 - fade_speed)*color_transformation[i] + fade_speed*color_transformations[color_scheme][i]; for(unsigned int i = 0; i < background_color.size(); ++i) background_color[i] = (1.0 - fade_speed)*background_color[i] + fade_speed*background_colors[color_scheme][i]; } void draw() { for(int i = 0; i < 2; ++i) magic(); auto const & draw_fbo = magic(); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); texture_shader.begin(); texture_shader.set_matrix("color_transformation", true, &color_transformation[0]); texture_shader.set_vector("background_color", &background_color[0]); texture(texture_shader, draw_fbo); //if(counter % 4 == 0) // save_bmp(); } fbo const & magic(){ ++counter2; fbo & read_fbo = (counter2 % 2) ? fbo1 : fbo2; fbo & draw_fbo = (counter2 % 2) ? fbo2 : fbo1; glClearColor(0.0, 0.0, 0.0, 0.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); draw_fbo.begin(); glClearColor(0.0, 0.0, 0.0, 0.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); blur_shader.begin(); blur_shader.set_uniform("offset", (float) cos(counter2) / width * 2.0f, (float) sin(counter2) / height * 2.0f); if(true){ blur_shader.set_uniform("fade", 0.75f); blur_shader.set_uniform("inter", 0.55f); } else { blur_shader.set_uniform("fade", 0.96f); blur_shader.set_uniform("inter", 0.9f); } texture(blur_shader, read_fbo); mshader.begin(); glBlendFunc(GL_ONE, GL_ONE); scene(); draw_fbo.end(); return draw_fbo; } void fade() { glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(2, GL_FLOAT, 0, &quad[0]); glDrawArrays(GL_QUADS, 0, 4); glDisableClientState(GL_VERTEX_ARRAY); } void texture(shader const & tex_shader, fbo const & read_fbo) { tex_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() { if(mouse_buttons[0] || mouse_buttons[1] || mouse_buttons[2]){ mshader.set_uniform("steps", counter/10); mshader.set_uniform("button", (mouse_buttons[0] ? 0 : (mouse_buttons[1] ? 1 : 2))); glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(2, GL_FLOAT, 0, &mouse[0]); glPointSize(50.0/1.0); glDrawArrays(GL_POINTS, 0, 1); glDisableClientState(GL_VERTEX_ARRAY); } if(counter < 50 || counter > 1200){ mshader.set_uniform("steps", counter/10); mshader.set_uniform("button", counter % 4); glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(2, GL_FLOAT, 0, &heart[0]); glLineWidth(15.0); glDrawArrays(GL_LINE_STRIP, 0, 11); glDisableClientState(GL_VERTEX_ARRAY); } } void save_screen(){ unsigned char data[width*height*6]; glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_SHORT, data); char filename[256]; sprintf(filename, "render/shot_%08d.png", counter); pngwriter png(width, height, &data[0], filename); png.close(); } void save_bmp(){ unsigned char data[width*height*3]; glReadPixels(0, 0, width, height, GL_BGR, GL_UNSIGNED_BYTE, data); char filename[256]; sprintf(filename, "render/shot_%08d.bmp", counter); bmp::bitmap image(width, height); image.data = data; std::ofstream file(filename); image.write(file); } }; #endif // APP_H