split fbo and texture into two separate objects

This commit is contained in:
itsmattkc
2019-08-27 15:36:13 +10:00
parent 46ea071b99
commit 4b5516abb5
14 changed files with 459 additions and 271 deletions
+2 -2
View File
@@ -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<GLuint>();
// FIXME: Does nothing
texture_output()->set_value(blend_input()->get_value(time).value<RenderTexture>());
texture_output()->set_value(QVariant::fromValue(blend_input()->get_value(time).value<RenderTexturePtr>()));
}
+1 -1
View File
@@ -72,7 +72,7 @@ QString MediaInput::Description()
void MediaInput::Release()
{
buffer_.Destroy();
texture_.Destroy();
decoder_ = nullptr;
}
+2 -2
View File
@@ -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_;
-1
View File
@@ -26,7 +26,6 @@
#include <QImage>
#include <QtMath>
#include "render/rendertypes.h"
#include "renderpath.h"
#include "rendererprobe.h"
+4 -3
View File
@@ -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
)
+127
View File
@@ -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 <http://www.gnu.org/licenses/>.
***/
#include "renderframebuffer.h"
#include <QDebug>
#include <QOpenGLExtraFunctions>
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;
}
+60
View File
@@ -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 <http://www.gnu.org/licenses/>.
***/
#ifndef RENDERFRAMEBUFFER_H
#define RENDERFRAMEBUFFER_H
#include <QOpenGLContext>
#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
+2 -2
View File
@@ -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_;
}
+3 -4
View File
@@ -25,9 +25,8 @@
#include <QOffscreenSurface>
#include <QOpenGLContext>
#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_;
+180
View File
@@ -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 <http://www.gnu.org/licenses/>.
***/
#include "rendertexture.h"
#include <QDebug>
#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;
}
+78
View File
@@ -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 <http://www.gnu.org/licenses/>.
***/
#ifndef RENDERTEXTURE_H
#define RENDERTEXTURE_H
#include <memory>
#include <QOpenGLFunctions>
#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<RenderTexture>;
Q_DECLARE_METATYPE(RenderTexturePtr)
#endif // RENDERTEXTURE_H
-8
View File
@@ -1,8 +0,0 @@
#ifndef RENDERTYPES_H
#define RENDERTYPES_H
#include <QOpenGLFunctions>
using RenderTexture = GLuint;
#endif // RENDERTYPES_H
-182
View File
@@ -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 <http://www.gnu.org/licenses/>.
***/
#include "texturebuffer.h"
#include <QOpenGLFunctions>
#include <QOpenGLExtraFunctions>
#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_;
}
-66
View File
@@ -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 <http://www.gnu.org/licenses/>.
***/
#ifndef FRAMEBUFFEROBJECT_H
#define FRAMEBUFFEROBJECT_H
#include <QOpenGLContext>
#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