diff --git a/app/node/blend/alphaover/alphaover.cpp b/app/node/blend/alphaover/alphaover.cpp index f5fb4056d..ede7691a2 100644 --- a/app/node/blend/alphaover/alphaover.cpp +++ b/app/node/blend/alphaover/alphaover.cpp @@ -1,6 +1,6 @@ #include "alphaover.h" -#include "render/rendertypes.h" +#include "render/rendertexture.h" AlphaOverBlend::AlphaOverBlend() { @@ -35,5 +35,5 @@ void AlphaOverBlend::Process(const rational &time) //GLuint base_tex = base_input_->get_value(time).value(); // FIXME: Does nothing - texture_output()->set_value(blend_input()->get_value(time).value()); + texture_output()->set_value(QVariant::fromValue(blend_input()->get_value(time).value())); } diff --git a/app/node/input/media/media.cpp b/app/node/input/media/media.cpp index 7999fcf7c..c6d0677a5 100644 --- a/app/node/input/media/media.cpp +++ b/app/node/input/media/media.cpp @@ -72,7 +72,7 @@ QString MediaInput::Description() void MediaInput::Release() { - buffer_.Destroy(); + texture_.Destroy(); decoder_ = nullptr; } diff --git a/app/node/input/media/media.h b/app/node/input/media/media.h index 733b3d26f..e9857ebc9 100644 --- a/app/node/input/media/media.h +++ b/app/node/input/media/media.h @@ -28,7 +28,7 @@ #include "render/colorservice.h" // FIXME: Test code only -#include "render/texturebuffer.h" +#include "render/rendertexture.h" #include "render/gl/shaderptr.h" // End test code @@ -65,7 +65,7 @@ private: NodeOutput* texture_output_; - TextureBuffer buffer_; + RenderTexture texture_; DecoderPtr decoder_; diff --git a/app/node/processor/renderer/renderer.cpp b/app/node/processor/renderer/renderer.cpp index e49537590..a8c3307da 100644 --- a/app/node/processor/renderer/renderer.cpp +++ b/app/node/processor/renderer/renderer.cpp @@ -26,7 +26,6 @@ #include #include -#include "render/rendertypes.h" #include "renderpath.h" #include "rendererprobe.h" diff --git a/app/render/CMakeLists.txt b/app/render/CMakeLists.txt index 16a537aec..3a0a6a23b 100644 --- a/app/render/CMakeLists.txt +++ b/app/render/CMakeLists.txt @@ -27,9 +27,10 @@ set(OLIVE_SOURCES render/renderinstance.h render/renderinstance.cpp render/rendermodes.h - render/rendertypes.h + render/renderframebuffer.h + render/renderframebuffer.cpp + render/rendertexture.h + render/rendertexture.cpp render/sampleformat.h - render/texturebuffer.h - render/texturebuffer.cpp PARENT_SCOPE ) diff --git a/app/render/renderframebuffer.cpp b/app/render/renderframebuffer.cpp new file mode 100644 index 000000000..be6601f61 --- /dev/null +++ b/app/render/renderframebuffer.cpp @@ -0,0 +1,127 @@ +/*** + + Olive - Non-Linear Video Editor + Copyright (C) 2019 Olive Team + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +***/ + +#include "renderframebuffer.h" + +#include +#include + +RenderFramebuffer::RenderFramebuffer() : + context_(nullptr), + buffer_(0), + texture_(nullptr) +{ + +} + +RenderFramebuffer::~RenderFramebuffer() +{ + Destroy(); +} + +void RenderFramebuffer::Create(QOpenGLContext *ctx) +{ + if (ctx == nullptr) { + qWarning() << tr("RenderTexture::Create was passed an invalid context"); + return; + } + + // Free any previous framebuffer + Destroy(); + + context_ = ctx; + + // Create framebuffer object + context_->functions()->glGenFramebuffers(1, &buffer_); +} + +void RenderFramebuffer::Destroy() +{ + if (context_ != nullptr) { + context_->functions()->glDeleteFramebuffers(1, &buffer_); + + buffer_ = 0; + + context_ = nullptr; + } +} + +bool RenderFramebuffer::IsCreated() const +{ + return (buffer_ > 0); +} + +void RenderFramebuffer::Bind() +{ + if (context_ == nullptr) { + return; + } + context_->functions()->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, buffer_); +} + +void RenderFramebuffer::Release() +{ + if (context_ == nullptr) { + return; + } + context_->functions()->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); +} + +void RenderFramebuffer::Attach(RenderTexturePtr texture) +{ + Detach(); + + texture_ = texture; + + QOpenGLFunctions* f = context_->functions(); + + // bind framebuffer for attaching + f->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, buffer_); + + // bind texture + f->glBindTexture(GL_TEXTURE_2D, texture_->texture()); + + context_->extraFunctions()->glFramebufferTexture2D( + GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture_->texture(), 0 + ); + + // release texture + f->glBindTexture(GL_TEXTURE_2D, 0); + + // release framebuffer + f->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); +} + +void RenderFramebuffer::Detach() +{ + QOpenGLFunctions* f = context_->functions(); + + // bind framebuffer for attaching + f->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, buffer_); + + context_->extraFunctions()->glFramebufferTexture2D( + GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0 + ); + + // release framebuffer + f->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); + + texture_ = nullptr; +} diff --git a/app/render/renderframebuffer.h b/app/render/renderframebuffer.h new file mode 100644 index 000000000..39cd9821b --- /dev/null +++ b/app/render/renderframebuffer.h @@ -0,0 +1,60 @@ +/*** + + Olive - Non-Linear Video Editor + Copyright (C) 2019 Olive Team + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +***/ + +#ifndef RENDERFRAMEBUFFER_H +#define RENDERFRAMEBUFFER_H + +#include + +#include "rendertexture.h" + +class RenderFramebuffer : public QObject +{ +public: + RenderFramebuffer(); + ~RenderFramebuffer(); + RenderFramebuffer(const RenderFramebuffer& other) = delete; + RenderFramebuffer(RenderFramebuffer&& other) = delete; + RenderFramebuffer& operator=(const RenderFramebuffer& other) = delete; + RenderFramebuffer& operator=(RenderFramebuffer&& other) = delete; + + void Create(QOpenGLContext *ctx); + + void Destroy(); + + bool IsCreated() const; + + void Bind(); + + void Release(); + + void Attach(RenderTexturePtr texture); + + void Detach(); + +private: + QOpenGLContext* context_; + + GLuint buffer_; + + RenderTexturePtr texture_; +}; + +#endif // RENDERFRAMEBUFFER_H diff --git a/app/render/renderinstance.cpp b/app/render/renderinstance.cpp index 6bb9af876..b0d72a942 100644 --- a/app/render/renderinstance.cpp +++ b/app/render/renderinstance.cpp @@ -51,7 +51,7 @@ bool RenderInstance::Start() return false; } - buffer_.Create(&ctx_, format_, width_, height_); + buffer_.Create(&ctx_); return true; } @@ -73,7 +73,7 @@ bool RenderInstance::IsStarted() return buffer_.IsCreated(); } -TextureBuffer *RenderInstance::buffer() +RenderFramebuffer *RenderInstance::buffer() { return &buffer_; } diff --git a/app/render/renderinstance.h b/app/render/renderinstance.h index 1578ceeed..58a390309 100644 --- a/app/render/renderinstance.h +++ b/app/render/renderinstance.h @@ -25,9 +25,8 @@ #include #include +#include "render/renderframebuffer.h" #include "render/rendermodes.h" -#include "render/rendertypes.h" -#include "render/texturebuffer.h" /** * @brief An object containing all resources necessary for each thread to support hardware accelerated rendering @@ -50,14 +49,14 @@ public: bool IsStarted(); - TextureBuffer* buffer(); + RenderFramebuffer* buffer(); private: QOpenGLContext ctx_; QOffscreenSurface surface_; - TextureBuffer buffer_; + RenderFramebuffer buffer_; int width_; diff --git a/app/render/rendertexture.cpp b/app/render/rendertexture.cpp new file mode 100644 index 000000000..df437a215 --- /dev/null +++ b/app/render/rendertexture.cpp @@ -0,0 +1,180 @@ +/*** + + Olive - Non-Linear Video Editor + Copyright (C) 2019 Olive Team + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +***/ + +#include "rendertexture.h" + +#include + +#include "render/pixelservice.h" + +RenderTexture::RenderTexture() : + context_(nullptr), + texture_(0) +{ + +} + +RenderTexture::~RenderTexture() +{ + Destroy(); +} + +bool RenderTexture::IsCreated() const +{ + return (texture_ != 0); +} + +void RenderTexture::Create(QOpenGLContext *ctx, int width, int height, const olive::PixelFormat &format, void* data) +{ + if (ctx == nullptr) { + qWarning() << tr("RenderTexture::Create was passed an invalid context"); + return; + } + + Destroy(); + + context_ = ctx; + + QOpenGLFunctions* f = context_->functions(); + + // Create texture + f->glGenTextures(1, &texture_); + + // Verify texture + if (texture_ == 0) { + qWarning() << tr("OpenGL texture creation failed"); + return; + } + + // Bind texture + f->glBindTexture(GL_TEXTURE_2D, texture_); + + // Allocate storage for texture + const PixelFormatInfo& bit_depth = PixelService::GetPixelFormatInfo(format); + + f->glTexImage2D( + GL_TEXTURE_2D, + 0, + bit_depth.internal_format, + width, + height, + 0, + bit_depth.pixel_format, + bit_depth.pixel_type, + data + ); + + // Set texture filtering to bilinear + f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + // Release texture + f->glBindTexture(GL_TEXTURE_2D, 0); +} + +void RenderTexture::Destroy() +{ + if (context_ != nullptr) { + context_->functions()->glDeleteTextures(1, &texture_); + + context_ = nullptr; + } +} + +void RenderTexture::Bind() +{ + if (context_ == nullptr) { + qWarning() << "RenderTexture::Bind() called with an invalid context"; + return; + } + + context_->functions()->glBindTexture(GL_TEXTURE_2D, texture_); +} + +void RenderTexture::Release() +{ + if (context_ == nullptr) { + qWarning() << "RenderTexture::Release() called with an invalid context"; + return; + } + + context_->functions()->glBindTexture(GL_TEXTURE_2D, 0); +} + +const int &RenderTexture::width() const +{ + return width_; +} + +const int &RenderTexture::height() const +{ + return height_; +} + +const olive::PixelFormat &RenderTexture::format() const +{ + return format_; +} + +QOpenGLContext *RenderTexture::context() const +{ + return context_; +} + +const GLuint &RenderTexture::texture() const +{ + return texture_; +} + +void RenderTexture::Upload(void *data) +{ + if (!IsCreated()) { + qWarning() << tr("RenderTexture::Upload() called while it wasn't created"); + return; + } + + Bind(); + + PixelFormatInfo info = PixelService::GetPixelFormatInfo(format_); + + context_->functions()->glTexSubImage2D(GL_TEXTURE_2D, + 0, + 0, + 0, + width_, + height_, + info.pixel_format, + info.pixel_type, + data); + + Release(); +} + +void *RenderTexture::Download() const +{ + if (!IsCreated()) { + qWarning() << tr("RenderTexture::Download() called while it wasn't created"); + return nullptr; + } + + // FIXME: Implement this + + return nullptr; +} diff --git a/app/render/rendertexture.h b/app/render/rendertexture.h new file mode 100644 index 000000000..c2e9fa7dc --- /dev/null +++ b/app/render/rendertexture.h @@ -0,0 +1,78 @@ +/*** + + Olive - Non-Linear Video Editor + Copyright (C) 2019 Olive Team + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +***/ + +#ifndef RENDERTEXTURE_H +#define RENDERTEXTURE_H + +#include +#include + +#include "pixelformat.h" + +class RenderTexture : public QObject +{ +public: + RenderTexture(); + ~RenderTexture(); + RenderTexture(const RenderTexture& other) = delete; + RenderTexture(RenderTexture&& other) = delete; + RenderTexture& operator=(const RenderTexture& other) = delete; + RenderTexture& operator=(RenderTexture&& other) = delete; + + void Create(QOpenGLContext* ctx, int width, int height, const olive::PixelFormat &format, void *data = nullptr); + + bool IsCreated() const; + + void Destroy(); + + void Bind(); + + void Release(); + + const int& width() const; + + const int& height() const; + + const olive::PixelFormat &format() const; + + QOpenGLContext* context() const; + + const GLuint& texture() const; + + void Upload(void* data); + + void* Download() const; + +private: + QOpenGLContext* context_; + + GLuint texture_; + + int width_; + + int height_; + + olive::PixelFormat format_; +}; + +using RenderTexturePtr = std::shared_ptr; +Q_DECLARE_METATYPE(RenderTexturePtr) + +#endif // RENDERTEXTURE_H diff --git a/app/render/rendertypes.h b/app/render/rendertypes.h deleted file mode 100644 index e240ed903..000000000 --- a/app/render/rendertypes.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef RENDERTYPES_H -#define RENDERTYPES_H - -#include - -using RenderTexture = GLuint; - -#endif // RENDERTYPES_H diff --git a/app/render/texturebuffer.cpp b/app/render/texturebuffer.cpp deleted file mode 100644 index 98f7fd735..000000000 --- a/app/render/texturebuffer.cpp +++ /dev/null @@ -1,182 +0,0 @@ -/*** - - Olive - Non-Linear Video Editor - Copyright (C) 2019 Olive Team - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -***/ - -#include "texturebuffer.h" - -#include -#include - -#include "render/pixelservice.h" - -TextureBuffer::TextureBuffer() : - ctx_(nullptr), - buffer_(0), - texture_(0) -{} - -TextureBuffer::~TextureBuffer() -{ - Destroy(); -} - -bool TextureBuffer::IsCreated() -{ - return (ctx_ != nullptr); -} - -void TextureBuffer::Create(QOpenGLContext *ctx, const olive::PixelFormat &format, int width, int height, void* data) -{ - // free any previous textures - Destroy(); - - // set context to new context provided - ctx_ = ctx; - - // Store frame metadata - width_ = width; - height_ = height; - format_ = format; - - QOpenGLFunctions* f = ctx->functions(); - - // create framebuffer object - f->glGenFramebuffers(1, &buffer_); - - // create texture - f->glGenTextures(1, &texture_); - - // bind framebuffer for attaching - f->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, buffer_); - - // bind texture - f->glBindTexture(GL_TEXTURE_2D, texture_); - - // allocate storage for texture - const PixelFormatInfo& bit_depth = PixelService::GetPixelFormatInfo(format); - - ctx->functions()->glTexImage2D( - GL_TEXTURE_2D, - 0, - bit_depth.internal_format, - width, - height, - 0, - bit_depth.pixel_format, - bit_depth.pixel_type, - data - ); - - // set texture filtering to bilinear - f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); - f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - - // attach texture to framebuffer - ctx->extraFunctions()->glFramebufferTexture2D( - GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture_, 0 - ); - - // clear new texture (doesn't seem to be necessary) - /*if (data == nullptr) { - ctx->functions()->glClearColor(0.0f, 0.0f, 0.0f, 0.0f); - ctx->functions()->glClear(GL_COLOR_BUFFER_BIT); - }*/ - - // release texture - f->glBindTexture(GL_TEXTURE_2D, 0); - - // release framebuffer - f->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); -} - -void TextureBuffer::Destroy() -{ - if (ctx_ != nullptr) { - ctx_->functions()->glDeleteFramebuffers(1, &buffer_); - - ctx_->functions()->glDeleteTextures(1, &texture_); - - ctx_ = nullptr; - } -} - -void TextureBuffer::Upload(void *data) -{ - if (!IsCreated()) { - return; - } - - BindTexture(); - - PixelFormatInfo info = PixelService::GetPixelFormatInfo(format_); - - glTexSubImage2D(GL_TEXTURE_2D, - 0, - 0, - 0, - width_, - height_, - info.pixel_format, - info.pixel_type, - data); - - ReleaseTexture(); -} - -void TextureBuffer::BindBuffer() const -{ - if (ctx_ == nullptr) { - return; - } - ctx_->functions()->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, buffer_); -} - -void TextureBuffer::ReleaseBuffer() const -{ - if (ctx_ == nullptr) { - return; - } - ctx_->functions()->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); -} - -void TextureBuffer::BindTexture() const -{ - if (ctx_ == nullptr) { - return; - } - ctx_->functions()->glBindTexture(GL_TEXTURE_2D, texture_); -} - -void TextureBuffer::ReleaseTexture() const -{ - if (ctx_ == nullptr) { - return; - } - ctx_->functions()->glBindTexture(GL_TEXTURE_2D, 0); -} - -const GLuint &TextureBuffer::buffer() const -{ - return buffer_; -} - -const GLuint &TextureBuffer::texture() const -{ - return texture_; -} diff --git a/app/render/texturebuffer.h b/app/render/texturebuffer.h deleted file mode 100644 index 36fd458da..000000000 --- a/app/render/texturebuffer.h +++ /dev/null @@ -1,66 +0,0 @@ -/*** - - Olive - Non-Linear Video Editor - Copyright (C) 2019 Olive Team - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -***/ - -#ifndef FRAMEBUFFEROBJECT_H -#define FRAMEBUFFEROBJECT_H - -#include - -#include "pixelformat.h" - -/** - * @brief A class for managing an OpenGL framebuffer and attached texture - * - * The GPU pipeline will frequently need framebuffers for drawing onto textures. The TextureBuffer is a convenience - * class to handle the creation, management, and destruction of a framebuffer with a texture attachment. - * - * After creating a new TextureBuffer, call Create() when a valid OpenGL context is available. - */ -class TextureBuffer -{ -public: - TextureBuffer(); - ~TextureBuffer(); - - bool IsCreated(); - void Create(QOpenGLContext* ctx, const olive::PixelFormat& format, int width, int height, void *data = nullptr); - void Destroy(); - - void Upload(void *data); - - const GLuint& buffer() const; - const GLuint& texture() const; - - void BindBuffer() const; - void ReleaseBuffer() const; - - void BindTexture() const; - void ReleaseTexture() const; -private: - QOpenGLContext* ctx_; - GLuint buffer_; - GLuint texture_; - - int width_; - int height_; - olive::PixelFormat format_; -}; - -#endif // FRAMEBUFFEROBJECT_H