From f71ccb4be694eaac7768be6056846c9d09f2bba4 Mon Sep 17 00:00:00 2001 From: Joshua Moerman Date: Thu, 28 Jul 2011 14:20:01 +0200 Subject: [PATCH] heart version, bmp output --- App.h | 154 ++++++++++++++++++++++++++++++--- bmp.h | 75 ++++++++++++++++ globals.h | 4 +- main.cpp | 3 + resources/myHBlurShader.frag | 4 +- resources/myHBlurShader.vert | 2 +- resources/myTeaShader.vert | 9 +- resources/myTextureShader.frag | 20 +++-- shader.h | 8 ++ 9 files changed, 252 insertions(+), 27 deletions(-) create mode 100644 bmp.h diff --git a/App.h b/App.h index c29e131..d49d61e 100644 --- a/App.h +++ b/App.h @@ -11,10 +11,68 @@ #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, @@ -27,10 +85,25 @@ static const GLfloat tex_quad[] = { 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; + int counter, counter2; unsigned int width, height; + unsigned int color_scheme; shader mshader; shader clear_shader; @@ -42,10 +115,15 @@ public: 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"), @@ -53,7 +131,9 @@ public: fbo1(width, height), fbo2(width, height), mouse_buttons{{false, false, false}}, - mouse{{0.0f, 0.0f}}{ + mouse{{0.0f, 0.0f}}, + color_transformation(), + background_color(){ //glEnable(GL_DEPTH_TEST); glEnable(GL_BLEND); @@ -67,16 +147,47 @@ public: 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() { - fbo & read_fbo = (counter % 2) ? fbo1 : fbo2; - fbo & draw_fbo = (counter % 2) ? fbo2 : fbo1; + 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); @@ -87,7 +198,7 @@ public: 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(counter) / width, (float) sin(counter) / height); + 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); @@ -101,12 +212,7 @@ public: scene(); draw_fbo.end(); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - texture_shader.begin(); - texture(texture_shader, draw_fbo); - - if(counter % 4 == 0) - save_screen(); + return draw_fbo; } void fade() { @@ -137,10 +243,20 @@ public: glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(2, GL_FLOAT, 0, &mouse[0]); - glPointSize(50.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(){ @@ -153,6 +269,20 @@ public: 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 diff --git a/bmp.h b/bmp.h new file mode 100644 index 0000000..5cd9218 --- /dev/null +++ b/bmp.h @@ -0,0 +1,75 @@ +#ifndef BMP_H +#define BMP_H + +#include +#include +#include + +namespace bmp { + +struct bitmap_file_header { + uint32_t filesize; + uint16_t creator1; + uint16_t creator2; + uint32_t bmp_offset; + + template + bitmap_file_header(DIBT dib_header): + filesize(dib_header.bytes() + dib_header.header_sz + 12 + 2), + creator1(0), + creator2(0), + bmp_offset(dib_header.header_sz + 12 + 2){} + + void write(std::ostream& out) const { + out << "BM"; + out.write(reinterpret_cast(this), 12); + } +}; + +struct bitmapcoreheader { + uint32_t header_sz; + uint16_t width; + uint16_t height; + uint16_t nplanes; + uint16_t bitspp; + + bitmapcoreheader(int width, int height): + header_sz(sizeof(bitmapcoreheader)), + width(width), + height(height), + nplanes(1), + bitspp(24){} + + void write(std::ostream& out) const { + out.write(reinterpret_cast(this), header_sz); + } + + unsigned int bytes(){ + return width*height*bitspp/8; + } +}; + +template +struct bitmap { + DIBT dib_header; + bitmap_file_header header; + T const * data; + + bitmap(int width, int height): + dib_header(width, height), + header(dib_header), + data(0) { + } + + void write(std::ostream& out){ + header.write(out); + dib_header.write(out); + std::copy_n((char const *)data, dib_header.bytes(), std::ostream_iterator(out)); + } + +}; + +} + +#endif // BMP_H + diff --git a/globals.h b/globals.h index 0da3080..b38349a 100644 --- a/globals.h +++ b/globals.h @@ -1,7 +1,7 @@ #ifndef globals_h #define globals_h -#define kWindowWidth 800 -#define kWindowHeight 600 +#define kWindowWidth 1280 +#define kWindowHeight 720 #endif // globals_h diff --git a/main.cpp b/main.cpp index 1e7c72a..d04e199 100644 --- a/main.cpp +++ b/main.cpp @@ -96,6 +96,9 @@ int main(int argc, char** argv) { app_ptr->mouse[0] = x; app_ptr->mouse[1] = y; }); + glutKeyboardFunc([](unsigned char x, int, int) { + app_ptr->pressed(x); + }); glutCloseFunc(end); // freeglut extension // my app-object diff --git a/resources/myHBlurShader.frag b/resources/myHBlurShader.frag index 3e4797b..51d8907 100644 --- a/resources/myHBlurShader.frag +++ b/resources/myHBlurShader.frag @@ -13,8 +13,8 @@ void main( void ) { gl_FragColor *= fade; //gl_FragColor = sin(gl_FragColor*3.0); - gl_FragColor -= 0.033*texture2D(tex, gl_TexCoord[0].st + 30.0*offset); - gl_FragColor -= 0.033*texture2D(tex, gl_TexCoord[0].st - 30.0*offset); + gl_FragColor -= 0.033*texture2D(tex, gl_TexCoord[0].st + 15.0*offset); + gl_FragColor -= 0.033*texture2D(tex, gl_TexCoord[0].st - 15.0*offset); gl_FragColor.a = 1.0; } diff --git a/resources/myHBlurShader.vert b/resources/myHBlurShader.vert index 9e4d3bc..0215d6c 100644 --- a/resources/myHBlurShader.vert +++ b/resources/myHBlurShader.vert @@ -1,5 +1,5 @@ void main( void ) { - gl_TexCoord[0] = gl_MultiTexCoord0; + gl_TexCoord[0] = (gl_MultiTexCoord0 - vec4(0.5))/1.00 + vec4(0.5); gl_Position = gl_Vertex; } diff --git a/resources/myTeaShader.vert b/resources/myTeaShader.vert index af24bc0..d82eacc 100644 --- a/resources/myTeaShader.vert +++ b/resources/myTeaShader.vert @@ -4,14 +4,15 @@ uniform int button; void main( void ) { gl_Position = gl_Vertex; - gl_Position.xy /= vec2(800, 600)*0.5; + gl_Position.xy *= vec2(1.0, 1.2); + /*gl_Position.xy /= vec2(1280, 720)*0.5; gl_Position.xy -= 1.0; - gl_Position.y *= -1.0; + gl_Position.y *= -1.0;*/ if(button == 0) color = vec4(1.0); else if (button == 1) - color = vec4(0.0, 1.0, 1.0, 1.0); + color = vec4(0.1, 1.0, 0.9, 1.0); else - color = vec4(0.0, 0.0, 1.0, 1.0); + color = vec4(0.0, 0.3, 1.0, 1.0); } diff --git a/resources/myTextureShader.frag b/resources/myTextureShader.frag index 7237842..cdedade 100644 --- a/resources/myTextureShader.frag +++ b/resources/myTextureShader.frag @@ -1,16 +1,24 @@ uniform sampler2D tex; +uniform vec4 background_color; +uniform mat4 color_transformation; + void main( void ) { - gl_FragColor = texture2D(tex, gl_TexCoord[0].st); + vec4 orig = texture2D(tex, gl_TexCoord[0].st); + + + gl_FragColor = background_color + color_transformation * orig; - vec2 offset = vec2(0.01, 0.0); + { // shine + vec2 offset = vec2(0.01, 0.0); - vec4 a = texture2D(tex, gl_TexCoord[0].st - offset); - vec4 b = texture2D(tex, gl_TexCoord[0].st + offset); + vec4 a = texture2D(tex, gl_TexCoord[0].st - offset); + vec4 b = texture2D(tex, gl_TexCoord[0].st + offset); - if(length(a-b) < 0.1 && length(gl_FragColor.rgb) > 0.3) - gl_FragColor *= 1.0 + 0.01/length(a-b); + if(length(a-b) < 0.1 && length(orig.rgb) > 0.3) + gl_FragColor *= 1.0 + 0.01/length(a-b); + } gl_FragColor.a = 1.0; } diff --git a/shader.h b/shader.h index 309804f..8d08566 100644 --- a/shader.h +++ b/shader.h @@ -92,6 +92,14 @@ public: glUniform4i(glGetUniformLocation(program, name), x, y, z, w); } + void set_matrix(char const* name, bool trans, const GLfloat* value) const { + glUniformMatrix4fv(glGetUniformLocation(program, name), 1, trans, value); + } + + void set_vector(char const* name, const GLfloat* value) const { + glUniform4fv(glGetUniformLocation(program, name), 1, value); + } + void set_texture(const char* name, GLenum target, GLuint tex, int textureLocation) const { glActiveTexture(GL_TEXTURE0 + textureLocation); glBindTexture(target, tex);