Implementation of custom Masks

FrameBuffer accepts to fill any size of FrameBufferImage as input, and a Dialog in TextureView allows to select a JPG or PNG.
This commit is contained in:
Bruno
2021-08-06 13:23:59 +02:00
parent d1b7073ff9
commit a9c8b67975
3 changed files with 62 additions and 9 deletions

View File

@@ -342,7 +342,16 @@ FrameBufferImage::FrameBufferImage(jpegBuffer jpgimg) :
rgb = stbi_load_from_memory(jpgimg.buffer, jpgimg.len, &width, &height, &c, 3); rgb = stbi_load_from_memory(jpgimg.buffer, jpgimg.len, &width, &height, &c, 3);
} }
FrameBufferImage::~FrameBufferImage() { FrameBufferImage::FrameBufferImage(const std::string &filename) :
rgb(nullptr), width(0), height(0)
{
int c = 0;
if (!filename.empty())
rgb = stbi_load(filename.c_str(), &width, &height, &c, 3);
}
FrameBufferImage::~FrameBufferImage()
{
if (rgb!=nullptr) if (rgb!=nullptr)
delete rgb; delete rgb;
} }
@@ -392,22 +401,49 @@ bool FrameBuffer::fill(FrameBufferImage *image)
if (!framebufferid_) if (!framebufferid_)
init(); init();
// not compatible for RGB // only compatible for RGB FrameBuffers
if (use_alpha_ || use_multi_sampling_) if (use_alpha_ || use_multi_sampling_)
return false; return false;
// invalid image // invalid image
if ( image == nullptr || if ( image == nullptr ||
image->rgb==nullptr || image->rgb==nullptr ||
image->width !=attrib_.viewport.x || image->width < 1 ||
image->height!=attrib_.viewport.y ) image->height < 1 )
return false; return false;
// fill texture with image // is it same size ?
glBindTexture(GL_TEXTURE_2D, textureid_); if (image->width == attrib_.viewport.x && image->height == attrib_.viewport.y ) {
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, image->width, image->height, // directly fill texture with image
GL_RGB, GL_UNSIGNED_BYTE, image->rgb); glBindTexture(GL_TEXTURE_2D, textureid_);
glBindTexture(GL_TEXTURE_2D, 0); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, image->width, image->height,
GL_RGB, GL_UNSIGNED_BYTE, image->rgb);
glBindTexture(GL_TEXTURE_2D, 0);
}
else {
uint textureimage, framebufferimage;
// generate texture
glGenTextures(1, &textureimage);
glBindTexture(GL_TEXTURE_2D, textureimage);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, image->width, image->height, 0, GL_RGB, GL_UNSIGNED_BYTE, image->rgb);
glBindTexture(GL_TEXTURE_2D, 0);
// create a framebuffer object
glGenFramebuffers(1, &framebufferimage);
glBindFramebuffer(GL_FRAMEBUFFER, framebufferimage);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureimage, 0);
// blit to the frame buffer object with interpolation
glBindFramebuffer(GL_READ_FRAMEBUFFER, framebufferimage);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebufferid_);
glBlitFramebuffer(0, 0, image->width, image->height,
0, 0, attrib_.viewport.x, attrib_.viewport.y, GL_COLOR_BUFFER_BIT, GL_LINEAR);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
// cleanup
glDeleteFramebuffers(1, &framebufferimage);
glDeleteTextures(1, &textureimage);
}
return true; return true;
} }

View File

@@ -24,6 +24,7 @@ public:
FrameBufferImage(int w, int h); FrameBufferImage(int w, int h);
FrameBufferImage(jpegBuffer jpgimg); FrameBufferImage(jpegBuffer jpgimg);
FrameBufferImage(const std::string &filename);
// non assignable class // non assignable class
FrameBufferImage(FrameBufferImage const&) = delete; FrameBufferImage(FrameBufferImage const&) = delete;
FrameBufferImage& operator=(FrameBufferImage const&) = delete; FrameBufferImage& operator=(FrameBufferImage const&) = delete;

View File

@@ -22,6 +22,7 @@
#include "Decorations.h" #include "Decorations.h"
#include "UserInterfaceManager.h" #include "UserInterfaceManager.h"
#include "ActionManager.h" #include "ActionManager.h"
#include "DialogToolkit.h"
#include "Log.h" #include "Log.h"
#include "TextureView.h" #include "TextureView.h"
@@ -717,6 +718,21 @@ void TextureView::draw()
ImGui::EndPopup(); ImGui::EndPopup();
} }
static DialogToolkit::OpenImageDialog maskdialog("Select Image");
ImGui::SameLine();
if (ImGui::Button(ICON_FA_FOLDER_OPEN))
maskdialog.open();
if (maskdialog.closed() && !maskdialog.path().empty())
{
FrameBufferImage *img = new FrameBufferImage(maskdialog.path());
if (edit_source_->maskbuffer_->fill( img )) {
std::ostringstream oss;
oss << edit_source_->name();
oss << ": Mask fill with " << maskdialog.path();
Action::manager().store(oss.str());
}
}
} }
// disabled info // disabled info