finished prototype of nodes providing a texture to a viewer

This commit is contained in:
itsmattkc
2019-07-13 03:13:59 -04:00
parent d76691a9ef
commit f2d11662c9
23 changed files with 383 additions and 68 deletions
+1
View File
@@ -16,6 +16,7 @@
add_subdirectory(generator)
add_subdirectory(output)
add_subdirectory(processor)
set(OLIVE_SOURCES
${OLIVE_SOURCES}
+32 -1
View File
@@ -1,14 +1,45 @@
#include "solid.h"
SolidGenerator::SolidGenerator(QObject *parent) :
Node(parent)
Node(parent),
texture_(nullptr)
{
texture_output_ = new NodeOutput(this);
texture_output_->set_data_type(NodeOutput::kTexture);
}
QString SolidGenerator::Name()
{
return tr("Solid");
}
QString SolidGenerator::Category()
{
return tr("Generator");
}
QString SolidGenerator::Description()
{
return tr("Generate a solid color.");
}
NodeOutput *SolidGenerator::texture_output()
{
return texture_output_;
}
void SolidGenerator::Process(const rational &time)
{
Q_UNUSED(time)
// FIXME: Test code
if (texture_ == nullptr) {
QImage img(1920, 1080, QImage::Format_RGBA8888_Premultiplied);
img.fill(Qt::red);
texture_ = new QOpenGLTexture(img);
}
texture_output_->set_value(texture_->textureId());
// End test code
}
+12
View File
@@ -1,17 +1,29 @@
#ifndef SOLIDGENERATOR_H
#define SOLIDGENERATOR_H
#include <QOpenGLTexture>
#include "node/node.h"
class SolidGenerator : public Node
{
Q_OBJECT
public:
SolidGenerator(QObject* parent = nullptr);
virtual QString Name() override;
virtual QString Category() override;
virtual QString Description() override;
NodeOutput* texture_output();
public slots:
virtual void Process(const rational &time) override;
private:
NodeOutput* texture_output_;
QOpenGLTexture* texture_;
};
#endif // SOLIDGENERATOR_H
+45
View File
@@ -24,3 +24,48 @@ Node::Node(QObject *parent) :
QObject(parent)
{
}
QString Node::Category()
{
// Return an empty category for any nodes that don't use one
return QString();
}
QString Node::Description()
{
// Return an empty string by default
return QString();
}
void Node::InvalidateCache(const rational &start_range, const rational &end_range)
{
Q_UNUSED(start_range)
Q_UNUSED(end_range)
/*
ParamList params = Parameters();
for (int i=0;i<params.size();i++) {
NodeParam* param = params.at(i);
if (param->type() == NodeParam::kOutput
&& param->) {
}
}
*/
}
Node::ParamList Node::Parameters()
{
const QObjectList& child_list = children();
ParamList params;
params.reserve(child_list.size());
for (int i=0;i<child_list.size();i++) {
params[i] = static_cast<NodeParam*>(child_list.at(i));
}
return params;
}
+14 -1
View File
@@ -23,14 +23,27 @@
#include <QObject>
#include "node/param.h"
#include "node/input.h"
#include "node/output.h"
#include "rational.h"
class Node : public QObject
{
Q_OBJECT
public:
Node(QObject* parent = nullptr);
virtual QString Name() = 0;
virtual QString Category();
virtual QString Description();
virtual void InvalidateCache(const rational& start_range, const rational& end_range);
using ParamList = QList<NodeParam *>;
ParamList Parameters();
public slots:
virtual void Process(const rational& time) = 0;
};
+52 -1
View File
@@ -1,6 +1,57 @@
#include "viewer.h"
#include "panel/panelfocusmanager.h"
ViewerOutput::ViewerOutput(QObject* parent) :
Node(parent)
Node(parent),
attached_viewer_(nullptr)
{
texture_input_ = new NodeInput(this);
texture_input_->add_data_input(NodeInput::kTexture);
}
QString ViewerOutput::Name()
{
return tr("Viewer");
}
QString ViewerOutput::Category()
{
return tr("Output");
}
QString ViewerOutput::Description()
{
return tr("Interface between a Viewer panel and the node system.");
}
NodeInput *ViewerOutput::texture_input()
{
return texture_input_;
}
void ViewerOutput::Process(const rational &time)
{
if (attached_viewer_ != nullptr) {
// Get the texture from whatever Node is currently connected (usually a Renderer of some kind)
GLuint current_texture = texture_input_->get_value(time).value<GLuint>();
// Send the texture to the Viewer
attached_viewer_->SetTexture(current_texture);
}
}
void ViewerOutput::AttachViewer(ViewerPanel *viewer)
{
// Disconnect old viewer if there's one attached
if (attached_viewer_ != nullptr) {
disconnect(attached_viewer_, SIGNAL(TimeChanged(const rational&)), this, SLOT(Process(const rational&)));
}
// FIXME: Currently this attaches to ViewerPanels, but should it attached to Viewers instead?
attached_viewer_ = viewer;
if (attached_viewer_ != nullptr) {
connect(attached_viewer_, SIGNAL(TimeChanged(const rational&)), this, SLOT(Process(const rational&)));
}
}
+15
View File
@@ -2,14 +2,29 @@
#define VIEWER_H
#include "node/node.h"
#include "panel/viewer/viewer.h"
class ViewerOutput : public Node
{
Q_OBJECT
public:
ViewerOutput(QObject* parent = nullptr);
virtual QString Name() override;
virtual QString Category() override;
virtual QString Description() override;
NodeInput* texture_input();
void AttachViewer(ViewerPanel* viewer);
public slots:
virtual void Process(const rational &time) override;
private:
NodeInput* texture_input_;
ViewerPanel* attached_viewer_;
};
#endif // VIEWER_H
@@ -14,11 +14,9 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
add_subdirectory(renderer)
set(OLIVE_SOURCES
${OLIVE_SOURCES}
render/renderer/renderer.h
render/renderer/renderer.cpp
render/renderer/rendererthread.h
render/renderer/rendererthread.cpp
PARENT_SCOPE
)
@@ -0,0 +1,24 @@
# 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}
node/processor/renderer/renderer.h
node/processor/renderer/renderer.cpp
node/processor/renderer/rendererthread.h
node/processor/renderer/rendererthread.cpp
PARENT_SCOPE
)
@@ -20,13 +20,29 @@
#include "renderer.h"
Renderer::Renderer() :
RendererProcessor::RendererProcessor(QObject *parent) :
Node(parent),
started_(false)
{
}
void Renderer::Start()
QString RendererProcessor::Name()
{
return tr("Renderer");
}
QString RendererProcessor::Category()
{
return tr("Processor");
}
QString RendererProcessor::Description()
{
return tr("A multi-threaded OpenGL hardware-accelerated node compositor.");
}
void RendererProcessor::Start()
{
if (started_) {
return;
@@ -42,7 +58,7 @@ void Renderer::Start()
started_ = true;
}
void Renderer::Stop()
void RendererProcessor::Stop()
{
if (!started_) {
return;
@@ -58,13 +74,7 @@ void Renderer::Stop()
threads_.clear();
}
/*RendererThread *Renderer::CurrentThread()
RendererThread *RendererProcessor::CurrentThread()
{
for (int i=0;i<threads_.size();i++) {
if (threads_.at(i) == QThread::currentThread()) {
return threads_.at(i);
}
}
return nullptr;
}*/
return dynamic_cast<RendererThread*>(QThread::currentThread());
}
+87
View File
@@ -0,0 +1,87 @@
/***
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 RENDERER_H
#define RENDERER_H
#include "node/node.h"
#include "rendererthread.h"
class RendererProcessor : public Node
{
Q_OBJECT
public:
/**
* @brief Renderer Constructor
*
* Constructing a Renderer object will not start any threads/backend on its own. Use Start() to do this and Stop()
* when the Renderer is about to be destroyed.
*/
RendererProcessor(QObject* parent = nullptr);
virtual QString Name() override;
virtual QString Category() override;
virtual QString Description() override;
/**
* @brief Set parameters of the Renderer
*
* The Renderer owns the buffers that are used in the rendering process and this function sets the kind of buffers
* to use. The Renderer must be stopped when calling this function.
*
* @param width
*
* Buffer width
*
* @param height
*
* Buffer height
*
* @param format
*
* Buffer pixel format
*/
void SetParameters(const int& width, const int& height, const olive::PixelFormat& format);
/**
* @brief Allocate and start the multithreaded backend
*/
void Start();
/**
* @brief Terminate and deallocate the multithreaded backend
*/
void Stop();
/**
* @brief Return current instance of a RenderThread (or nullptr if there is none)
*
* This function attempts a dynamic_cast on QThread::currentThread() to RendererThread, which will return nullptr if
* the cast fails (e.g. if this function is called from the main thread rather than a RendererThread).
*/
static RendererThread* CurrentThread();
private:
QVector<RendererThread*> threads_;
bool started_;
};
#endif // RENDERER_H
+8 -4
View File
@@ -20,21 +20,25 @@
#include "viewer.h"
#include "widget/viewer/viewer.h"
ViewerPanel::ViewerPanel(QWidget *parent) :
PanelWidget(parent)
{
// QObject system handles deleting this
ViewerWidget* viewer = new ViewerWidget(this);
viewer_ = new ViewerWidget(this);
connect(viewer_, SIGNAL(TimeChanged(const rational&)), this, SIGNAL(TimeChanged(const rational&)));
// Set ViewerWidget as the central widget
setWidget(viewer);
setWidget(viewer_);
// Set strings
Retranslate();
}
void ViewerPanel::SetTexture(GLuint tex)
{
viewer_->SetTexture(tex);
}
void ViewerPanel::changeEvent(QEvent *e)
{
if (e->type() == QEvent::LanguageChange) {
+18
View File
@@ -21,7 +21,10 @@
#ifndef VIEWER_PANEL_H
#define VIEWER_PANEL_H
#include <QOpenGLFunctions>
#include "widget/panel/panel.h"
#include "widget/viewer/viewer.h"
/**
* @brief Dockable wrapper around a ViewerWidget
@@ -31,11 +34,26 @@ class ViewerPanel : public PanelWidget {
public:
ViewerPanel(QWidget* parent);
public slots:
/**
* @brief Set the texture to draw and draw it
*
* Wrapper function for Viewer::SetTexture().
*
* @param tex
*/
void SetTexture(GLuint tex);
protected:
virtual void changeEvent(QEvent* e) override;
signals:
void TimeChanged(const rational&);
private:
void Retranslate();
ViewerWidget* viewer_;
};
#endif // VIEWER_PANEL_H
-1
View File
@@ -15,7 +15,6 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
add_subdirectory(gl)
add_subdirectory(renderer)
set(OLIVE_SOURCES
${OLIVE_SOURCES}
-43
View File
@@ -1,43 +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 RENDERER_H
#define RENDERER_H
#include "render/renderer/rendererthread.h"
class Renderer
{
public:
Renderer();
void Start();
void Stop();
//RendererThread* CurrentThread();
private:
QVector<RendererThread*> threads_;
bool started_;
};
#endif // RENDERER_H
@@ -64,26 +64,31 @@ PlaybackControls::PlaybackControls(QWidget *parent) :
QPushButton* go_to_start_btn = new QPushButton();
go_to_start_btn->setIcon(olive::icon::GoToStart);
lower_middle_layout->addWidget(go_to_start_btn);
connect(go_to_start_btn, SIGNAL(clicked(bool)), this, SIGNAL(BeginClicked()));
// Prev Frame Button
QPushButton* prev_frame_btn = new QPushButton();
prev_frame_btn->setIcon(olive::icon::PrevFrame);
lower_middle_layout->addWidget(prev_frame_btn);
connect(prev_frame_btn, SIGNAL(clicked(bool)), this, SIGNAL(PrevFrameClicked()));
// Play/Pause Button
QPushButton* play_btn = new QPushButton();
play_btn->setIcon(olive::icon::Play);
lower_middle_layout->addWidget(play_btn);
connect(play_btn, SIGNAL(clicked(bool)), this, SIGNAL(PlayClicked()));
// Next Frame Button
QPushButton* next_frame_btn = new QPushButton();
next_frame_btn->setIcon(olive::icon::NextFrame);
lower_middle_layout->addWidget(next_frame_btn);
connect(next_frame_btn, SIGNAL(clicked(bool)), this, SIGNAL(NextFrameClicked()));
// Go To End Button
QPushButton* go_to_end_btn = new QPushButton();
go_to_end_btn->setIcon(olive::icon::GoToEnd);
lower_middle_layout->addWidget(go_to_end_btn);
connect(go_to_end_btn, SIGNAL(clicked(bool)), this, SIGNAL(EndClicked()));
lower_middle_layout->addStretch();
@@ -31,6 +31,7 @@
*/
class PlaybackControls : public QWidget
{
Q_OBJECT
public:
PlaybackControls(QWidget* parent);
+14
View File
@@ -40,4 +40,18 @@ ViewerWidget::ViewerWidget(QWidget *parent) :
controls_->SetTimecodeEnabled(true);
controls_->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Maximum);
layout->addWidget(controls_);
// FIXME: Test code
connect(controls_, SIGNAL(PlayClicked()), this, SLOT(TemporaryTestFunction()));
// End test code
}
void ViewerWidget::SetTexture(GLuint tex)
{
gl_widget_->SetTexture(tex);
}
void ViewerWidget::TemporaryTestFunction()
{
emit TimeChanged(69);
}
+16
View File
@@ -25,6 +25,7 @@
#include <QPushButton>
#include <QLabel>
#include "rational.h"
#include "viewerglwidget.h"
#include "widget/playbackcontrols/playbackcontrols.h"
@@ -39,10 +40,25 @@ public:
void SetPlaybackControlsEnabled(bool enabled);
public slots:
/**
* @brief Set the texture to draw and draw it
*
* Wrapper function for ViewerGLWidget::SetTexture().
*
* @param tex
*/
void SetTexture(GLuint tex);
signals:
void TimeChanged(const rational&);
private:
ViewerGLWidget* gl_widget_;
PlaybackControls* controls_;
private slots:
void TemporaryTestFunction();
};
#endif // VIEWER_WIDGET_H
+3 -1
View File
@@ -52,14 +52,16 @@ public:
*/
ViewerGLWidget(QWidget* parent);
public slots:
/**
* @brief Set the texture to draw and draw it
*
* Use this function
* Use this function to update the viewer.
*
* @param tex
*/
void SetTexture(GLuint tex);
protected:
/**
* @brief Initialize function to set up the OpenGL context upon its construction
+12
View File
@@ -32,6 +32,11 @@
// Main menu bar
#include "mainmenu.h"
// FIXME: Test code
#include "node/output/viewer/viewer.h"
#include "node/generator/solid/solid.h"
// End test code
olive::MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent)
{
@@ -73,4 +78,11 @@ void olive::MainWindow::ProjectOpen(Project* p)
TimelinePanel* timeline_panel = new TimelinePanel(this);
addDockWidget(Qt::BottomDockWidgetArea, timeline_panel);
// FIXME: Test code
ViewerOutput* vo = new ViewerOutput(this);
vo->AttachViewer(viewer_panel2);
SolidGenerator* sg = new SolidGenerator(this);
NodeInput::ConnectEdge(sg->texture_output(), vo->texture_input());
// End test code
}