diff --git a/olive.pro b/olive.pro index 43cede51f..299cf59b4 100644 --- a/olive.pro +++ b/olive.pro @@ -176,7 +176,8 @@ SOURCES += \ rendering/bitdepths.cpp \ timeline/mediaimportdata.cpp \ dialogs/autocutsilencedialog.cpp \ - ui/columnedgridlayout.cpp + ui/columnedgridlayout.cpp \ + rendering/shadergenerators.cpp HEADERS += \ ui/mainwindow.h \ @@ -306,7 +307,8 @@ HEADERS += \ rendering/bitdepths.h \ timeline/mediaimportdata.h \ dialogs/autocutsilencedialog.h \ - ui/columnedgridlayout.h + ui/columnedgridlayout.h \ + rendering/shadergenerators.h FORMS += diff --git a/rendering/framebufferobject.cpp b/rendering/framebufferobject.cpp index c69995064..2e51ab151 100644 --- a/rendering/framebufferobject.cpp +++ b/rendering/framebufferobject.cpp @@ -24,6 +24,9 @@ #include #include +// TODO take this from Config rather than having a constant +const GLuint kPixelFormat = GL_RGBA16F; + FramebufferObject::FramebufferObject() : buffer_(0), texture_(0), @@ -61,12 +64,8 @@ void FramebufferObject::Create(QOpenGLContext *ctx, int width, int height) ctx->functions()->glBindTexture(GL_TEXTURE_2D, texture_); // allocate storage for texture - /*ctx->functions()->glTexImage2D( - GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr - );*/ - ctx->functions()->glTexImage2D( - GL_TEXTURE_2D, 0, GL_RGBA16F, width, height, 0, GL_RGBA, GL_FLOAT, nullptr + GL_TEXTURE_2D, 0, kPixelFormat, width, height, 0, GL_RGBA, GL_FLOAT, nullptr ); // set texture filtering to bilinear diff --git a/rendering/renderfunctions.cpp b/rendering/renderfunctions.cpp index 0a0aee87c..e64097165 100644 --- a/rendering/renderfunctions.cpp +++ b/rendering/renderfunctions.cpp @@ -44,6 +44,7 @@ extern "C" { #include "panels/timeline.h" #include "panels/viewer.h" #include "qopenglshaderprogramptr.h" +#include "shadergenerators.h" GLfloat olive::rendering::blit_vertices[] = { -1.0f, -1.0f, 0.0f, @@ -75,14 +76,6 @@ GLfloat olive::rendering::flipped_blit_texcoords[] = { 1.0, 0.0 }; -#ifndef NO_OCIO -// copied from source code to OCIODisplay -const int OCIO_LUT3D_EDGE_SIZE = 32; - -// copied from source code to OCIODisplay, expanded from 3*LUT3D_EDGE_SIZE*LUT3D_EDGE_SIZE*LUT3D_EDGE_SIZE -const int OCIO_NUM_3D_ENTRIES = 98304; -#endif - void olive::rendering::Blit(QOpenGLShaderProgram* pipeline, bool flipped, QMatrix4x4 matrix) { QOpenGLVertexArrayObject m_vao; @@ -126,95 +119,6 @@ void olive::rendering::Blit(QOpenGLShaderProgram* pipeline, bool flipped, QMatri } -QOpenGLShaderProgramPtr olive::rendering::GetPipeline(const QString& shader_code) -{ - QOpenGLShaderProgramPtr program = std::make_shared(); - - // Generate vertex shader - QString vert_shader = "#version 110\n" - "\n" - "#ifdef GL_ES\n" - "precision mediump int;\n" - "precision mediump float;\n" - "#endif\n" - "\n" - "uniform mat4 mvp_matrix;\n" - "\n" - "attribute vec4 a_position;\n" - "attribute vec2 a_texcoord;\n" - "\n" - "varying vec2 v_texcoord;\n" - "\n" - "void main() {\n" - " gl_Position = mvp_matrix * a_position;\n" - " v_texcoord = a_texcoord;\n" - "}\n"; - - // Generate fragment shader - QString frag_shader = "#version 110\n" - "\n" - "#ifdef GL_ES\n" - "precision mediump int;\n" - "precision mediump float;\n" - "#endif\n" - "\n" - "uniform sampler2D texture;\n" - "uniform float opacity;\n" - "uniform bool color_only;\n" - "uniform vec4 color_only_color;\n" - "varying vec2 v_texcoord;\n" - "\n"; - - // Finish the function with the main function - - // Check if additional code was passed to this function, add it here - if (shader_code.isEmpty()) { - - // If not, just add a pure main() function - - frag_shader.append("\n" - "void main() {\n" - " if (color_only) {\n" - " gl_FragColor = color_only_color;" - " } else {\n" - " vec4 color = texture2D(texture, v_texcoord)*opacity;\n" - " gl_FragColor = color;\n" - " }\n" - "}\n"); - - } else { - - // If additional code was passed, add it and reference it in main(). - // - // The function in the additional code is expected to be `vec4 process(vec4 color)`. The texture coordinate can be - // acquired through `v_texcoord`. - - frag_shader.append(shader_code); - - frag_shader.append("\n" - "void main() {\n" - " vec4 color = process(texture2D(texture, v_texcoord))*opacity;\n" - " gl_FragColor = color;\n" - "}\n"); - - } - - - - - // Add shaders to program - program->addShaderFromSourceCode(QOpenGLShader::Vertex, vert_shader); - program->addShaderFromSourceCode(QOpenGLShader::Fragment, frag_shader); - program->link(); - - // Set opacity default to 100% - program->bind(); - program->setUniformValue("opacity", 1.0f); - program->release(); - - return program; -} - void draw_clip(QOpenGLContext* ctx, QOpenGLShaderProgram* pipeline, GLuint fbo, @@ -560,7 +464,13 @@ GLuint olive::rendering::compose_sequence(ComposeSequenceParams ¶ms) { OCIO::ConstProcessorRcPtr processor = config->getProcessor(input_cs.toUtf8(), OCIO::ROLE_SCENE_LINEAR); - c->ocio_shader = olive::rendering::SetupOCIO(params.ctx, c->ocio_lut_texture, processor); + olive::shader::AlphaAssociateMode associate_mode = (c->media()->to_footage()->alpha_is_associated) + ? olive::shader::DisassociateAndReassociate : olive::shader::Associate; + + c->ocio_shader = olive::shader::SetupOCIO(params.ctx, + c->ocio_lut_texture, + processor, + associate_mode); } catch (OCIO::Exception& e) { qWarning() << e.what(); } @@ -578,19 +488,6 @@ GLuint olive::rendering::compose_sequence(ComposeSequenceParams ¶ms) { } #endif - if (!c->media()->to_footage()->alpha_is_associated) { - - // alpha is not premultiplied, we'll need to multiply it for the rest of the pipeline - params.ctx->functions()->glBlendFuncSeparate(GL_SRC_ALPHA, GL_ZERO, GL_ONE, GL_ZERO); - - textureID = draw_clip(params.ctx, params.pipeline, c->fbo.at(fbo_switcher), textureID, true); - - params.ctx->functions()->glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); - - fbo_switcher = !fbo_switcher; - - } - } } @@ -696,9 +593,8 @@ GLuint olive::rendering::compose_sequence(ComposeSequenceParams ¶ms) { params.ctx->functions()->glBindTexture(GL_TEXTURE_2D, textureID); // set texture filter to bilinear - //params.ctx->functions()->glGenerateMipmap(GL_TEXTURE_2D); - //params.ctx->functions()->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); - params.ctx->functions()->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + params.ctx->functions()->glGenerateMipmap(GL_TEXTURE_2D); + params.ctx->functions()->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); params.ctx->functions()->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // draw clip on screen according to gl coordinates @@ -953,74 +849,6 @@ void close_active_clips(Sequence* s) { } #ifndef NO_OCIO -QOpenGLShaderProgramPtr olive::rendering::SetupOCIO(QOpenGLContext* ctx, - GLuint& lut_texture, - OCIO::ConstProcessorRcPtr processor) -{ - - QOpenGLExtraFunctions* xf = ctx->extraFunctions(); - - // Create LUT texture - xf->glGenTextures(1, &lut_texture); - - // Bind LUT - xf->glBindTexture(GL_TEXTURE_3D, lut_texture); - - // Set texture parameters - xf->glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - xf->glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - xf->glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - xf->glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - xf->glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); - - // Allocate storage for texture - xf->glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB16F_ARB, - OCIO_LUT3D_EDGE_SIZE, OCIO_LUT3D_EDGE_SIZE, OCIO_LUT3D_EDGE_SIZE, - 0, GL_RGB,GL_FLOAT, nullptr); - - // - // SET UP GLSL SHADER - // - - OCIO::GpuShaderDesc shaderDesc; - shaderDesc.setLanguage(OCIO::GPU_LANGUAGE_GLSL_1_0); - shaderDesc.setFunctionName("OCIODisplay"); - shaderDesc.setLut3DEdgeLen(OCIO_LUT3D_EDGE_SIZE); - - // - // COMPUTE 3D LUT - // - - GLfloat* ocio_lut_data = new GLfloat[OCIO_NUM_3D_ENTRIES]; - processor->getGpuLut3D(ocio_lut_data, shaderDesc); - - // Upload LUT data to texture - xf->glTexSubImage3D(GL_TEXTURE_3D, 0, - 0, 0, 0, - OCIO_LUT3D_EDGE_SIZE, OCIO_LUT3D_EDGE_SIZE, OCIO_LUT3D_EDGE_SIZE, - GL_RGB, GL_FLOAT, ocio_lut_data); - - delete [] ocio_lut_data; - - // Create OCIO shader code - QString shader_text(processor->getGpuShaderText(shaderDesc)); - shader_text.append("\n" - "uniform sampler3D tex2;\n" - "\n" - "vec4 process(vec4 col) {\n" - " return OCIODisplay(col, tex2);\n" - "}\n"); - - - // Get pipeline-based shader to inject OCIO shader into - QOpenGLShaderProgramPtr shader = olive::rendering::GetPipeline(shader_text); - - // Release LUT - xf->glBindTexture(GL_TEXTURE_3D, 0); - - return shader; -} - GLuint olive::rendering::OCIOBlit(QOpenGLShaderProgram *pipeline, GLuint lut, const FramebufferObject& fbo, diff --git a/rendering/renderfunctions.h b/rendering/renderfunctions.h index 08ab77afa..a4f5c2877 100644 --- a/rendering/renderfunctions.h +++ b/rendering/renderfunctions.h @@ -389,9 +389,8 @@ namespace olive { extern GLfloat blit_texcoords[]; extern GLfloat flipped_blit_texcoords[]; void Blit(QOpenGLShaderProgram* pipeline, bool flipped = false, QMatrix4x4 matrix = QMatrix4x4()); - QOpenGLShaderProgramPtr GetPipeline(const QString &shader_code = QString()); + #ifndef NO_OCIO - QOpenGLShaderProgramPtr SetupOCIO(QOpenGLContext *ctx, GLuint &lut_texture, OCIO::ConstProcessorRcPtr processor); GLuint OCIOBlit(QOpenGLShaderProgram *pipeline, GLuint lut, const FramebufferObject& fbo, diff --git a/rendering/renderthread.cpp b/rendering/renderthread.cpp index 552958e94..d1ab0b22f 100644 --- a/rendering/renderthread.cpp +++ b/rendering/renderthread.cpp @@ -36,6 +36,7 @@ namespace OCIO = OCIO_NAMESPACE::v1; #include "effects/effectloaders.h" #include "global/config.h" #include "rendering/renderfunctions.h" +#include "rendering/shadergenerators.h" RenderThread::RenderThread() : gizmos(nullptr), @@ -117,7 +118,7 @@ void RenderThread::run() { olive::effects_loaded.unlock(); blend_mode_program->link(); - pipeline_program = olive::rendering::GetPipeline(); + pipeline_program = olive::shader::GetPipeline(); } #ifndef NO_OCIO @@ -193,7 +194,7 @@ void RenderThread::set_up_ocio() OCIO::ConstProcessorRcPtr processor = config->getProcessor(transform); // Create a OCIO shader with this processor - ocio_shader = olive::rendering::SetupOCIO(ctx, ocio_lut_texture, processor); + ocio_shader = olive::shader::SetupOCIO(ctx, ocio_lut_texture, processor, olive::shader::NoAssociate); } catch(OCIO::Exception & e) { qCritical() << e.what(); diff --git a/rendering/shadergenerators.cpp b/rendering/shadergenerators.cpp new file mode 100644 index 000000000..dde856ba6 --- /dev/null +++ b/rendering/shadergenerators.cpp @@ -0,0 +1,225 @@ +#include "shadergenerators.h" + +#include + +QOpenGLShaderProgramPtr olive::shader::GetPipeline(const QString& shader_code) +{ + QOpenGLShaderProgramPtr program = std::make_shared(); + + // Generate vertex shader + QString vert_shader = "#version 110\n" + "\n" + "#ifdef GL_ES\n" + "precision mediump int;\n" + "precision mediump float;\n" + "#endif\n" + "\n" + "uniform mat4 mvp_matrix;\n" + "\n" + "attribute vec4 a_position;\n" + "attribute vec2 a_texcoord;\n" + "\n" + "varying vec2 v_texcoord;\n" + "\n" + "void main() {\n" + " gl_Position = mvp_matrix * a_position;\n" + " v_texcoord = a_texcoord;\n" + "}\n"; + + // Generate fragment shader + QString frag_shader = "#version 110\n" + "\n" + "#ifdef GL_ES\n" + "precision mediump int;\n" + "precision mediump float;\n" + "#endif\n" + "\n" + "uniform sampler2D texture;\n" + "uniform float opacity;\n" + "uniform bool color_only;\n" + "uniform vec4 color_only_color;\n" + "varying vec2 v_texcoord;\n" + "\n"; + + // Finish the function with the main function + + // Check if additional code was passed to this function, add it here + if (shader_code.isEmpty()) { + + // If not, just add a pure main() function + + frag_shader.append("\n" + "void main() {\n" + " if (color_only) {\n" + " gl_FragColor = color_only_color;" + " } else {\n" + " vec4 color = texture2D(texture, v_texcoord)*opacity;\n" + " gl_FragColor = color;\n" + " }\n" + "}\n"); + + } else { + + // If additional code was passed, add it and reference it in main(). + // + // The function in the additional code is expected to be `vec4 process(vec4 color)`. The texture coordinate can be + // acquired through `v_texcoord`. + + frag_shader.append(shader_code); + + frag_shader.append("\n" + "void main() {\n" + " vec4 color = process(texture2D(texture, v_texcoord))*opacity;\n" + " gl_FragColor = color;\n" + "}\n"); + + } + + + + + // Add shaders to program + program->addShaderFromSourceCode(QOpenGLShader::Vertex, vert_shader); + program->addShaderFromSourceCode(QOpenGLShader::Fragment, frag_shader); + program->link(); + + // Set opacity default to 100% + program->bind(); + program->setUniformValue("opacity", 1.0f); + program->release(); + + return program; +} + +QString olive::shader::GetAlphaDisassociateFunction(const QString &function_name) +{ + return QString("vec4 %1(vec4 col) {\n" + " if (col.a > 0.0) {\n" + " return vec4(col.rgb / col.a, col.a);" + " }\n" + " return col;\n" + "}\n").arg(function_name); +} + +QString olive::shader::GetAlphaReassociateFunction(const QString &function_name) +{ + return QString("vec4 %1(vec4 col) {\n" + " if (col.a > 0.0) {\n" + " return vec4(col.rgb * col.a, col.a);" + " }\n" + " return col;\n" + "}\n").arg(function_name); +} + +QString olive::shader::GetAlphaAssociateFunction(const QString &function_name) +{ + return QString("vec4 %1(vec4 col) {\n" + " return vec4(col.rgb * col.a, col.a);\n" + "}\n").arg(function_name); +} + +#ifndef NO_OCIO + +// copied from source code to OCIODisplay +const int OCIO_LUT3D_EDGE_SIZE = 32; + +// copied from source code to OCIODisplay, expanded from 3*LUT3D_EDGE_SIZE*LUT3D_EDGE_SIZE*LUT3D_EDGE_SIZE +const int OCIO_NUM_3D_ENTRIES = 98304; + +QOpenGLShaderProgramPtr olive::shader::SetupOCIO(QOpenGLContext* ctx, + GLuint& lut_texture, + OCIO::ConstProcessorRcPtr processor, + AlphaAssociateMode alpha_associate_mode) +{ + + QOpenGLExtraFunctions* xf = ctx->extraFunctions(); + + // Create LUT texture + xf->glGenTextures(1, &lut_texture); + + // Bind LUT + xf->glBindTexture(GL_TEXTURE_3D, lut_texture); + + // Set texture parameters + xf->glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + xf->glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + xf->glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + xf->glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + xf->glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); + + // Allocate storage for texture + xf->glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB16F_ARB, + OCIO_LUT3D_EDGE_SIZE, OCIO_LUT3D_EDGE_SIZE, OCIO_LUT3D_EDGE_SIZE, + 0, GL_RGB,GL_FLOAT, nullptr); + + // + // SET UP GLSL SHADER + // + + OCIO::GpuShaderDesc shaderDesc; + shaderDesc.setLanguage(OCIO::GPU_LANGUAGE_GLSL_1_0); + shaderDesc.setFunctionName("OCIODisplay"); + shaderDesc.setLut3DEdgeLen(OCIO_LUT3D_EDGE_SIZE); + + // + // COMPUTE 3D LUT + // + + GLfloat* ocio_lut_data = new GLfloat[OCIO_NUM_3D_ENTRIES]; + processor->getGpuLut3D(ocio_lut_data, shaderDesc); + + // Upload LUT data to texture + xf->glTexSubImage3D(GL_TEXTURE_3D, 0, + 0, 0, 0, + OCIO_LUT3D_EDGE_SIZE, OCIO_LUT3D_EDGE_SIZE, OCIO_LUT3D_EDGE_SIZE, + GL_RGB, GL_FLOAT, ocio_lut_data); + + delete [] ocio_lut_data; + + // Create OCIO shader code + QString shader_text(processor->getGpuShaderText(shaderDesc)); + + QString ocio_call_func; + + // Enforce alpha association + switch (alpha_associate_mode) { + case Associate: + // If alpha is not already associated, we can just associate after OCIO + + // Add associate function + shader_text.append(GetAlphaAssociateFunction("assoc")); + + // Make OCIO call pass through associate function + ocio_call_func = "assoc(OCIODisplay(col, tex2));"; + break; + case DisassociateAndReassociate: + // If alpha is already associated, we'll need to disassociate and reassociate + shader_text.append("\n"); + shader_text.append(GetAlphaDisassociateFunction("disassoc")); + shader_text.append(GetAlphaReassociateFunction("reassoc")); + + // Make OCIO call pass through disassociate and reassociate function + ocio_call_func = "reassoc(OCIODisplay(disassoc(col), tex2));"; + break; + default: + // No association + ocio_call_func = "OCIODisplay(col, tex2);"; + } + + shader_text.append(QString("\n" + "uniform sampler3D tex2;\n" + "\n" + "vec4 process(vec4 col) {\n" + " return %1\n" + "}\n").arg(ocio_call_func)); + + + // Get pipeline-based shader to inject OCIO shader into + QOpenGLShaderProgramPtr shader = olive::shader::GetPipeline(shader_text); + + // Release LUT + xf->glBindTexture(GL_TEXTURE_3D, 0); + + return shader; +} +#endif diff --git a/rendering/shadergenerators.h b/rendering/shadergenerators.h new file mode 100644 index 000000000..eacb51e83 --- /dev/null +++ b/rendering/shadergenerators.h @@ -0,0 +1,37 @@ +#ifndef SHADERGENERATORS_H +#define SHADERGENERATORS_H + +#include "qopenglshaderprogramptr.h" +#include "framebufferobject.h" + +#ifndef NO_OCIO +#include +namespace OCIO = OCIO_NAMESPACE::v1; +#endif + +namespace olive { +namespace shader { + +QOpenGLShaderProgramPtr GetPipeline(const QString &shader_code = QString()); + +#ifndef NO_OCIO +enum AlphaAssociateMode { + NoAssociate, + Associate, + DisassociateAndReassociate +}; + +QOpenGLShaderProgramPtr SetupOCIO(QOpenGLContext *ctx, + GLuint &lut_texture, + OCIO::ConstProcessorRcPtr processor, + AlphaAssociateMode alpha_associate_mode); +#endif + +QString GetAlphaDisassociateFunction(const QString& function_name); +QString GetAlphaReassociateFunction(const QString& function_name); +QString GetAlphaAssociateFunction(const QString& function_name); + +} +} + +#endif // SHADERGENERATORS_H diff --git a/timeline/clip.cpp b/timeline/clip.cpp index a2b5fd4fe..79b79de46 100644 --- a/timeline/clip.cpp +++ b/timeline/clip.cpp @@ -474,7 +474,7 @@ void Clip::Open() { } // reset variable used to optimize uploading frame data - texture_frame = -1; + texture_timestamp = -1; if (UsesCacher()) { // cacher will unlock open_lock @@ -558,47 +558,60 @@ bool Clip::Retrieve() if (frame != nullptr && cacher.queue()->contains(frame)) { - bool allocate_data = false; + //if (frame->pts != texture_timestamp) { + + bool allocate_data = false; - // check if the opengl texture exists yet, create it if not - if (texture == 0) { QOpenGLFunctions* f = QOpenGLContext::currentContext()->functions(); - // create texture object - f->glGenTextures(1, &texture); + // check if the opengl texture exists yet, create it if not + if (texture == 0) { - f->glBindTexture(GL_TEXTURE_2D, texture); + // create texture object + f->glGenTextures(1, &texture); - // set texture filtering to bilinear - f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + f->glBindTexture(GL_TEXTURE_2D, texture); - // queue an allocation ahead - allocate_data = true; + // set texture filtering to bilinear + f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + f->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - } + // queue an allocation ahead + allocate_data = true; - QOpenGLFunctions* f = QOpenGLContext::currentContext()->functions(); + } else { - f->glPixelStorei(GL_UNPACK_ROW_LENGTH, frame->linesize[0]/kRGBAComponentCount); + f->glBindTexture(GL_TEXTURE_2D, texture); - int video_width = cacher.media_width(); - int video_height = cacher.media_height(); + } - if (allocate_data) { - // the raw frame size may differ from the one we're using (e.g. a lower resolution proxy), so we make sure - // the texture is using the correct dimensions, but then treat it as if it's the original resolution in the - // composition - f->glTexImage2D( - GL_TEXTURE_2D, 0, GL_RGBA8, video_width, video_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, frame->data[0] - ); - } else { - f->glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, video_width, video_height, GL_RGBA, GL_UNSIGNED_BYTE, frame->data[0]); - } + f->glPixelStorei(GL_UNPACK_ROW_LENGTH, frame->linesize[0]/kRGBAComponentCount); - f->glBindTexture(GL_TEXTURE_2D, 0); + int video_width = cacher.media_width(); + int video_height = cacher.media_height(); - f->glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); + if (allocate_data) { + + // the raw frame size may differ from the one we're using (e.g. a lower resolution proxy), so we make sure + // the texture is using the correct dimensions, but then treat it as if it's the original resolution in the + // composition + f->glTexImage2D( + GL_TEXTURE_2D, 0, GL_RGBA8, video_width, video_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, frame->data[0] + ); + + } else { + + f->glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, video_width, video_height, GL_RGBA, GL_UNSIGNED_BYTE, frame->data[0]); + + } + + f->glBindTexture(GL_TEXTURE_2D, 0); + + f->glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); + + texture_timestamp = frame->pts; + + //} ret = true; } else { diff --git a/timeline/clip.h b/timeline/clip.h index fa82abcf2..993141ebf 100644 --- a/timeline/clip.h +++ b/timeline/clip.h @@ -155,7 +155,7 @@ public: // video playback variables QVector fbo; GLuint texture; - long texture_frame; + int64_t texture_timestamp; #ifndef NO_OCIO QOpenGLShaderProgramPtr ocio_shader; diff --git a/ui/viewerwidget.cpp b/ui/viewerwidget.cpp index 81099abf3..488fc9678 100644 --- a/ui/viewerwidget.cpp +++ b/ui/viewerwidget.cpp @@ -57,6 +57,7 @@ extern "C" { #include "ui/timelinewidget.h" #include "rendering/renderfunctions.h" #include "rendering/renderthread.h" +#include "rendering/shadergenerators.h" #include "ui/viewerwindow.h" #include "ui/menu.h" #include "mainwindow.h" @@ -217,7 +218,7 @@ void ViewerWidget::initializeGL() { connect(context(), SIGNAL(aboutToBeDestroyed()), this, SLOT(context_destroy()), Qt::DirectConnection); - pipeline_ = olive::rendering::GetPipeline(); + pipeline_ = olive::shader::GetPipeline(); vao_.create(); diff --git a/ui/viewerwindow.cpp b/ui/viewerwindow.cpp index a6c5308eb..43b0fc595 100644 --- a/ui/viewerwindow.cpp +++ b/ui/viewerwindow.cpp @@ -31,6 +31,7 @@ #include #include "rendering/renderfunctions.h" +#include "rendering/shadergenerators.h" #include "ui/mainwindow.h" ViewerWindow::ViewerWindow(QWidget *parent) : @@ -109,7 +110,7 @@ void ViewerWindow::mouseMoveEvent(QMouseEvent *) { void ViewerWindow::initializeGL() { - pipeline_ = olive::rendering::GetPipeline(); + pipeline_ = olive::shader::GetPipeline(); } void ViewerWindow::paintGL() {