diff --git a/ImageShader.cpp b/ImageShader.cpp index b2ef5ac..8fdd1eb 100644 --- a/ImageShader.cpp +++ b/ImageShader.cpp @@ -16,6 +16,7 @@ void ImageShader::use() program_->setUniform("brightness", brightness); program_->setUniform("contrast", contrast); + program_->setUniform("stipple", stipple); } @@ -25,6 +26,7 @@ void ImageShader::reset() brightness = 0.f; contrast = 0.f; + stipple = 0.f; } void ImageShader::accept(Visitor& v) { diff --git a/ImageShader.h b/ImageShader.h index a529c7f..b445304 100644 --- a/ImageShader.h +++ b/ImageShader.h @@ -16,6 +16,7 @@ public: float brightness; float contrast; + float stipple; }; #endif // IMAGESHADER_H diff --git a/Mesh.cpp b/Mesh.cpp index 8f31f1b..a520053 100644 --- a/Mesh.cpp +++ b/Mesh.cpp @@ -332,20 +332,31 @@ Mesh::Mesh(const std::string& ply_path, const std::string& tex_path) : Primitive Log::Warning("Mesh could not be created from %s", ply_path.c_str()); } - // selective creation of the shader (deleted in Primitive) - if (texture_resource_.empty()) - shader_ = new Shader; - else - shader_ = new ImageShader; + // default non texture shader (deleted in Primitive) + shader_ = new Shader; } +void Mesh::setTexture(uint textureindex) +{ + if (textureindex) { + + // replace previous shader with a new Image Shader + if (shader_) + delete shader_; + shader_ = new ImageShader; + + textureindex_ = textureindex; + } + +} + void Mesh::init() { Primitive::init(); if (!texture_resource_.empty()) - textureindex_ = Resource::getTextureImage(texture_resource_); + setTexture(Resource::getTextureImage(texture_resource_)); } diff --git a/Mesh.h b/Mesh.h index 8261a42..eea9fa7 100644 --- a/Mesh.h +++ b/Mesh.h @@ -18,6 +18,8 @@ class Mesh : public Primitive { public: Mesh(const std::string& ply_path, const std::string& tex_path = ""); + void setTexture(uint textureindex); + void init () override; void draw (glm::mat4 modelview, glm::mat4 projection) override; void accept (Visitor& v) override; diff --git a/Primitives.cpp b/Primitives.cpp index bfb5eee..ca493a6 100644 --- a/Primitives.cpp +++ b/Primitives.cpp @@ -125,6 +125,8 @@ void MediaSurface::init() mediaplayer_->open(uri_); mediaplayer_->play(true); + + } void MediaSurface::draw(glm::mat4 modelview, glm::mat4 projection) diff --git a/RenderingManager.cpp b/RenderingManager.cpp index 91d2aa8..e275132 100644 --- a/RenderingManager.cpp +++ b/RenderingManager.cpp @@ -49,7 +49,6 @@ // local statics static GstGLContext *global_gl_context = NULL; static GstGLDisplay *global_display = NULL; -//static guintptr global_window_handle = 0; static void glfw_error_callback(int error, const char* description) { @@ -167,8 +166,6 @@ bool Rendering::Init() (guintptr) glfwGetGLXContext(main_window_), GST_GL_PLATFORM_GLX, GST_GL_API_OPENGL); - global_window_handle = (guintptr) glfwGetX11Window(main_window_); - #endif // TODO : force GPU decoding diff --git a/Source.cpp b/Source.cpp index 70f11e6..724c219 100644 --- a/Source.cpp +++ b/Source.cpp @@ -3,6 +3,7 @@ #include "Source.h" +#include "defines.h" #include "FrameBuffer.h" #include "ImageShader.h" #include "Primitives.h" @@ -14,7 +15,7 @@ // gobal static list of all sources SourceList Source::sources_; -Source::Source(std::string name) : name_("") +Source::Source(std::string name) : name_(""), initialized_(false) { // set a name rename(name); @@ -30,7 +31,7 @@ Source::Source(std::string name) : name_("") Frame *frame = new Frame; frame->translation_.z = 0.1; groups_[View::MIXING]->addChild(frame); - groups_[View::MIXING]->scale_ = glm::vec3(0.25f, 0.25f, 1.f); + groups_[View::MIXING]->scale_ = glm::vec3(0.2f, 0.2f, 1.f); // add source to the list sources_.push_front(this); @@ -147,8 +148,19 @@ MediaPlayer *MediaSource::mediaplayer() const return surface_->getMediaPlayer(); } +void MediaSource::init() +{ + ImageShader *is = static_cast(surface_->shader()); + if (is) + is->stipple = 1.0; + + initialized_ = true; +} + void MediaSource::render() { + if (!initialized_) + init(); // surface_->shader() // scalle all mixing nodes to match scale of surface @@ -158,7 +170,9 @@ void MediaSource::render() } // read position of the mixing node and interpret this as transparency change - float alpha = 1.0 - ABS( groups_[View::MIXING]->translation_.x ); + float alpha = 1.0 - SQUARE( glm::length(groups_[View::MIXING]->translation_) ); surface_->shader()->color.a = alpha; + + } diff --git a/Source.h b/Source.h index 62abeea..aaf64ee 100644 --- a/Source.h +++ b/Source.h @@ -51,6 +51,10 @@ protected: // name std::string name_; + // every Source shall be initialized on first draw + bool initialized_; + virtual void init() = 0; + // nodes std::map groups_; @@ -96,6 +100,8 @@ public: protected: + virtual void init(); + MediaSurface *surface_; }; diff --git a/View.cpp b/View.cpp index 1178e9d..c6c598e 100644 --- a/View.cpp +++ b/View.cpp @@ -3,14 +3,20 @@ #include #include +// memmove +#include + #include "defines.h" #include "View.h" #include "Source.h" #include "Primitives.h" +#include "Resource.h" #include "Mesh.h" #include "FrameBuffer.h" #include "Log.h" +#define CIRCLE_PIXELS 64 +#define CIRCLE_PIXEL_RADIUS 1024.0 View::View() { @@ -24,8 +30,12 @@ void View::update(float dt) MixingView::MixingView() : View() { + // default settings + scene.root()->scale_ = glm::vec3(1.4, 1.4, 1.0); + // Mixing scene - Mesh *disk = new Mesh("mesh/disk.ply", "images/transparencygrid.png"); + Mesh *disk = new Mesh("mesh/disk.ply"); + disk->setTexture(textureMixingQuadratic()); backgound_.addChild(disk); glm::vec4 pink( 0.8f, 0.f, 0.8f, 1.f ); @@ -104,6 +114,55 @@ void MixingView::grab (glm::vec2 from, glm::vec2 to, Source *s) } + +uint MixingView::textureMixingQuadratic() +{ + static GLuint texid = 0; + if (texid == 0) { + // generate the texture with alpha exactly as computed for sources + glGenTextures(1, &texid); + glBindTexture(GL_TEXTURE_2D, texid); + GLubyte matrix[CIRCLE_PIXELS*CIRCLE_PIXELS * 4]; + GLubyte color[4] = {0,0,0,0}; + GLfloat luminance = 1.f; + GLfloat alpha = 0.f; + GLfloat distance = 0.f; + int l = -CIRCLE_PIXELS / 2 + 1, c = 0; + + for (int i = 0; i < CIRCLE_PIXELS / 2; ++i) { + c = -CIRCLE_PIXELS / 2 + 1; + for (int j=0; j < CIRCLE_PIXELS / 2; ++j) { + // distance to the center + distance = (GLfloat) ((c * c) + (l * l)) / CIRCLE_PIXEL_RADIUS; + // luminance + luminance = 255.f * CLAMP( 0.95f - 0.8f * distance, 0.f, 1.f); + color[0] = color[1] = color[2] = static_cast(luminance); + // alpha + alpha = 255.f * CLAMP( 1.f - distance , 0.f, 1.f); + color[3] = static_cast(alpha); + + // 1st quadrant + memmove(&matrix[ j * 4 + i * CIRCLE_PIXELS * 4 ], color, 4); + // 4nd quadrant + memmove(&matrix[ (CIRCLE_PIXELS -j -1)* 4 + i * CIRCLE_PIXELS * 4 ], color, 4); + // 3rd quadrant + memmove(&matrix[ j * 4 + (CIRCLE_PIXELS -i -1) * CIRCLE_PIXELS * 4 ], color, 4); + // 4th quadrant + memmove(&matrix[ (CIRCLE_PIXELS -j -1) * 4 + (CIRCLE_PIXELS -i -1) * CIRCLE_PIXELS * 4 ], color, 4); + + ++c; + } + ++l; + } + // two components texture : luminance and alpha + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, CIRCLE_PIXELS, CIRCLE_PIXELS, 0, GL_RGBA, GL_UNSIGNED_BYTE, (float *) matrix); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + } + return texid; +} + RenderView::RenderView() : View(), frame_buffer_(nullptr) { setResolution(1280, 720); diff --git a/View.h b/View.h index cab6018..476887d 100644 --- a/View.h +++ b/View.h @@ -38,6 +38,8 @@ public: void drag (glm::vec2 from, glm::vec2 to) override; void grab (glm::vec2 from, glm::vec2 to, Source *s) override; +private: + uint textureMixingQuadratic(); }; class RenderView : public View @@ -53,5 +55,6 @@ public: void setResolution (uint width, uint height); inline FrameBuffer *frameBuffer () const { return frame_buffer_; } + }; #endif // VIEW_H diff --git a/defines.h b/defines.h index 1c2d214..8ed99c1 100644 --- a/defines.h +++ b/defines.h @@ -10,6 +10,7 @@ #define ABS(a) (((a) < 0) ? -(a) : (a)) #define ABS_DIFF(a, b) ( (a) < (b) ? (b - a) : (a - b) ) #define SIGN(a) (((a) < 0) ? -1.0 : 1.0) +#define SQUARE(a) ((a) * (a)) #define CLAMP(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x))) #define EPSILON 0.00001 #define LOG100(val) (50.0/log(10.0)*log((float)val + 1.0)) diff --git a/rsc/shaders/texture-shader.fs b/rsc/shaders/texture-shader.fs index 00375de..901f365 100644 --- a/rsc/shaders/texture-shader.fs +++ b/rsc/shaders/texture-shader.fs @@ -9,13 +9,16 @@ uniform sampler2D sourceTexture; uniform vec4 color; uniform float contrast; uniform float brightness; +uniform float stipple; uniform vec3 resolution; // viewport resolution (in pixels) void main() { - vec4 texturecolor = texture(sourceTexture, vertexUV); - vec3 transformedRGB = mix(vec3(0.62), texturecolor.rgb, contrast + 1.0) + brightness; - transformedRGB *= vertexColor.rgb; + vec4 textureColor = texture(sourceTexture, vertexUV); + vec3 transformedRGB = mix(vec3(0.62), textureColor.rgb, contrast + 1.0) + brightness; + transformedRGB *= vertexColor.rgb * color.rgb; - FragColor = color * vec4(transformedRGB, texturecolor.a * vertexColor.a); + float a = int(gl_FragCoord.x + gl_FragCoord.y)%2 > 1 - int(stipple) ? 1.0 : color.a; + + FragColor = vec4(transformedRGB, textureColor.a * vertexColor.a * a); }