From c7ea3aee6f9cf8604ca34ba8eb24abf75474e3c4 Mon Sep 17 00:00:00 2001 From: frank <420@shampoo.ooo> Date: Mon, 9 Aug 2021 22:47:55 -0400 Subject: [PATCH] added flat background to 3d scene and effects to fragment shader --- config.json | 3 +- resource/mario_3_star_background.png | Bin 0 -> 7437 bytes src/Pudding.cpp | 48 ++++++++++++++++++++++++--- src/Pudding.hpp | 2 +- src/flat.frag | 14 ++++++-- src/flat.vert | 1 - src/mvp.frag | 18 +++++++++- src/white.frag | 9 +++++ 8 files changed, 84 insertions(+), 11 deletions(-) create mode 100644 resource/mario_3_star_background.png create mode 100644 src/white.frag diff --git a/config.json b/config.json index 40922b8..c31331f 100644 --- a/config.json +++ b/config.json @@ -20,7 +20,8 @@ "enabled": true, "write-mp4": true, "video-frame-length": 33.333, - "max-video-memory": 2000 + "max-video-memory": 2000, + "mp4-pixel-format": "yuv420p" }, "input": { diff --git a/resource/mario_3_star_background.png b/resource/mario_3_star_background.png new file mode 100644 index 0000000000000000000000000000000000000000..55e81e5dc40c96f2814b156f0d5fbba4f114c5fa GIT binary patch literal 7437 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 E0gk3+L;wH) literal 0 HcmV?d00001 diff --git a/src/Pudding.cpp b/src/Pudding.cpp index 51dd708..09cf719 100644 --- a/src/Pudding.cpp +++ b/src/Pudding.cpp @@ -33,7 +33,7 @@ Pudding::Pudding() /* initialize a zbar image scanner for reading barcodes of any format */ image_scanner.set_config(zbar::ZBAR_NONE, zbar::ZBAR_CFG_ENABLE, 1); /* set up pudding model */ - set_pudding_model(1.0f, 1.6f, 12, 5, -.6, .6, .25); + set_pudding_model(1.0f, 1.6f, 10, 12, -.6, .6, .25); /* use gl context so we can draw 3D */ load_gl_context(); initialize_camera(); @@ -68,7 +68,7 @@ void Pudding::set_pudding_model( sfw::points_on_circle(layer_base_ring, ring_vertex_count, layer_base_percent * (base_radius - top_radius) + top_radius); /* layers above gradient position are brown, layers below are yellow, and the layer that contains gradient positon * is a gradient from brown to yellow */ - if (layer_top_percent <= gradient_position && layer_base_percent >= gradient_position) + if (layer_top_percent <= gradient_position && layer_base_percent > gradient_position) { layer_top_color = &PUDDING_BROWN; layer_bottom_color = &PUDDING_YELLOW; @@ -132,6 +132,23 @@ void Pudding::set_pudding_model( void Pudding::load_gl_context() { super::load_gl_context(); + /* load background as surface, generate texture to load pixel data into, allocate storage, bind and edit texture properties */ + std::unique_ptr surface(IMG_Load("resource/mario_3_star_background.png"), SDL_FreeSurface); + std::unique_ptr flipped_surface(rotozoomSurfaceXY(surface.get(), 0, 1, -1, 0), SDL_FreeSurface); + glGenTextures(1, &background_texture_id); + glBindTexture(GL_TEXTURE_2D, background_texture_id); + glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGB8, flipped_surface->w, flipped_surface->h); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + // SDL_Surface* surface = zoomSurface( + // rotateSurface90Degrees(IMG_Load("resource/tile.png"), 2), -1, 1, SMOOTHING_OFF); + /* load as an SDL surface to translate image format into pixel data, flip, and get dimensions */ + // SDL_RWops* rw = SDL_RWFromConstMem(storage.data(), storage.size()); + // SDL_Surface* surface = IMG_Load_RW(rw, 0); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, flipped_surface->w, flipped_surface->h, GL_RGBA, GL_UNSIGNED_BYTE, flipped_surface->pixels); + std::ostringstream message; + message << "loaded background image " << flipped_surface->w << "x" << flipped_surface->h; + log(message.str()); /* Allocate a vertex array object, bind it as current, doesn't need to be a member var because the same one is always bound */ GLuint vao; glGenVertexArrays(1, &vao); @@ -606,14 +623,32 @@ void Pudding::update() viewport_box.set_right(get_window_box().get_center_x(), true); } glViewport(viewport_box.get_x(), viewport_box.get_y(), viewport_box.get_w(), viewport_box.get_h()); - glClearColor(1.0, 0.5, 0.8, 1.0f); glDisable(GL_DEPTH_TEST); + glClearColor(0, 0, 0, 1); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + /* switch to flat shader for background */ + glUseProgram(flat_program); + /* disable pudding attributes and enable rectangle attributes */ + glDisableVertexAttribArray(2); + glDisableVertexAttribArray(3); + glEnableVertexAttribArray(0); + glEnableVertexAttribArray(1); + GLint base_texture_location = glGetUniformLocation(flat_program, "base_texture"); + glUniform1i(base_texture_location, 0); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, background_texture_id); + /* set blend to modify white part of background, color passed is in HSV format */ + GLint blend_min_hsv_location = glGetUniformLocation(flat_program, "blend_min_hsv"); + float hue = std::abs(std::abs(model[0][0]) - 0.5) * 2; + glUniform3f(blend_min_hsv_location, hue, 0.9, 1); + /* draws rectangle vertices and rectangle texture using UV coords */ + glDrawArrays(GL_TRIANGLES, 0, 6); /* draw pudding model using MVP shader */ glUseProgram(mvp_program); /* calculate the transformation matrix for displaying pudding in viewport */ model = glm::rotate(model, weight(get_configuration()["pudding"]["rotation-speed"].get()), Y_UNIT_NORMAL_3D); - projection = glm::perspective(glm::radians(45.0f), viewport_box.aspect(), 0.1f, 100.0f); + projection = glm::perspective( + glm::radians(viewport_box.get_w() > viewport_box.get_h() ? 40.0f : 45.0f), viewport_box.aspect(), 0.1f, 100.0f); mvp = projection * VIEW_MATRIX * model; /* pass the mvp matrix to the shader */ glUniformMatrix4fv(mvp_id, 1, GL_FALSE, &mvp[0][0]); @@ -638,11 +673,14 @@ void Pudding::update() glEnableVertexAttribArray(1); glDisable(GL_DEPTH_TEST); /* just need to set these once since we're drawing one texture per viewport */ - GLint base_texture_location = glGetUniformLocation(flat_program, "baseTexture"); + GLint base_texture_location = glGetUniformLocation(flat_program, "base_texture"); glUniform1i(base_texture_location, 0); glActiveTexture(GL_TEXTURE0); /* move viewport to the right side of screen */ viewport_box.set_left(get_window_box().get_center_x()); + /* reset blend to display the original texture colors */ + GLint blend_min_location = glGetUniformLocation(flat_program, "blend_min_hsv"); + glUniform3f(blend_min_location, 1, 0, 1); /* draw the current item image if items have been downloaded */ if (items.size() > 0) { diff --git a/src/Pudding.hpp b/src/Pudding.hpp index 86feefd..087b0ee 100644 --- a/src/Pudding.hpp +++ b/src/Pudding.hpp @@ -46,7 +46,7 @@ private: cv::VideoCapture capture; cv::Mat capture_frame; zbar::ImageScanner image_scanner; - GLuint vbo, flat_program, mvp_program, video_capture_texture_id, mvp_id; + GLuint vbo, flat_program, mvp_program, video_capture_texture_id, mvp_id, background_texture_id; glm::mat4 projection, model = glm::mat4(1.0f), mvp; std::vector pudding_vertices, pudding_colors; diff --git a/src/flat.frag b/src/flat.frag index a48288c..8db5178 100644 --- a/src/flat.frag +++ b/src/flat.frag @@ -1,9 +1,19 @@ #version 130 in vec2 UV; -uniform sampler2D baseTexture; +uniform sampler2D base_texture; +uniform vec3 blend_min_hsv; + +/* from http://lolengine.net/blog/2013/07/27/rgb-to-hsv-in-glsl, licensed under WTFPL */ +vec3 hsv2rgb(vec3 c) +{ + vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); + vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www); + return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y); +} void main(void) { - gl_FragColor = texture(baseTexture, UV); + gl_FragColor = texture(base_texture, UV); + gl_FragColor = min(gl_FragColor, vec4(hsv2rgb(blend_min_hsv), 1)); } diff --git a/src/flat.vert b/src/flat.vert index 7edfcb9..69414b8 100644 --- a/src/flat.vert +++ b/src/flat.vert @@ -2,7 +2,6 @@ in vec2 in_Position; in vec2 vertexUV; - out vec2 UV; void main(void) diff --git a/src/mvp.frag b/src/mvp.frag index 98014fc..bc433c5 100644 --- a/src/mvp.frag +++ b/src/mvp.frag @@ -5,5 +5,21 @@ in float x; void main(void) { - gl_FragColor = vec4(ex_Color * x, 1); + vec3 shadowed = ex_Color; + float r = min(1, shadowed[0]); + float g = min(1, shadowed[1]); + float b = min(1, shadowed[2]); + float dx = abs(floor(gl_FragCoord[0]) - 480) / 480.0; + if (int(floor(gl_FragCoord[0] / 3) + floor(gl_FragCoord[1]) / 3) % 2 == 0) + { + gl_FragColor = vec4(vec3(r, g, b) * 1.3, 1); + } + else + { + gl_FragColor = vec4(vec3(r, g, b) * 0.6, 1); + } + gl_FragColor[0] = int(gl_FragColor[0] * 4) / 4.0; + gl_FragColor[1] = int(gl_FragColor[1] * 4) / 4.0; + gl_FragColor[2] = int(gl_FragColor[2] * 4) / 4.0; + gl_FragColor *= x; } diff --git a/src/white.frag b/src/white.frag new file mode 100644 index 0000000..8daf986 --- /dev/null +++ b/src/white.frag @@ -0,0 +1,9 @@ +#version 130 + +in vec3 ex_Color; +in float x; + +void main(void) +{ + gl_FragColor = vec4(1, 1, 1, 1); +}