scopes: moved all shared code to a base class to easily add more scopes
This commit is contained in:
@@ -15,6 +15,7 @@
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
add_subdirectory(histogram)
|
||||
add_subdirectory(scopebase)
|
||||
add_subdirectory(waveform)
|
||||
|
||||
set(OLIVE_SOURCES
|
||||
|
||||
@@ -29,189 +29,8 @@
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
|
||||
HistogramScope::HistogramScope(QWidget* parent) :
|
||||
ManagedDisplayWidget(parent),
|
||||
buffer_(nullptr)
|
||||
ScopeBase(parent)
|
||||
{
|
||||
EnableDefaultContextMenu();
|
||||
|
||||
connect(&worker_, &HistogramScopeWorker::Finished, this, &HistogramScope::FinishedProcessing, Qt::QueuedConnection);
|
||||
worker_.start(QThread::IdlePriority);
|
||||
}
|
||||
|
||||
HistogramScope::~HistogramScope()
|
||||
{
|
||||
worker_.Cancel();
|
||||
worker_.quit();
|
||||
worker_.wait();
|
||||
}
|
||||
|
||||
void HistogramScope::SetBuffer(Frame* frame)
|
||||
{
|
||||
buffer_ = frame;
|
||||
|
||||
if (isVisible()) {
|
||||
StartUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
void HistogramScope::FinishedProcessing(QVector<double> red, QVector<double> green, QVector<double> blue)
|
||||
{
|
||||
red_val_ = red;
|
||||
green_val_ = green;
|
||||
blue_val_ = blue;
|
||||
|
||||
update();
|
||||
}
|
||||
|
||||
void HistogramScope::paintGL()
|
||||
{
|
||||
QVector<QLine> red_lines(red_val_.size());
|
||||
QVector<QLine> green_lines(green_val_.size());
|
||||
QVector<QLine> blue_lines(blue_val_.size());
|
||||
|
||||
for (int i=0;i<red_lines.size();i++) {
|
||||
red_lines.replace(i, QLine(i, height() * (1.0 - red_val_.at(i)), i, height()));
|
||||
green_lines.replace(i, QLine(i, height() * (1.0 - green_val_.at(i)), i, height()));
|
||||
blue_lines.replace(i, QLine(i, height() * (1.0 - blue_val_.at(i)), i, height()));
|
||||
}
|
||||
|
||||
QPainter p(this);
|
||||
p.setCompositionMode(QPainter::CompositionMode_Plus);
|
||||
|
||||
p.setPen(Qt::red);
|
||||
p.drawLines(red_lines);
|
||||
|
||||
p.setPen(Qt::green);
|
||||
p.drawLines(green_lines);
|
||||
|
||||
p.setPen(Qt::blue);
|
||||
p.drawLines(blue_lines);
|
||||
}
|
||||
|
||||
void HistogramScope::resizeEvent(QResizeEvent *e)
|
||||
{
|
||||
QOpenGLWidget::resizeEvent(e);
|
||||
|
||||
StartUpdate();
|
||||
}
|
||||
|
||||
void HistogramScope::ColorProcessorChangedEvent()
|
||||
{
|
||||
StartUpdate();
|
||||
}
|
||||
|
||||
void HistogramScope::StartUpdate()
|
||||
{
|
||||
if (buffer_) {
|
||||
worker_.QueueNext(*buffer_, color_service(), width());
|
||||
} else {
|
||||
// Update with nothing
|
||||
red_val_.clear();
|
||||
green_val_.clear();
|
||||
blue_val_.clear();
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
void HistogramScope::showEvent(QShowEvent* e)
|
||||
{
|
||||
ManagedDisplayWidget::showEvent(e);
|
||||
|
||||
StartUpdate();
|
||||
}
|
||||
|
||||
HistogramScopeWorker::HistogramScopeWorker() :
|
||||
cancelled_(false)
|
||||
{
|
||||
}
|
||||
|
||||
void HistogramScopeWorker::run()
|
||||
{
|
||||
while (!cancelled_) {
|
||||
next_lock_.lock();
|
||||
while (!next_.is_allocated()) {
|
||||
next_wait_.wait(&next_lock_);
|
||||
|
||||
if (cancelled_){
|
||||
next_lock_.unlock();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Copy values
|
||||
Frame f = next_;
|
||||
int w = next_width_;
|
||||
ColorProcessorPtr processor = next_processor_;
|
||||
next_.destroy();
|
||||
|
||||
next_lock_.unlock();
|
||||
|
||||
// Color manage frame
|
||||
|
||||
QVector<int> data(w * kRGBChannels, 0);
|
||||
|
||||
int max_w = w-1;
|
||||
|
||||
for (int x=0;x<f.width();x++) {
|
||||
for (int y=0;y<f.height();y++) {
|
||||
Color c = f.get_pixel(x, y);
|
||||
|
||||
if (processor) {
|
||||
c = processor->ConvertColor(c);
|
||||
}
|
||||
|
||||
data[qFloor(clamp(c.red(), 0.0f, 1.0f) * max_w)]++;
|
||||
data[qFloor(clamp(c.green(), 0.0f, 1.0f) * max_w) + w]++;
|
||||
data[qFloor(clamp(c.blue(), 0.0f, 1.0f) * max_w) + w * 2]++;
|
||||
}
|
||||
}
|
||||
|
||||
int max_val = 0;
|
||||
|
||||
foreach (const int& i, data) {
|
||||
if (i > max_val) {
|
||||
max_val = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (!max_val) {
|
||||
// Prevent divide by zero
|
||||
return;
|
||||
}
|
||||
|
||||
QVector<double> red_lines(w);
|
||||
QVector<double> green_lines(w);
|
||||
QVector<double> blue_lines(w);
|
||||
|
||||
for (int i=0;i<w;i++) {
|
||||
red_lines.replace(i, static_cast<double>(data.at(i)) / static_cast<double>(max_val));
|
||||
green_lines.replace(i, static_cast<double>(data.at(i + w)) / static_cast<double>(max_val));
|
||||
blue_lines.replace(i, static_cast<double>(data.at(i + w * 2)) / static_cast<double>(max_val));
|
||||
}
|
||||
|
||||
emit Finished(red_lines, green_lines, blue_lines);
|
||||
}
|
||||
}
|
||||
|
||||
void HistogramScopeWorker::QueueNext(const Frame &f, ColorProcessorPtr processor, int width)
|
||||
{
|
||||
next_lock_.lock();
|
||||
|
||||
next_ = f;
|
||||
next_width_ = width;
|
||||
next_processor_ = processor;
|
||||
|
||||
next_wait_.wakeOne();
|
||||
|
||||
next_lock_.unlock();
|
||||
}
|
||||
|
||||
void HistogramScopeWorker::Cancel()
|
||||
{
|
||||
cancelled_ = true;
|
||||
next_lock_.lock();
|
||||
next_wait_.wakeOne();
|
||||
next_lock_.unlock();
|
||||
}
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
|
||||
@@ -21,80 +21,20 @@
|
||||
#ifndef HISTOGRAMSCOPE_H
|
||||
#define HISTOGRAMSCOPE_H
|
||||
|
||||
#include <QMutex>
|
||||
#include <QThread>
|
||||
#include <QWaitCondition>
|
||||
|
||||
#include "codec/frame.h"
|
||||
#include "render/colorprocessor.h"
|
||||
#include "widget/manageddisplay/manageddisplay.h"
|
||||
#include "widget/scope/scopebase/scopebase.h"
|
||||
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
|
||||
class HistogramScopeWorker : public QThread
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
HistogramScopeWorker();
|
||||
|
||||
// Thread-safe
|
||||
void QueueNext(const Frame& f, ColorProcessorPtr processor, int width);
|
||||
|
||||
// Thread-safe
|
||||
void Cancel();
|
||||
|
||||
protected:
|
||||
virtual void run() override;
|
||||
|
||||
signals:
|
||||
void Finished(QVector<double> red, QVector<double> green, QVector<double> blue);
|
||||
|
||||
private:
|
||||
QAtomicInt cancelled_;
|
||||
|
||||
QMutex next_lock_;
|
||||
QWaitCondition next_wait_;
|
||||
Frame next_;
|
||||
int next_width_;
|
||||
ColorProcessorPtr next_processor_;
|
||||
|
||||
};
|
||||
|
||||
class HistogramScope : public ManagedDisplayWidget
|
||||
class HistogramScope : public ScopeBase
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
HistogramScope(QWidget* parent = nullptr);
|
||||
|
||||
virtual ~HistogramScope() override;
|
||||
|
||||
public slots:
|
||||
void SetBuffer(Frame* frame);
|
||||
|
||||
protected:
|
||||
virtual void paintGL() override;
|
||||
//virtual OpenGLShaderPtr CreateShader() override;
|
||||
|
||||
virtual void resizeEvent(QResizeEvent* e) override;
|
||||
|
||||
virtual void ColorProcessorChangedEvent() override;
|
||||
|
||||
virtual void showEvent(QShowEvent* e) override;
|
||||
|
||||
private:
|
||||
void StartUpdate();
|
||||
|
||||
Frame* buffer_;
|
||||
|
||||
QVector<double> red_val_;
|
||||
|
||||
QVector<double> green_val_;
|
||||
|
||||
QVector<double> blue_val_;
|
||||
|
||||
HistogramScopeWorker worker_;
|
||||
|
||||
private slots:
|
||||
void FinishedProcessing(QVector<double> red, QVector<double> green, QVector<double> blue);
|
||||
//virtual void DrawScope() override;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
# 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/>.
|
||||
|
||||
set(OLIVE_SOURCES
|
||||
${OLIVE_SOURCES}
|
||||
widget/scope/scopebase/scopebase.h
|
||||
widget/scope/scopebase/scopebase.cpp
|
||||
PARENT_SCOPE
|
||||
)
|
||||
@@ -0,0 +1,163 @@
|
||||
/***
|
||||
|
||||
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 "scopebase.h"
|
||||
|
||||
#include "render/backend/opengl/openglrenderfunctions.h"
|
||||
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
|
||||
ScopeBase::ScopeBase(QWidget* parent) :
|
||||
ManagedDisplayWidget(parent),
|
||||
buffer_(nullptr)
|
||||
{
|
||||
EnableDefaultContextMenu();
|
||||
}
|
||||
|
||||
ScopeBase::~ScopeBase()
|
||||
{
|
||||
CleanUp();
|
||||
|
||||
if (context()) {
|
||||
disconnect(context(), &QOpenGLContext::aboutToBeDestroyed, this, &ScopeBase::CleanUp);
|
||||
}
|
||||
}
|
||||
|
||||
void ScopeBase::SetBuffer(Frame *frame)
|
||||
{
|
||||
buffer_ = frame;
|
||||
|
||||
UploadTextureFromBuffer();
|
||||
}
|
||||
|
||||
void ScopeBase::showEvent(QShowEvent* e)
|
||||
{
|
||||
ManagedDisplayWidget::showEvent(e);
|
||||
|
||||
UploadTextureFromBuffer();
|
||||
}
|
||||
|
||||
OpenGLShaderPtr ScopeBase::CreateShader()
|
||||
{
|
||||
return OpenGLShader::CreateDefault();
|
||||
}
|
||||
|
||||
void ScopeBase::DrawScope()
|
||||
{
|
||||
managed_tex().Bind();
|
||||
|
||||
OpenGLRenderFunctions::Blit(pipeline());
|
||||
|
||||
managed_tex().Release();
|
||||
}
|
||||
|
||||
OpenGLShaderPtr ScopeBase::pipeline()
|
||||
{
|
||||
return pipeline_;
|
||||
}
|
||||
|
||||
OpenGLTexture &ScopeBase::managed_tex()
|
||||
{
|
||||
return managed_tex_;
|
||||
}
|
||||
|
||||
void ScopeBase::UploadTextureFromBuffer()
|
||||
{
|
||||
if (!isVisible()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (buffer_) {
|
||||
makeCurrent();
|
||||
|
||||
if (!texture_.IsCreated()
|
||||
|| texture_.width() != buffer_->width()
|
||||
|| texture_.height() != buffer_->height()
|
||||
|| texture_.format() != buffer_->format()) {
|
||||
texture_.Destroy();
|
||||
managed_tex_.Destroy();
|
||||
|
||||
texture_.Create(context(), buffer_);
|
||||
managed_tex_.Create(context(), buffer_->video_params());
|
||||
} else {
|
||||
texture_.Upload(buffer_);
|
||||
}
|
||||
|
||||
doneCurrent();
|
||||
}
|
||||
|
||||
update();
|
||||
}
|
||||
|
||||
void ScopeBase::CleanUp()
|
||||
{
|
||||
makeCurrent();
|
||||
|
||||
pipeline_ = nullptr;
|
||||
texture_.Destroy();
|
||||
managed_tex_.Destroy();
|
||||
framebuffer_.Destroy();
|
||||
|
||||
doneCurrent();
|
||||
}
|
||||
|
||||
void ScopeBase::initializeGL()
|
||||
{
|
||||
ManagedDisplayWidget::initializeGL();
|
||||
|
||||
pipeline_ = CreateShader();
|
||||
|
||||
framebuffer_.Create(context());
|
||||
|
||||
connect(context(), &QOpenGLContext::aboutToBeDestroyed, this, &ScopeBase::CleanUp, Qt::DirectConnection);
|
||||
|
||||
UploadTextureFromBuffer();
|
||||
}
|
||||
|
||||
void ScopeBase::paintGL()
|
||||
{
|
||||
QOpenGLFunctions* f = context()->functions();
|
||||
|
||||
f->glClearColor(0, 0, 0, 0);
|
||||
f->glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
if (buffer_ && pipeline() && texture_.IsCreated()) {
|
||||
// Convert reference frame to display space
|
||||
framebuffer_.Attach(&managed_tex_);
|
||||
framebuffer_.Bind();
|
||||
|
||||
texture_.Bind();
|
||||
|
||||
f->glViewport(0, 0, texture_.width(), texture_.height());
|
||||
|
||||
color_service()->ProcessOpenGL();
|
||||
|
||||
texture_.Release();
|
||||
|
||||
framebuffer_.Release();
|
||||
framebuffer_.Detach();
|
||||
|
||||
f->glViewport(0, 0, width(), height());
|
||||
|
||||
DrawScope();
|
||||
}
|
||||
}
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
@@ -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 SCOPEBASE_H
|
||||
#define SCOPEBASE_H
|
||||
|
||||
#include "codec/frame.h"
|
||||
#include "render/backend/opengl/openglcolorprocessor.h"
|
||||
#include "render/backend/opengl/openglframebuffer.h"
|
||||
#include "render/backend/opengl/openglshader.h"
|
||||
#include "render/backend/opengl/opengltexture.h"
|
||||
#include "widget/manageddisplay/manageddisplay.h"
|
||||
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
|
||||
class ScopeBase : public ManagedDisplayWidget
|
||||
{
|
||||
public:
|
||||
ScopeBase(QWidget* parent = nullptr);
|
||||
|
||||
virtual ~ScopeBase() override;
|
||||
|
||||
public slots:
|
||||
void SetBuffer(Frame* frame);
|
||||
|
||||
protected:
|
||||
virtual void initializeGL() override;
|
||||
|
||||
virtual void paintGL() override;
|
||||
|
||||
virtual void showEvent(QShowEvent* e) override;
|
||||
|
||||
virtual OpenGLShaderPtr CreateShader();
|
||||
|
||||
virtual void DrawScope();
|
||||
|
||||
OpenGLShaderPtr pipeline();
|
||||
|
||||
OpenGLTexture& managed_tex();
|
||||
|
||||
private:
|
||||
void UploadTextureFromBuffer();
|
||||
|
||||
OpenGLShaderPtr pipeline_;
|
||||
|
||||
OpenGLTexture texture_;
|
||||
|
||||
OpenGLTexture managed_tex_;
|
||||
|
||||
OpenGLFramebuffer framebuffer_;
|
||||
|
||||
Frame* buffer_;
|
||||
|
||||
private slots:
|
||||
void CleanUp();
|
||||
|
||||
};
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
|
||||
#endif // SCOPEBASE_H
|
||||
@@ -32,59 +32,24 @@
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
|
||||
WaveformScope::WaveformScope(QWidget* parent) :
|
||||
ManagedDisplayWidget(parent),
|
||||
buffer_(nullptr)
|
||||
ScopeBase(parent)
|
||||
{
|
||||
EnableDefaultContextMenu();
|
||||
}
|
||||
|
||||
WaveformScope::~WaveformScope()
|
||||
OpenGLShaderPtr WaveformScope::CreateShader()
|
||||
{
|
||||
CleanUp();
|
||||
OpenGLShaderPtr pipeline = OpenGLShader::Create();
|
||||
|
||||
if (context()) {
|
||||
disconnect(context(), &QOpenGLContext::aboutToBeDestroyed, this, &WaveformScope::CleanUp);
|
||||
}
|
||||
pipeline->create();
|
||||
pipeline->addShaderFromSourceCode(QOpenGLShader::Vertex, OpenGLShader::CodeDefaultVertex());
|
||||
pipeline->addShaderFromSourceCode(QOpenGLShader::Fragment, Node::ReadFileAsString(":/shaders/rgbwaveform.frag"));
|
||||
pipeline->link();
|
||||
|
||||
return pipeline;
|
||||
}
|
||||
|
||||
void WaveformScope::SetBuffer(Frame *frame)
|
||||
void WaveformScope::DrawScope()
|
||||
{
|
||||
buffer_ = frame;
|
||||
|
||||
UploadTextureFromBuffer();
|
||||
}
|
||||
|
||||
void WaveformScope::showEvent(QShowEvent* e)
|
||||
{
|
||||
ManagedDisplayWidget::showEvent(e);
|
||||
|
||||
UploadTextureFromBuffer();
|
||||
}
|
||||
|
||||
void WaveformScope::initializeGL()
|
||||
{
|
||||
ManagedDisplayWidget::initializeGL();
|
||||
|
||||
pipeline_ = OpenGLShader::Create();
|
||||
pipeline_->create();
|
||||
pipeline_->addShaderFromSourceCode(QOpenGLShader::Vertex, OpenGLShader::CodeDefaultVertex());
|
||||
pipeline_->addShaderFromSourceCode(QOpenGLShader::Fragment, Node::ReadFileAsString(":/shaders/rgbwaveform.frag"));
|
||||
pipeline_->link();
|
||||
|
||||
framebuffer_.Create(context());
|
||||
|
||||
connect(context(), &QOpenGLContext::aboutToBeDestroyed, this, &WaveformScope::CleanUp, Qt::DirectConnection);
|
||||
|
||||
UploadTextureFromBuffer();
|
||||
}
|
||||
|
||||
void WaveformScope::paintGL()
|
||||
{
|
||||
QOpenGLFunctions* f = context()->functions();
|
||||
|
||||
f->glClearColor(0, 0, 0, 0);
|
||||
f->glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
float waveform_scale = 0.80f;
|
||||
float waveform_dim_x = width() * waveform_scale;
|
||||
float waveform_dim_y = height() * waveform_scale;
|
||||
@@ -93,59 +58,40 @@ void WaveformScope::paintGL()
|
||||
float waveform_end_dim_x = width() - waveform_start_dim_x;
|
||||
float waveform_end_dim_y = height() - waveform_start_dim_y;
|
||||
|
||||
if (buffer_ && pipeline_ && texture_.IsCreated()) {
|
||||
// Convert reference frame to display space
|
||||
framebuffer_.Attach(&managed_tex_);
|
||||
framebuffer_.Bind();
|
||||
// Draw waveform through shader
|
||||
pipeline()->bind();
|
||||
pipeline()->setUniformValue("ove_resolution", managed_tex().width(), managed_tex().height());
|
||||
pipeline()->setUniformValue("ove_viewport", width(), height());
|
||||
GLfloat luma[3] = {0.0, 0.0, 0.0};
|
||||
color_manager()->GetDefaultLumaCoefs(luma);
|
||||
pipeline()->setUniformValue("luma_coeffs", luma[0], luma[1], luma[2]);
|
||||
|
||||
texture_.Bind();
|
||||
// Scale of the waveform relative to the viewport surface.
|
||||
pipeline()->setUniformValue("waveform_scale", waveform_scale);
|
||||
pipeline()->setUniformValue(
|
||||
"waveform_dims", waveform_dim_x, waveform_dim_y);
|
||||
|
||||
f->glViewport(0, 0, texture_.width(), texture_.height());
|
||||
pipeline()->setUniformValue(
|
||||
"waveform_region",
|
||||
waveform_start_dim_x, waveform_start_dim_y,
|
||||
waveform_end_dim_x, waveform_end_dim_y);
|
||||
|
||||
color_service()->ProcessOpenGL();
|
||||
float waveform_start_uv_x = waveform_start_dim_x / width();
|
||||
float waveform_start_uv_y = waveform_start_dim_y / height();
|
||||
float waveform_end_uv_x = waveform_end_dim_x / width();
|
||||
float waveform_end_uv_y = waveform_end_dim_y / height();
|
||||
pipeline()->setUniformValue(
|
||||
"waveform_uv",
|
||||
waveform_start_uv_x, waveform_start_uv_y,
|
||||
waveform_end_uv_x, waveform_end_uv_y);
|
||||
|
||||
texture_.Release();
|
||||
pipeline()->release();
|
||||
|
||||
framebuffer_.Release();
|
||||
framebuffer_.Detach();
|
||||
managed_tex().Bind();
|
||||
|
||||
// Draw waveform through shader
|
||||
pipeline_->bind();
|
||||
pipeline_->setUniformValue("ove_resolution", texture_.width(), texture_.height());
|
||||
pipeline_->setUniformValue("ove_viewport", width(), height());
|
||||
GLfloat luma[3] = {0.0, 0.0, 0.0};
|
||||
color_manager()->GetDefaultLumaCoefs(luma);
|
||||
pipeline_->setUniformValue("luma_coeffs", luma[0], luma[1], luma[2]);
|
||||
OpenGLRenderFunctions::Blit(pipeline());
|
||||
|
||||
// Scale of the waveform relative to the viewport surface.
|
||||
pipeline_->setUniformValue("waveform_scale", waveform_scale);
|
||||
pipeline_->setUniformValue(
|
||||
"waveform_dims", waveform_dim_x, waveform_dim_y);
|
||||
|
||||
pipeline_->setUniformValue(
|
||||
"waveform_region",
|
||||
waveform_start_dim_x, waveform_start_dim_y,
|
||||
waveform_end_dim_x, waveform_end_dim_y);
|
||||
|
||||
float waveform_start_uv_x = waveform_start_dim_x / width();
|
||||
float waveform_start_uv_y = waveform_start_dim_y / height();
|
||||
float waveform_end_uv_x = waveform_end_dim_x / width();
|
||||
float waveform_end_uv_y = waveform_end_dim_y / height();
|
||||
pipeline_->setUniformValue(
|
||||
"waveform_uv",
|
||||
waveform_start_uv_x, waveform_start_uv_y,
|
||||
waveform_end_uv_x, waveform_end_uv_y);
|
||||
|
||||
pipeline_->release();
|
||||
|
||||
f->glViewport(0, 0, width(), height());
|
||||
|
||||
managed_tex_.Bind();
|
||||
|
||||
OpenGLRenderFunctions::Blit(pipeline_);
|
||||
|
||||
managed_tex_.Release();
|
||||
}
|
||||
managed_tex().Release();
|
||||
|
||||
// Draw line overlays
|
||||
QPainter p(this);
|
||||
@@ -179,44 +125,4 @@ void WaveformScope::paintGL()
|
||||
p.drawLines(ire_lines);
|
||||
}
|
||||
|
||||
void WaveformScope::UploadTextureFromBuffer()
|
||||
{
|
||||
if (!isVisible()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (buffer_) {
|
||||
makeCurrent();
|
||||
|
||||
if (!texture_.IsCreated()
|
||||
|| texture_.width() != buffer_->width()
|
||||
|| texture_.height() != buffer_->height()
|
||||
|| texture_.format() != buffer_->format()) {
|
||||
texture_.Destroy();
|
||||
managed_tex_.Destroy();
|
||||
|
||||
texture_.Create(context(), buffer_);
|
||||
managed_tex_.Create(context(), buffer_->video_params());
|
||||
} else {
|
||||
texture_.Upload(buffer_);
|
||||
}
|
||||
|
||||
doneCurrent();
|
||||
}
|
||||
|
||||
update();
|
||||
}
|
||||
|
||||
void WaveformScope::CleanUp()
|
||||
{
|
||||
makeCurrent();
|
||||
|
||||
pipeline_ = nullptr;
|
||||
texture_.Destroy();
|
||||
managed_tex_.Destroy();
|
||||
framebuffer_.Destroy();
|
||||
|
||||
doneCurrent();
|
||||
}
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
|
||||
@@ -21,48 +21,20 @@
|
||||
#ifndef WAVEFORMSCOPE_H
|
||||
#define WAVEFORMSCOPE_H
|
||||
|
||||
#include "codec/frame.h"
|
||||
#include "render/backend/opengl/openglcolorprocessor.h"
|
||||
#include "render/backend/opengl/openglframebuffer.h"
|
||||
#include "render/backend/opengl/openglshader.h"
|
||||
#include "render/backend/opengl/opengltexture.h"
|
||||
#include "widget/manageddisplay/manageddisplay.h"
|
||||
#include "widget/scope/scopebase/scopebase.h"
|
||||
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
|
||||
class WaveformScope : public ManagedDisplayWidget
|
||||
class WaveformScope : public ScopeBase
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
WaveformScope(QWidget* parent = nullptr);
|
||||
|
||||
virtual ~WaveformScope() override;
|
||||
|
||||
public slots:
|
||||
void SetBuffer(Frame* frame);
|
||||
|
||||
protected:
|
||||
virtual void initializeGL() override;
|
||||
virtual OpenGLShaderPtr CreateShader() override;
|
||||
|
||||
virtual void paintGL() override;
|
||||
|
||||
virtual void showEvent(QShowEvent* e) override;
|
||||
|
||||
private:
|
||||
void UploadTextureFromBuffer();
|
||||
|
||||
OpenGLShaderPtr pipeline_;
|
||||
|
||||
OpenGLTexture texture_;
|
||||
|
||||
OpenGLTexture managed_tex_;
|
||||
|
||||
OpenGLFramebuffer framebuffer_;
|
||||
|
||||
Frame* buffer_;
|
||||
|
||||
private slots:
|
||||
void CleanUp();
|
||||
virtual void DrawScope() override;
|
||||
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user