merged all drawing functions into a single shader processing function
This commit is contained in:
@@ -140,10 +140,6 @@ void OpenGLRenderer::Destroy()
|
||||
// Delete framebuffer
|
||||
functions_->glDeleteFramebuffers(1, &framebuffer_);
|
||||
|
||||
// Delete all shaders
|
||||
qDeleteAll(shader_cache_);
|
||||
shader_cache_.clear();
|
||||
|
||||
// Delete context if it belongs to us
|
||||
if (context_->parent() == this) {
|
||||
delete context_;
|
||||
@@ -171,8 +167,6 @@ void OpenGLRenderer::AttachTextureAsDestination(Renderer::Texture* texture)
|
||||
GL_TEXTURE_2D,
|
||||
texture->id().value<GLuint>(),
|
||||
0);
|
||||
|
||||
SetViewport(texture->width(), texture->height());
|
||||
}
|
||||
|
||||
void OpenGLRenderer::DetachTextureAsDestination()
|
||||
@@ -221,6 +215,8 @@ QVariant OpenGLRenderer::CreateNativeShader(ShaderCode code)
|
||||
goto error;
|
||||
}
|
||||
|
||||
qDebug() << "Shader created successfully";
|
||||
|
||||
return Node::PtrToValue(program);
|
||||
|
||||
error:
|
||||
@@ -281,51 +277,14 @@ void OpenGLRenderer::DownloadFromTexture(Texture* texture, void *data, int lines
|
||||
functions_->glBindTexture(GL_TEXTURE_2D, current_tex);
|
||||
}
|
||||
|
||||
Renderer::TexturePtr OpenGLRenderer::ProcessShader(const Node *node, ShaderJob job, VideoParams params)
|
||||
void OpenGLRenderer::Blit(QVariant s, ShaderJob job, Renderer::Texture *destination, VideoParams destination_params)
|
||||
{
|
||||
// If this node is iterative, we'll pick up which input here
|
||||
GLuint iterative_input = 0;
|
||||
QList<GLuint> textures_to_bind;
|
||||
bool input_textures_have_alpha = false;
|
||||
|
||||
QString full_shader_id = QStringLiteral("%1:%2").arg(node->id(), job.GetShaderID());
|
||||
QOpenGLShaderProgram* shader = shader_cache_.value(full_shader_id);
|
||||
|
||||
if (!shader) {
|
||||
// Since we have shader code, compile it now
|
||||
ShaderCode code = node->GetShaderCode(job.GetShaderID());
|
||||
QString vert_code = code.vert_code();
|
||||
QString frag_code = code.frag_code();
|
||||
|
||||
if (frag_code.isEmpty() && vert_code.isEmpty()) {
|
||||
qWarning() << "No shader code found for" << node->id() << "- operation will be a no-op";
|
||||
}
|
||||
|
||||
if (frag_code.isEmpty()) {
|
||||
frag_code = Node::ReadFileAsString(QStringLiteral(":/shaders/default.frag"));
|
||||
}
|
||||
|
||||
if (vert_code.isEmpty()) {
|
||||
vert_code = Node::ReadFileAsString(QStringLiteral(":/shaders/default.vert"));
|
||||
}
|
||||
|
||||
shader = new QOpenGLShaderProgram(this);
|
||||
if (shader
|
||||
&& shader->create()
|
||||
&& shader->addShaderFromSourceCode(QOpenGLShader::Fragment, frag_code)
|
||||
&& shader->addShaderFromSourceCode(QOpenGLShader::Vertex, vert_code)
|
||||
&& shader->link()) {
|
||||
shader_cache_.insert(full_shader_id, shader);
|
||||
} else {
|
||||
qWarning() << "Failed to compile shader for" << node->id();
|
||||
shader = nullptr;
|
||||
}
|
||||
|
||||
if (!shader) {
|
||||
// Couldn't find or build the shader required
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
QOpenGLShaderProgram* shader = Node::ValueToPtr<QOpenGLShaderProgram>(s);
|
||||
|
||||
shader->bind();
|
||||
|
||||
@@ -338,28 +297,25 @@ Renderer::TexturePtr OpenGLRenderer::ProcessShader(const Node *node, ShaderJob j
|
||||
continue;
|
||||
}
|
||||
|
||||
// See if this value corresponds to an input (NOTE: it may not and this may be null)
|
||||
NodeInput* corresponding_input = node->GetInputWithID(it.key());
|
||||
|
||||
// This variable is used in the shader, let's set it
|
||||
const QVariant& value = it.value().data();
|
||||
const ShaderValue& value = it.value();
|
||||
|
||||
NodeParam::DataType data_type = (it.value().type() != NodeParam::kNone)
|
||||
? it.value().type()
|
||||
: corresponding_input->data_type();
|
||||
if (value.array) {
|
||||
qWarning() << "FIXME: Array support is currently a stub";
|
||||
}
|
||||
|
||||
switch (data_type) {
|
||||
switch (value.type) {
|
||||
case NodeInput::kInt:
|
||||
// kInt technically specifies a LongLong, but OpenGL doesn't support those. This may lead to
|
||||
// over/underflows if the number is large enough, but the likelihood of that is quite low.
|
||||
shader->setUniformValue(variable_location, value.toInt());
|
||||
shader->setUniformValue(variable_location, value.data.toInt());
|
||||
break;
|
||||
case NodeInput::kFloat:
|
||||
// kFloat technically specifies a double but as above, OpenGL doesn't support those.
|
||||
shader->setUniformValue(variable_location, value.toFloat());
|
||||
shader->setUniformValue(variable_location, value.data.toFloat());
|
||||
break;
|
||||
case NodeInput::kVec2:
|
||||
if (corresponding_input && corresponding_input->IsArray()) {
|
||||
/*if (corresponding_input && corresponding_input->IsArray()) {
|
||||
QVector<NodeValue> nv = value.value< QVector<NodeValue> >();
|
||||
QVector<QVector2D> a(nv.size());
|
||||
|
||||
@@ -374,41 +330,42 @@ Renderer::TexturePtr OpenGLRenderer::ProcessShader(const Node *node, ShaderJob j
|
||||
shader->setUniformValue(count_location, a.size());
|
||||
}
|
||||
} else {
|
||||
shader->setUniformValue(variable_location, value.value<QVector2D>());
|
||||
}
|
||||
|
||||
}*/
|
||||
shader->setUniformValue(variable_location, value.data.value<QVector2D>());
|
||||
break;
|
||||
case NodeInput::kVec3:
|
||||
shader->setUniformValue(variable_location, value.value<QVector3D>());
|
||||
shader->setUniformValue(variable_location, value.data.value<QVector3D>());
|
||||
break;
|
||||
case NodeInput::kVec4:
|
||||
shader->setUniformValue(variable_location, value.value<QVector4D>());
|
||||
shader->setUniformValue(variable_location, value.data.value<QVector4D>());
|
||||
break;
|
||||
case NodeInput::kMatrix:
|
||||
shader->setUniformValue(variable_location, value.value<QMatrix4x4>());
|
||||
shader->setUniformValue(variable_location, value.data.value<QMatrix4x4>());
|
||||
break;
|
||||
case NodeInput::kCombo:
|
||||
shader->setUniformValue(variable_location, value.value<int>());
|
||||
shader->setUniformValue(variable_location, value.data.value<int>());
|
||||
break;
|
||||
case NodeInput::kColor:
|
||||
{
|
||||
Color color = value.value<Color>();
|
||||
Color color = value.data.value<Color>();
|
||||
|
||||
shader->setUniformValue(variable_location, color.red(), color.green(), color.blue(), color.alpha());
|
||||
break;
|
||||
}
|
||||
case NodeInput::kBoolean:
|
||||
shader->setUniformValue(variable_location, value.toBool());
|
||||
shader->setUniformValue(variable_location, value.data.toBool());
|
||||
break;
|
||||
case NodeInput::kBuffer:
|
||||
case NodeInput::kTexture:
|
||||
{
|
||||
TexturePtr texture = value.value<TexturePtr>();
|
||||
TexturePtr texture = value.data.value<TexturePtr>();
|
||||
|
||||
// Set value to bound texture
|
||||
shader->setUniformValue(variable_location, textures_to_bind.size());
|
||||
|
||||
// If this texture binding is the iterative input, set it here
|
||||
if (corresponding_input && corresponding_input == job.GetIterativeInput()) {
|
||||
if (it.key() == job.GetIterativeInput()) {
|
||||
iterative_input = textures_to_bind.size();
|
||||
}
|
||||
|
||||
@@ -434,8 +391,8 @@ Renderer::TexturePtr OpenGLRenderer::ProcessShader(const Node *node, ShaderJob j
|
||||
|
||||
// Adjust virtual width by pixel aspect if necessary
|
||||
if (texture->params().pixel_aspect_ratio() != 1
|
||||
|| params.pixel_aspect_ratio() != 1) {
|
||||
double relative_pixel_aspect = texture->params().pixel_aspect_ratio().toDouble() / params.pixel_aspect_ratio().toDouble();
|
||||
|| destination_params.pixel_aspect_ratio() != 1) {
|
||||
double relative_pixel_aspect = texture->params().pixel_aspect_ratio().toDouble() / destination_params.pixel_aspect_ratio().toDouble();
|
||||
|
||||
adjusted_width = qRound(static_cast<double>(adjusted_width) * relative_pixel_aspect);
|
||||
}
|
||||
@@ -466,32 +423,13 @@ Renderer::TexturePtr OpenGLRenderer::ProcessShader(const Node *node, ShaderJob j
|
||||
}
|
||||
}
|
||||
|
||||
// Provide some standard args
|
||||
// Set ove_resolution to the destination to the "logical" resolution of the destination
|
||||
shader->setUniformValue("ove_resolution",
|
||||
static_cast<GLfloat>(params.width()),
|
||||
static_cast<GLfloat>(params.height()));
|
||||
static_cast<GLfloat>(destination_params.width()),
|
||||
static_cast<GLfloat>(destination_params.height()));
|
||||
|
||||
// Create the output textures
|
||||
int real_iteration_count;
|
||||
if (job.GetIterationCount() > 1 && job.GetIterativeInput()) {
|
||||
real_iteration_count = job.GetIterationCount();
|
||||
} else {
|
||||
real_iteration_count = 1;
|
||||
}
|
||||
|
||||
TexturePtr dst_refs[2];
|
||||
dst_refs[0] = CreateTexture(params);
|
||||
|
||||
// If this node requires multiple iterations, get a texture for it too
|
||||
if (real_iteration_count > 1) {
|
||||
dst_refs[1] = CreateTexture(params);
|
||||
}
|
||||
|
||||
// Some nodes use multiple iterations for optimization
|
||||
TexturePtr input_tex, output_tex;
|
||||
|
||||
// Set up OpenGL parameters as necessary
|
||||
functions_->glViewport(0, 0, params.effective_width(), params.effective_height());
|
||||
// Set the viewport to the "physical" resolution of the destination
|
||||
functions_->glViewport(0, 0, destination_params.effective_width(), destination_params.effective_height());
|
||||
|
||||
// Bind all textures
|
||||
for (int i=0; i<textures_to_bind.size(); i++) {
|
||||
@@ -516,30 +454,71 @@ Renderer::TexturePtr OpenGLRenderer::ProcessShader(const Node *node, ShaderJob j
|
||||
functions_->glVertexAttribPointer(tex_location, 2, GL_FLOAT, GL_FALSE, 0, nullptr);
|
||||
frag_vbo_.release();
|
||||
|
||||
// Some shaders optimize through multiple iterations which requires ping-ponging textures
|
||||
// - If there are only two iterations, we can just create one backend texture and then the
|
||||
// destination can be the second
|
||||
// - If there are more than two iterations, we need to ping pong back and forth between two
|
||||
// textures. We can still use the destination as the last iteration, but we'll need textures
|
||||
// for the iterative process.
|
||||
int real_iteration_count;
|
||||
if (job.GetIterationCount() > 1 && !job.GetIterativeInput().isEmpty()) {
|
||||
real_iteration_count = job.GetIterationCount();
|
||||
} else {
|
||||
real_iteration_count = 1;
|
||||
}
|
||||
|
||||
TexturePtr output_tex, input_tex;
|
||||
if (real_iteration_count > 1) {
|
||||
// Create one texture to bounce off
|
||||
output_tex = CreateTexture(destination_params);
|
||||
|
||||
if (real_iteration_count > 2) {
|
||||
// Create a second texture bounce off
|
||||
input_tex = CreateTexture(destination_params);
|
||||
}
|
||||
}
|
||||
|
||||
for (int iteration=0; iteration<real_iteration_count; iteration++) {
|
||||
// Set iteration number
|
||||
shader->setUniformValue("ove_iteration", iteration);
|
||||
|
||||
// Replace iterative input
|
||||
if (iteration == 0) {
|
||||
output_tex = dst_refs[0];
|
||||
if (iteration == real_iteration_count-1) {
|
||||
// This is the last iteration, draw to the destination
|
||||
if (destination) {
|
||||
// If we have a destination texture, draw to it
|
||||
AttachTextureAsDestination(destination);
|
||||
} else if (iteration > 0) {
|
||||
// Otherwise, if we were iterating before, detach texture now
|
||||
DetachTextureAsDestination();
|
||||
}
|
||||
} else {
|
||||
input_tex = dst_refs[(iteration+1)%2];
|
||||
output_tex = dst_refs[iteration%2];
|
||||
// Always draw to output_tex
|
||||
AttachTextureAsDestination(output_tex.get());
|
||||
|
||||
functions_->glActiveTexture(GL_TEXTURE0 + iterative_input);
|
||||
functions_->glBindTexture(GL_TEXTURE_2D, input_tex->id().value<GLuint>());
|
||||
PrepareInputTexture(job.GetBilinearFiltering());
|
||||
if (iteration > 0) {
|
||||
// If this is not the first iteration, replace the iterative texture with the one we
|
||||
// last drew
|
||||
functions_->glActiveTexture(GL_TEXTURE0 + iterative_input);
|
||||
functions_->glBindTexture(GL_TEXTURE_2D, input_tex->id().value<GLuint>());
|
||||
PrepareInputTexture(job.GetBilinearFiltering());
|
||||
}
|
||||
|
||||
// Swap so that the next iteration, the texture we draw now will be the input texture next
|
||||
std::swap(output_tex, input_tex);
|
||||
}
|
||||
|
||||
AttachTextureAsDestination(output_tex.get());
|
||||
|
||||
// Blit this texture through this shader
|
||||
functions_->glDrawArrays(GL_TRIANGLES, 0, blit_vertices.size() / 3);
|
||||
}
|
||||
|
||||
// Reset framebuffer to default
|
||||
DetachTextureAsDestination();
|
||||
if (destination) {
|
||||
// Reset framebuffer to default if we were drawing to a texture
|
||||
DetachTextureAsDestination();
|
||||
|
||||
// Set metadata for whether this texture has a meaningful alpha channel
|
||||
destination->set_has_meaningful_alpha((input_textures_have_alpha || job.GetAlphaChannelRequired()));
|
||||
}
|
||||
|
||||
// Release any textures we bound before
|
||||
for (int i=textures_to_bind.size()-1; i>=0; i--) {
|
||||
@@ -552,23 +531,9 @@ Renderer::TexturePtr OpenGLRenderer::ProcessShader(const Node *node, ShaderJob j
|
||||
|
||||
// Release shader
|
||||
shader->release();
|
||||
|
||||
output_tex->set_has_meaningful_alpha((input_textures_have_alpha || job.GetAlphaChannelRequired()));
|
||||
|
||||
return output_tex;
|
||||
}
|
||||
|
||||
void OpenGLRenderer::SetViewport(int width, int height)
|
||||
{
|
||||
functions_->glViewport(0, 0, width, height);
|
||||
}
|
||||
|
||||
void OpenGLRenderer::BlitColorManaged(ColorProcessorPtr color_processor, Texture *source, Renderer::Texture* destination)
|
||||
{
|
||||
qCritical() << "OpenGLRenderer::BlitColorMangaed is a stub!";
|
||||
}
|
||||
|
||||
void OpenGLRenderer::Blit(Renderer::Texture *source, QVariant shader, Renderer::ShaderUniformMap parameters, Renderer::Texture *destination)
|
||||
/*void OpenGLRenderer::Blit(Renderer::Texture *source, QVariant shader, Renderer::ShaderUniformMap parameters, Renderer::Texture *destination)
|
||||
{
|
||||
QOpenGLShaderProgram* program = Node::ValueToPtr<QOpenGLShaderProgram>(shader);
|
||||
|
||||
@@ -594,7 +559,7 @@ void OpenGLRenderer::Blit(Renderer::Texture *source, QVariant shader, Renderer::
|
||||
if (destination) {
|
||||
DetachTextureAsDestination();
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
GLint OpenGLRenderer::GetInternalFormat(PixelFormat::Format format)
|
||||
{
|
||||
|
||||
@@ -51,10 +51,6 @@ public slots:
|
||||
|
||||
virtual void ClearDestination(double r = 0.0, double g = 0.0, double b = 0.0, double a = 0.0) override;
|
||||
|
||||
virtual void AttachTextureAsDestination(OLIVE_NAMESPACE::Renderer::Texture* texture) override;
|
||||
|
||||
virtual void DetachTextureAsDestination() override;
|
||||
|
||||
virtual QVariant CreateNativeTexture(OLIVE_NAMESPACE::VideoParams param, void* data = nullptr, int linesize = 0) override;
|
||||
|
||||
virtual void DestroyNativeTexture(QVariant texture) override;
|
||||
@@ -67,21 +63,21 @@ public slots:
|
||||
|
||||
virtual void DownloadFromTexture(OLIVE_NAMESPACE::Renderer::Texture* texture, void* data, int linesize) override;
|
||||
|
||||
virtual TexturePtr ProcessShader(const OLIVE_NAMESPACE::Node* node,
|
||||
OLIVE_NAMESPACE::ShaderJob job,
|
||||
OLIVE_NAMESPACE::VideoParams params) override;
|
||||
|
||||
virtual void SetViewport(int width, int height) override;
|
||||
|
||||
virtual void BlitColorManaged(OLIVE_NAMESPACE::ColorProcessorPtr color_processor, OLIVE_NAMESPACE::Renderer::Texture* source, OLIVE_NAMESPACE::Renderer::Texture *destination = nullptr) override;
|
||||
|
||||
virtual void Blit(OLIVE_NAMESPACE::Renderer::Texture* source, QVariant shader, OLIVE_NAMESPACE::Renderer::ShaderUniformMap parameters, OLIVE_NAMESPACE::Renderer::Texture* destination = nullptr) override;
|
||||
protected slots:
|
||||
virtual void Blit(QVariant shader,
|
||||
OLIVE_NAMESPACE::ShaderJob job,
|
||||
OLIVE_NAMESPACE::Renderer::Texture* destination,
|
||||
OLIVE_NAMESPACE::VideoParams destination_params) override;
|
||||
|
||||
private:
|
||||
static GLint GetInternalFormat(PixelFormat::Format format);
|
||||
|
||||
static GLenum GetPixelType(PixelFormat::Format format);
|
||||
|
||||
void AttachTextureAsDestination(OLIVE_NAMESPACE::Renderer::Texture* texture);
|
||||
|
||||
void DetachTextureAsDestination();
|
||||
|
||||
void PrepareInputTexture(bool bilinear);
|
||||
|
||||
QOpenGLContext* context_;
|
||||
@@ -98,8 +94,6 @@ private:
|
||||
|
||||
GLuint framebuffer_;
|
||||
|
||||
QHash<QString, QOpenGLShaderProgram*> shader_cache_;
|
||||
|
||||
};
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
|
||||
@@ -20,6 +20,13 @@
|
||||
|
||||
#include "renderer.h"
|
||||
|
||||
#include <OpenColorIO/OpenColorIO.h>
|
||||
namespace OCIO = OCIO_NAMESPACE::v1;
|
||||
|
||||
#include <QFloat16>
|
||||
|
||||
#include "render/colormanager.h"
|
||||
|
||||
OLIVE_NAMESPACE_ENTER
|
||||
|
||||
Renderer::Renderer(QObject *parent) :
|
||||
@@ -39,4 +46,91 @@ Renderer::TexturePtr Renderer::CreateTexture(const VideoParams ¶m, void *dat
|
||||
return std::make_shared<Texture>(this, v, param);
|
||||
}
|
||||
|
||||
// copied from source code to OCIODisplay
|
||||
/*const int OCIO_LUT3D_EDGE_SIZE = 64;
|
||||
|
||||
const int OCIO_LUT3D_PIXEL_COUNT = OCIO_LUT3D_EDGE_SIZE*OCIO_LUT3D_EDGE_SIZE*OCIO_LUT3D_EDGE_SIZE;
|
||||
const int OCIO_LUT3D_ENTRY_COUNT = 3 * OCIO_LUT3D_PIXEL_COUNT;
|
||||
const int OCIO_LUT3D_ENTRY_COUNT_WITH_ALPHA = 4 * OCIO_LUT3D_PIXEL_COUNT;
|
||||
const int OCIO_LUT2D_EDGE_SIZE = 512;*/
|
||||
|
||||
void Renderer::BlitColorManaged(ColorProcessorPtr color_processor, TexturePtr source, Texture *destination)
|
||||
{
|
||||
/*ColorContext color_ctx;
|
||||
|
||||
if (color_cache_.contains(color_processor->id())) {
|
||||
color_ctx = color_cache_.value(color_processor->id());
|
||||
} else {
|
||||
// Generate OCIO color context
|
||||
|
||||
// Generate OCIO shader descriptor
|
||||
const char* ocio_func_name = "OCIODisplay";
|
||||
OCIO::GpuShaderDesc shader_desc;
|
||||
shader_desc.setLanguage(OCIO::GPU_LANGUAGE_GLSL_1_0);
|
||||
shader_desc.setFunctionName(ocio_func_name);
|
||||
shader_desc.setLut3DEdgeLen(OCIO_LUT3D_EDGE_SIZE);
|
||||
|
||||
// Generate LUT
|
||||
QVector<float> lut_data(OCIO_LUT3D_ENTRY_COUNT);
|
||||
color_processor->GetProcessor()->getGpuLut3D(lut_data.data(), shader_desc);
|
||||
|
||||
// Convert to half float RGBA
|
||||
QVector<qfloat16> texture_ready_lut_data(OCIO_LUT3D_ENTRY_COUNT_WITH_ALPHA);
|
||||
for (int i=0; i<OCIO_LUT3D_PIXEL_COUNT; i++) {
|
||||
texture_ready_lut_data[i*kRGBAChannels+0] = lut_data[i*kRGBChannels+0];
|
||||
texture_ready_lut_data[i*kRGBAChannels+1] = lut_data[i*kRGBChannels+1];
|
||||
texture_ready_lut_data[i*kRGBAChannels+2] = lut_data[i*kRGBChannels+2];
|
||||
texture_ready_lut_data[i*kRGBAChannels+3] = 1.0f;
|
||||
}
|
||||
|
||||
// Create LUT texture
|
||||
color_ctx.lut = CreateTexture(VideoParams(OCIO_LUT2D_EDGE_SIZE, OCIO_LUT2D_EDGE_SIZE, PixelFormat::PIX_FMT_RGBA32F),
|
||||
texture_ready_lut_data.data());
|
||||
|
||||
// Create shader
|
||||
QString frag_code;
|
||||
|
||||
frag_code.append(QStringLiteral("sampler2D texture;\n"
|
||||
"sampler2D lut;\n"
|
||||
"\n"
|
||||
"vec3 LUTLookup(sampler2D lut3d, vec3 in_coord)\n"
|
||||
"{\n"
|
||||
" return texture2D(lut3d, vec2());\n"
|
||||
"}\n"
|
||||
"\n"));
|
||||
|
||||
// Correct code for our GLSL set up
|
||||
QString ocio_code = color_processor->GetProcessor()->getGpuShaderText(shader_desc);
|
||||
ocio_code.replace(QStringLiteral("texture3D"), QStringLiteral("texture2D"));
|
||||
ocio_code.replace(QStringLiteral("sampler3D"), QStringLiteral("sampler2D"));
|
||||
|
||||
|
||||
|
||||
qDebug() << frag_code;
|
||||
|
||||
//qDebug() << "FIXME: GPU doesn't handle associated alpha yet";
|
||||
}*/
|
||||
|
||||
qDebug() << "BlitColorManaged is a partial stub";
|
||||
|
||||
QVariant shader = CreateNativeShader(ShaderCode(FileFunctions::ReadFileAsString(":/shaders/default.frag"), FileFunctions::ReadFileAsString(":/shaders/default.vert")));
|
||||
|
||||
ShaderJob job;
|
||||
job.InsertValue(QStringLiteral("ove_maintex"), ShaderValue(QVariant::fromValue(source), NodeParam::kTexture));
|
||||
|
||||
BlitToTexture(shader, job, destination);
|
||||
}
|
||||
|
||||
void Renderer::BlitColorManaged(ColorProcessorPtr color_processor, TexturePtr source, VideoParams params)
|
||||
{
|
||||
qDebug() << "BlitColorManaged is a partial stub";
|
||||
|
||||
QVariant shader = CreateNativeShader(ShaderCode(FileFunctions::ReadFileAsString(":/shaders/default.frag"), FileFunctions::ReadFileAsString(":/shaders/default.vert")));
|
||||
|
||||
ShaderJob job;
|
||||
job.InsertValue(QStringLiteral("ove_maintex"), ShaderValue(QVariant::fromValue(source), NodeParam::kTexture));
|
||||
|
||||
Blit(shader, job, params);
|
||||
}
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
|
||||
@@ -121,12 +121,22 @@ public:
|
||||
|
||||
TexturePtr CreateTexture(const VideoParams& param, void* data = nullptr, int linesize = 0);
|
||||
|
||||
struct ShaderValue {
|
||||
QVariant data;
|
||||
NodeParam::DataType type;
|
||||
};
|
||||
void BlitToTexture(QVariant shader,
|
||||
OLIVE_NAMESPACE::ShaderJob job,
|
||||
OLIVE_NAMESPACE::Renderer::Texture* destination)
|
||||
{
|
||||
Blit(shader, job, destination, destination->params());
|
||||
}
|
||||
|
||||
using ShaderUniformMap = QHash<QString, ShaderValue>;
|
||||
void Blit(QVariant shader,
|
||||
OLIVE_NAMESPACE::ShaderJob job,
|
||||
OLIVE_NAMESPACE::VideoParams params)
|
||||
{
|
||||
Blit(shader, job, nullptr, params);
|
||||
}
|
||||
|
||||
void BlitColorManaged(ColorProcessorPtr color_processor, TexturePtr source, Texture* destination);
|
||||
void BlitColorManaged(ColorProcessorPtr color_processor, TexturePtr source, VideoParams params);
|
||||
|
||||
public slots:
|
||||
virtual void PostInit() = 0;
|
||||
@@ -135,10 +145,6 @@ public slots:
|
||||
|
||||
virtual void ClearDestination(double r = 0.0, double g = 0.0, double b = 0.0, double a = 0.0) = 0;
|
||||
|
||||
virtual void AttachTextureAsDestination(OLIVE_NAMESPACE::Renderer::Texture* texture) = 0;
|
||||
|
||||
virtual void DetachTextureAsDestination() = 0;
|
||||
|
||||
virtual QVariant CreateNativeTexture(OLIVE_NAMESPACE::VideoParams param, void* data = nullptr, int linesize = 0) = 0;
|
||||
|
||||
virtual void DestroyNativeTexture(QVariant texture) = 0;
|
||||
@@ -151,18 +157,19 @@ public slots:
|
||||
|
||||
virtual void DownloadFromTexture(OLIVE_NAMESPACE::Renderer::Texture* texture, void* data, int linesize) = 0;
|
||||
|
||||
virtual TexturePtr ProcessShader(const OLIVE_NAMESPACE::Node* node,
|
||||
OLIVE_NAMESPACE::ShaderJob job,
|
||||
OLIVE_NAMESPACE::VideoParams params) = 0;
|
||||
|
||||
virtual void SetViewport(int width, int height) = 0;
|
||||
|
||||
virtual void BlitColorManaged(OLIVE_NAMESPACE::ColorProcessorPtr color_processor, OLIVE_NAMESPACE::Renderer::Texture* source, OLIVE_NAMESPACE::Renderer::Texture *destination = nullptr) = 0;
|
||||
|
||||
virtual void Blit(OLIVE_NAMESPACE::Renderer::Texture* source, QVariant shader, OLIVE_NAMESPACE::Renderer::ShaderUniformMap parameters, OLIVE_NAMESPACE::Renderer::Texture* destination = nullptr) = 0;
|
||||
protected slots:
|
||||
virtual void Blit(QVariant shader,
|
||||
OLIVE_NAMESPACE::ShaderJob job,
|
||||
OLIVE_NAMESPACE::Renderer::Texture* destination,
|
||||
OLIVE_NAMESPACE::VideoParams destination_params) = 0;
|
||||
|
||||
private:
|
||||
struct ColorContext {
|
||||
QVariant shader;
|
||||
TexturePtr lut;
|
||||
};
|
||||
|
||||
QHash<QString, ColorContext> color_cache_;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -76,17 +76,6 @@ void RendererThreadWrapper::ClearDestination(double r, double g, double b, doubl
|
||||
Q_ARG(double, a));
|
||||
}
|
||||
|
||||
void RendererThreadWrapper::AttachTextureAsDestination(Renderer::Texture *texture)
|
||||
{
|
||||
QMetaObject::invokeMethod(inner_, "AttachTextureAsDestination", Qt::BlockingQueuedConnection,
|
||||
OLIVE_NS_ARG(Renderer::Texture*, texture));
|
||||
}
|
||||
|
||||
void RendererThreadWrapper::DetachTextureAsDestination()
|
||||
{
|
||||
QMetaObject::invokeMethod(inner_, "DetachTextureAsDestination", Qt::BlockingQueuedConnection);
|
||||
}
|
||||
|
||||
QVariant RendererThreadWrapper::CreateNativeTexture(VideoParams param, void *data, int linesize)
|
||||
{
|
||||
QVariant v;
|
||||
@@ -139,41 +128,15 @@ void RendererThreadWrapper::DownloadFromTexture(Renderer::Texture *texture, void
|
||||
Q_ARG(int, linesize));
|
||||
}
|
||||
|
||||
Renderer::TexturePtr RendererThreadWrapper::ProcessShader(const Node *node, ShaderJob job, VideoParams params)
|
||||
void RendererThreadWrapper::Blit(QVariant shader, ShaderJob job, Renderer::Texture *destination, VideoParams destination_params)
|
||||
{
|
||||
Renderer::TexturePtr tex;
|
||||
|
||||
QMetaObject::invokeMethod(inner_, "Blit", Qt::BlockingQueuedConnection,
|
||||
OLIVE_NS_RETURN_ARG(Renderer::TexturePtr, tex),
|
||||
OLIVE_NS_CONST_ARG(Node*, node),
|
||||
OLIVE_NS_ARG(ShaderJob, job),
|
||||
OLIVE_NS_ARG(VideoParams, params));
|
||||
|
||||
return tex;
|
||||
}
|
||||
|
||||
void RendererThreadWrapper::SetViewport(int width, int height)
|
||||
{
|
||||
QMetaObject::invokeMethod(inner_, "SetViewport", Qt::BlockingQueuedConnection,
|
||||
Q_ARG(int, width),
|
||||
Q_ARG(int, height));
|
||||
}
|
||||
|
||||
void RendererThreadWrapper::BlitColorManaged(ColorProcessorPtr color_processor, Renderer::Texture *source, Renderer::Texture *destination)
|
||||
{
|
||||
QMetaObject::invokeMethod(inner_, "BlitColorManaged", Qt::BlockingQueuedConnection,
|
||||
OLIVE_NS_ARG(ColorProcessorPtr, color_processor),
|
||||
OLIVE_NS_ARG(Renderer::Texture*, source),
|
||||
OLIVE_NS_ARG(Renderer::Texture*, destination));
|
||||
}
|
||||
|
||||
void RendererThreadWrapper::Blit(Renderer::Texture *source, QVariant shader, Renderer::ShaderUniformMap parameters, Renderer::Texture *destination)
|
||||
{
|
||||
QMetaObject::invokeMethod(inner_, "Blit", Qt::BlockingQueuedConnection,
|
||||
OLIVE_NS_ARG(Renderer::Texture*, source),
|
||||
Q_ARG(QVariant, shader),
|
||||
Q_ARG(Renderer::ShaderUniformMap, parameters),
|
||||
OLIVE_NS_ARG(Renderer::Texture*, destination));
|
||||
OLIVE_NS_ARG(ShaderJob, job),
|
||||
OLIVE_NS_ARG(Renderer::Texture*, destination),
|
||||
OLIVE_NS_ARG(VideoParams, destination_params));
|
||||
}
|
||||
|
||||
OLIVE_NAMESPACE_EXIT
|
||||
|
||||
@@ -47,10 +47,6 @@ public slots:
|
||||
|
||||
virtual void ClearDestination(double r = 0.0, double g = 0.0, double b = 0.0, double a = 0.0) override;
|
||||
|
||||
virtual void AttachTextureAsDestination(OLIVE_NAMESPACE::Renderer::Texture* texture) override;
|
||||
|
||||
virtual void DetachTextureAsDestination() override;
|
||||
|
||||
virtual QVariant CreateNativeTexture(OLIVE_NAMESPACE::VideoParams param, void* data = nullptr, int linesize = 0) override;
|
||||
|
||||
virtual void DestroyNativeTexture(QVariant texture) override;
|
||||
@@ -63,15 +59,11 @@ public slots:
|
||||
|
||||
virtual void DownloadFromTexture(OLIVE_NAMESPACE::Renderer::Texture* texture, void* data, int linesize) override;
|
||||
|
||||
virtual TexturePtr ProcessShader(const OLIVE_NAMESPACE::Node* node,
|
||||
OLIVE_NAMESPACE::ShaderJob job,
|
||||
OLIVE_NAMESPACE::VideoParams params) override;
|
||||
|
||||
virtual void SetViewport(int width, int height) override;
|
||||
|
||||
virtual void BlitColorManaged(OLIVE_NAMESPACE::ColorProcessorPtr color_processor, OLIVE_NAMESPACE::Renderer::Texture* source, OLIVE_NAMESPACE::Renderer::Texture *destination = nullptr) override;
|
||||
|
||||
virtual void Blit(OLIVE_NAMESPACE::Renderer::Texture* source, QVariant shader, OLIVE_NAMESPACE::Renderer::ShaderUniformMap parameters, OLIVE_NAMESPACE::Renderer::Texture* destination = nullptr) override;
|
||||
protected slots:
|
||||
virtual void Blit(QVariant shader,
|
||||
OLIVE_NAMESPACE::ShaderJob job,
|
||||
OLIVE_NAMESPACE::Renderer::Texture* destination,
|
||||
OLIVE_NAMESPACE::VideoParams destination_params) override;
|
||||
|
||||
private:
|
||||
Renderer* inner_;
|
||||
|
||||
Reference in New Issue
Block a user