Files
oak-editor/app/render/backend/opengl/openglworker.cpp
T
itsmattkc 16ac2fc0e1 sweeping node graph changes for new rendering pipeline
The new rendering pipeline strives to simplify the nodes themselves as much
as possible and move much of the logic to an external rendering engine. This
change removes all of the responsibilities that no longer belong to the
nodes themselves and will soon be folded into the renderer.
2019-11-02 01:39:37 +11:00

118 lines
2.6 KiB
C++

#include "openglworker.h"
#include "node/node.h"
OpenGLWorker::OpenGLWorker(QOpenGLContext *share_ctx, QObject *parent) :
QObject(parent),
share_ctx_(share_ctx),
ctx_(nullptr),
functions_(nullptr)
{
surface_.create();
}
OpenGLWorker::~OpenGLWorker()
{
surface_.destroy();
}
bool OpenGLWorker::IsStarted()
{
return ctx_ != nullptr;
}
void OpenGLWorker::SetParameters(const VideoRenderingParams &video_params)
{
video_params_ = video_params;
}
void OpenGLWorker::Init()
{
// Create context object
ctx_ = new QOpenGLContext();
// Set share context
ctx_->setShareContext(share_ctx_);
// Create OpenGL context (automatically destroys any existing if there is one)
if (!ctx_->create()) {
qWarning() << "Failed to create OpenGL context in thread" << thread();
Close();
return;
}
ctx_->moveToThread(this->thread());
qDebug() << "Processor initialized in thread" << thread() << "- context is in" << ctx_->thread();
// The rest of the initialization needs to occur in the other thread, so we signal for it to start
QMetaObject::invokeMethod(this, "FinishInit", Qt::QueuedConnection);
}
void OpenGLWorker::Close()
{
buffer_.Destroy();
functions_ = nullptr;
delete ctx_;
}
void OpenGLWorker::Render(const NodeDependency &path)
{
NodeOutput* output = path.node();
Node* node = output->parent();
QList<Node*> all_deps = node->GetDependencies();
// Lock all Nodes to prevent UI changes during this render
foreach (Node* dep, all_deps) {
dep->LockUserInput();
}
node->LockUserInput();
// FIXME: Write traversal code
// Start OpenGL flushing now while we do clean up work on the CPU
functions_->glFlush();
// Unlock all Nodes so changes can be made again
foreach (Node* dep, all_deps) {
dep->UnlockUserInput();
}
node->UnlockUserInput();
// Now we need the texture done so we call glFinish()
functions_->glFinish();
}
void OpenGLWorker::UpdateViewportFromParams()
{
if (functions_ != nullptr && video_params_.is_valid()) {
functions_->glViewport(0, 0, video_params_.effective_width(), video_params_.effective_height());
}
}
void OpenGLWorker::FinishInit()
{
// Make context current on that surface
if (!ctx_->makeCurrent(&surface_)) {
qWarning() << "Failed to makeCurrent() on offscreen surface in thread" << thread();
return;
}
// Store OpenGL functions instance
functions_ = ctx_->functions();
// Set up OpenGL parameters as necessary
functions_->glEnable(GL_BLEND);
UpdateViewportFromParams();
buffer_.Create(ctx_);
qDebug() << "Context in" << ctx_->thread() << "successfully finished";
}
void OpenGLWorker::RenderAsSibling(const NodeDependency &)
{
}