added flat background to 3d scene and effects to fragment shader

This commit is contained in:
frank 2021-08-09 22:47:55 -04:00
parent 00f64b4bf9
commit c7ea3aee6f
8 changed files with 84 additions and 11 deletions

View File

@ -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":
{

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

View File

@ -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<SDL_Surface, decltype(&SDL_FreeSurface)> surface(IMG_Load("resource/mario_3_star_background.png"), SDL_FreeSurface);
std::unique_ptr<SDL_Surface, decltype(&SDL_FreeSurface)> 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<float>()), 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)
{

View File

@ -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<glm::vec3> pudding_vertices, pudding_colors;

View File

@ -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));
}

View File

@ -2,7 +2,6 @@
in vec2 in_Position;
in vec2 vertexUV;
out vec2 UV;
void main(void)

View File

@ -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;
}

9
src/white.frag Normal file
View File

@ -0,0 +1,9 @@
#version 130
in vec3 ex_Color;
in float x;
void main(void)
{
gl_FragColor = vec4(1, 1, 1, 1);
}