nearly finished gles transition

This commit is contained in:
itsmattkc
2019-03-17 18:19:12 +11:00
parent c8496ac2a8
commit 05ac0314d7
19 changed files with 344 additions and 392 deletions
+26 -31
View File
@@ -120,7 +120,7 @@ Effect::Effect(Clip* c, const EffectMeta *em) :
parent_clip(c),
meta(em),
flags_(0),
glslProgram(nullptr),
shader_program_(nullptr),
texture(nullptr),
isOpen(false),
bound(false),
@@ -304,9 +304,9 @@ Effect::Effect(Clip* c, const EffectMeta *em) :
for (int i=0;i<attributes.size();i++) {
const QXmlStreamAttribute& attr = attributes.at(i);
if (attr.name() == "vert") {
vertPath = attr.value().toString();
shader_vert_path_ = attr.value().toString();
} else if (attr.name() == "frag") {
fragPath = attr.value().toString();
shader_frag_path_ = attr.value().toString();
} else if (attr.name() == "iterations") {
setIterations(attr.value().toInt());
}
@@ -708,9 +708,9 @@ bool Effect::is_open() {
}
void Effect::validate_meta_path() {
if (!meta->path.isEmpty() || (vertPath.isEmpty() && fragPath.isEmpty())) return;
if (!meta->path.isEmpty() || (shader_vert_path_.isEmpty() && shader_frag_path_.isEmpty())) return;
QList<QString> effects_paths = get_effects_paths();
const QString& test_fn = vertPath.isEmpty() ? fragPath : vertPath;
const QString& test_fn = shader_vert_path_.isEmpty() ? shader_frag_path_ : shader_vert_path_;
for (int i=0;i<effects_paths.size();i++) {
if (QFileInfo::exists(effects_paths.at(i) + "/" + test_fn)) {
for (int j=0;j<olive::effects.size();j++) {
@@ -733,19 +733,19 @@ void Effect::open() {
if (QOpenGLContext::currentContext() == nullptr) {
qWarning() << "No current context to create a shader program for - will retry next repaint";
} else {
glslProgram = new QOpenGLShaderProgram();
shader_program_ = std::make_shared<QOpenGLShaderProgram>();
validate_meta_path();
bool glsl_compiled = true;
if (!vertPath.isEmpty()) {
if (glslProgram->addShaderFromSourceFile(QOpenGLShader::Vertex, meta->path + "/" + vertPath)) {
if (!shader_vert_path_.isEmpty()) {
if (shader_program_->addShaderFromSourceFile(QOpenGLShader::Vertex, meta->path + "/" + shader_vert_path_)) {
qInfo() << "Vertex shader added successfully";
} else {
glsl_compiled = false;
qWarning() << "Vertex shader could not be added";
}
}
if (!fragPath.isEmpty()) {
if (glslProgram->addShaderFromSourceFile(QOpenGLShader::Fragment, meta->path + "/" + fragPath)) {
if (!shader_frag_path_.isEmpty()) {
if (shader_program_->addShaderFromSourceFile(QOpenGLShader::Fragment, meta->path + "/" + shader_frag_path_)) {
qInfo() << "Fragment shader added successfully";
} else {
glsl_compiled = false;
@@ -753,7 +753,7 @@ void Effect::open() {
}
}
if (glsl_compiled) {
if (glslProgram->link()) {
if (shader_program_->link()) {
qInfo() << "Shader program linked successfully";
} else {
qWarning() << "Shader program failed to link";
@@ -771,15 +771,12 @@ void Effect::close() {
qWarning() << "Tried to close an effect that was already closed";
}
delete_texture();
if (glslProgram != nullptr) {
delete glslProgram;
glslProgram = nullptr;
}
shader_program_ = nullptr;
isOpen = false;
}
bool Effect::is_glsl_linked() {
return glslProgram != nullptr && glslProgram->isLinked();
return shader_program_ != nullptr && shader_program_->isLinked();
}
void Effect::startEffect() {
@@ -789,13 +786,13 @@ void Effect::startEffect() {
}
if (olive::CurrentRuntimeConfig.shaders_are_enabled
&& (Flags() & Effect::ShaderFlag)
&& glslProgram->isLinked()) {
bound = glslProgram->bind();
&& shader_program_->isLinked()) {
bound = shader_program_->bind();
}
}
void Effect::endEffect() {
if (bound) glslProgram->release();
if (bound) shader_program_->release();
bound = false;
}
@@ -827,9 +824,9 @@ EffectPtr Effect::copy(Clip *c) {
}
void Effect::process_shader(double timecode, GLTextureCoords&, int iteration) {
glslProgram->setUniformValue("resolution", parent_clip->media_width(), parent_clip->media_height());
glslProgram->setUniformValue("time", GLfloat(timecode));
glslProgram->setUniformValue("iteration", iteration);
shader_program_->setUniformValue("resolution", parent_clip->media_width(), parent_clip->media_height());
shader_program_->setUniformValue("time", GLfloat(timecode));
shader_program_->setUniformValue("iteration", iteration);
for (int i=0;i<rows.size();i++) {
EffectRow* row = rows.at(i);
@@ -840,14 +837,14 @@ void Effect::process_shader(double timecode, GLTextureCoords&, int iteration) {
case EffectField::EFFECT_FIELD_DOUBLE:
{
DoubleField* double_field = static_cast<DoubleField*>(field);
glslProgram->setUniformValue(double_field->id().toUtf8().constData(),
shader_program_->setUniformValue(double_field->id().toUtf8().constData(),
GLfloat(double_field->GetDoubleAt(timecode)));
}
break;
case EffectField::EFFECT_FIELD_COLOR:
{
ColorField* color_field = static_cast<ColorField*>(field);
glslProgram->setUniformValue(
shader_program_->setUniformValue(
color_field->id().toUtf8().constData(),
GLfloat(color_field->GetColorAt(timecode).redF()),
GLfloat(color_field->GetColorAt(timecode).greenF()),
@@ -856,10 +853,10 @@ void Effect::process_shader(double timecode, GLTextureCoords&, int iteration) {
}
break;
case EffectField::EFFECT_FIELD_BOOL:
glslProgram->setUniformValue(field->id().toUtf8().constData(), field->GetValueAt(timecode).toBool());
shader_program_->setUniformValue(field->id().toUtf8().constData(), field->GetValueAt(timecode).toBool());
break;
case EffectField::EFFECT_FIELD_COMBO:
glslProgram->setUniformValue(field->id().toUtf8().constData(), field->GetValueAt(timecode).toInt());
shader_program_->setUniformValue(field->id().toUtf8().constData(), field->GetValueAt(timecode).toInt());
break;
// can you even send a string to a uniform value?
@@ -1058,7 +1055,7 @@ void Effect::redraw(double) {
}
bool Effect::valueHasChanged(double timecode) {
if (cachedValues.size() == 0) {
if (cachedValues.isEmpty()) {
for (int i=0;i<row_count();i++) {
EffectRow* crow = row(i);
@@ -1089,10 +1086,8 @@ bool Effect::valueHasChanged(double timecode) {
}
void Effect::delete_texture() {
if (texture != nullptr) {
delete texture;
texture = nullptr;
}
delete texture;
texture = nullptr;
}
const EffectMeta* get_meta_from_name(const QString& input) {
+13 -28
View File
@@ -44,6 +44,7 @@
#include "ui/checkboxex.h"
#include "effectrow.h"
#include "effectgizmo.h"
#include "rendering/qopenglshaderprogramptr.h"
class Clip;
@@ -113,33 +114,17 @@ enum EffectInternal {
};
struct GLTextureCoords {
int grid_size;
QMatrix4x4 matrix;
int vertexTopLeftX;
int vertexTopLeftY;
int vertexTopLeftZ;
int vertexTopRightX;
int vertexTopRightY;
int vertexTopRightZ;
int vertexBottomLeftX;
int vertexBottomLeftY;
int vertexBottomLeftZ;
int vertexBottomRightX;
int vertexBottomRightY;
int vertexBottomRightZ;
QVector3D vertex_top_left;
QVector3D vertex_top_right;
QVector3D vertex_bottom_left;
QVector3D vertex_bottom_right;
float textureTopLeftX;
float textureTopLeftY;
float textureTopLeftQ;
float textureTopRightX;
float textureTopRightY;
float textureTopRightQ;
float textureBottomRightX;
float textureBottomRightY;
float textureBottomRightQ;
float textureBottomLeftX;
float textureBottomLeftY;
float textureBottomLeftQ;
QVector2D texture_top_left;
QVector2D texture_top_right;
QVector2D texture_bottom_left;
QVector2D texture_bottom_right;
int blendmode;
float opacity;
@@ -240,9 +225,9 @@ private slots:
void load_from_file();
protected:
// glsl effect
QOpenGLShaderProgram* glslProgram;
QString vertPath;
QString fragPath;
QOpenGLShaderProgramPtr shader_program_;
QString shader_vert_path_;
QString shader_frag_path_;
// superimpose effect
QImage img;
+3 -1
View File
@@ -183,7 +183,9 @@ QVariant EffectField::GetValueAt(double timecode)
} else {
QColor before_data = keyframes.at(before_keyframe).data.value<QColor>();
QColor after_data = keyframes.at(after_keyframe).data.value<QColor>();
value = QColor(lerp(before_data.red(), after_data.red(), progress), lerp(before_data.green(), after_data.green(), progress), lerp(before_data.blue(), after_data.blue(), progress));
value = QColor(lerp(before_data.red(), after_data.red(), progress),
lerp(before_data.green(), after_data.green(), progress),
lerp(before_data.blue(), after_data.blue(), progress));
}
persistent_data_ = value;
break;
+1 -1
View File
@@ -45,7 +45,7 @@ class EffectGizmo : public QObject {
public:
EffectGizmo(Effect* parent, int type);
QVector<QPoint> world_pos;
QVector<QVector3D> world_pos;
QVector<QPoint> screen_pos;
DoubleField* x_field1;
+15 -19
View File
@@ -63,35 +63,31 @@ CornerPinEffect::CornerPinEffect(Clip* c, const EffectMeta *em) : Effect(c, em)
bottom_right_gizmo->x_field1 = bottom_right_x;
bottom_right_gizmo->y_field1 = bottom_right_y;
vertPath = "cornerpin.vert";
fragPath = "cornerpin.frag";
shader_vert_path_ = "cornerpin.vert";
shader_frag_path_ = "cornerpin.frag";
}
void CornerPinEffect::process_coords(double timecode, GLTextureCoords &coords, int) {
coords.vertexTopLeftX += top_left_x->GetDoubleAt(timecode);
coords.vertexTopLeftY += top_left_y->GetDoubleAt(timecode);
coords.vertex_top_left += QVector3D(top_left_x->GetDoubleAt(timecode), top_left_y->GetDoubleAt(timecode), 0.0f);
coords.vertexTopRightX += top_right_x->GetDoubleAt(timecode);
coords.vertexTopRightY += top_right_y->GetDoubleAt(timecode);
coords.vertex_top_right += QVector3D(top_right_x->GetDoubleAt(timecode), top_right_y->GetDoubleAt(timecode), 0.0f);
coords.vertexBottomLeftX += bottom_left_x->GetDoubleAt(timecode);
coords.vertexBottomLeftY += bottom_left_y->GetDoubleAt(timecode);
coords.vertex_bottom_left += QVector3D(bottom_left_x->GetDoubleAt(timecode), bottom_left_y->GetDoubleAt(timecode), 0.0f);
coords.vertexBottomRightX += bottom_right_x->GetDoubleAt(timecode);
coords.vertexBottomRightY += bottom_right_y->GetDoubleAt(timecode);
coords.vertex_bottom_right += QVector3D(bottom_right_x->GetDoubleAt(timecode), bottom_right_y->GetDoubleAt(timecode), 0.0f);
}
void CornerPinEffect::process_shader(double timecode, GLTextureCoords &coords, int) {
glslProgram->setUniformValue("p0", GLfloat(coords.vertexBottomLeftX), GLfloat(coords.vertexBottomLeftY));
glslProgram->setUniformValue("p1", GLfloat(coords.vertexBottomRightX), GLfloat(coords.vertexBottomRightY));
glslProgram->setUniformValue("p2", GLfloat(coords.vertexTopLeftX), GLfloat(coords.vertexTopLeftY));
glslProgram->setUniformValue("p3", GLfloat(coords.vertexTopRightX), GLfloat(coords.vertexTopRightY));
glslProgram->setUniformValue("perspective", perspective->GetBoolAt(timecode));
shader_program_->setUniformValue("p0", coords.vertex_bottom_left.x(), coords.vertex_bottom_left.y());
shader_program_->setUniformValue("p1", coords.vertex_bottom_right.x(), coords.vertex_bottom_right.y());
shader_program_->setUniformValue("p2", coords.vertex_top_left.x(), coords.vertex_top_left.y());
shader_program_->setUniformValue("p3", coords.vertex_top_right.x(), coords.vertex_top_right.y());
shader_program_->setUniformValue("perspective", perspective->GetBoolAt(timecode));
}
void CornerPinEffect::gizmo_draw(double, GLTextureCoords &coords) {
top_left_gizmo->world_pos[0] = QPoint(coords.vertexTopLeftX, coords.vertexTopLeftY);
top_right_gizmo->world_pos[0] = QPoint(coords.vertexTopRightX, coords.vertexTopRightY);
bottom_right_gizmo->world_pos[0] = QPoint(coords.vertexBottomRightX, coords.vertexBottomRightY);
bottom_left_gizmo->world_pos[0] = QPoint(coords.vertexBottomLeftX, coords.vertexBottomLeftY);
top_left_gizmo->world_pos[0] = coords.vertex_top_left;
top_right_gizmo->world_pos[0] = coords.vertex_top_right;
bottom_right_gizmo->world_pos[0] = coords.vertex_bottom_right;
bottom_left_gizmo->world_pos[0] = coords.vertex_bottom_left;
}
+4 -9
View File
@@ -78,15 +78,10 @@ void ShakeEffect::process_coords(double timecode, GLTextureCoords& coords, int)
yoff *= multiplier;
rotoff *= rotmult;
coords.vertexTopLeftX += xoff;
coords.vertexTopRightX += xoff;
coords.vertexBottomLeftX += xoff;
coords.vertexBottomRightX += xoff;
coords.vertexTopLeftY += yoff;
coords.vertexTopRightY += yoff;
coords.vertexBottomLeftY += yoff;
coords.vertexBottomRightY += yoff;
coords.vertex_top_left += QVector3D(xoff, yoff, 0.0);
coords.vertex_top_right += QVector3D(xoff, yoff, 0.0);
coords.vertex_bottom_left += QVector3D(xoff, yoff, 0.0);
coords.vertex_bottom_right += QVector3D(xoff, yoff, 0.0);
glRotatef(rotoff, 0, 0, 1);
}
+2 -2
View File
@@ -151,8 +151,8 @@ TextEffect::TextEffect(Clip* c, const EffectMeta* em) :
connect(shadow_bool, SIGNAL(Toggled(bool)), this, SLOT(shadow_enable(bool)));
connect(outline_bool, SIGNAL(Toggled(bool)), this, SLOT(outline_enable(bool)));
vertPath = "common.vert";
fragPath = "dropshadow.frag";
shader_vert_path_ = "common.vert";
shader_frag_path_ = "dropshadow.frag";
}
void TextEffect::redraw(double timecode) {
+28 -21
View File
@@ -198,14 +198,10 @@ void TransformEffect::process_coords(double timecode, GLTextureCoords& coords, i
int anchor_x_offset = qRound(anchor_x_box->GetDoubleAt(timecode));
int anchor_y_offset = qRound(anchor_y_box->GetDoubleAt(timecode));
coords.vertexTopLeftX -= anchor_x_offset;
coords.vertexTopRightX -= anchor_x_offset;
coords.vertexBottomLeftX -= anchor_x_offset;
coords.vertexBottomRightX -= anchor_x_offset;
coords.vertexTopLeftY -= anchor_y_offset;
coords.vertexTopRightY -= anchor_y_offset;
coords.vertexBottomLeftY -= anchor_y_offset;
coords.vertexBottomRightY -= anchor_y_offset;
coords.vertex_top_left -= QVector3D(anchor_x_offset, anchor_y_offset, 0.0f);
coords.vertex_top_right -= QVector3D(anchor_x_offset, anchor_y_offset, 0.0f);
coords.vertex_bottom_left -= QVector3D(anchor_x_offset, anchor_y_offset, 0.0f);
coords.vertex_bottom_right -= QVector3D(anchor_x_offset, anchor_y_offset, 0.0f);
// rotation
glRotated(rotation->GetDoubleAt(timecode), 0, 0, 1);
@@ -223,19 +219,30 @@ void TransformEffect::process_coords(double timecode, GLTextureCoords& coords, i
}
void TransformEffect::gizmo_draw(double, GLTextureCoords& coords) {
top_left_gizmo->world_pos[0] = QPoint(coords.vertexTopLeftX, coords.vertexTopLeftY);
top_center_gizmo->world_pos[0] = QPoint(lerp(coords.vertexTopLeftX, coords.vertexTopRightX, 0.5), lerp(coords.vertexTopLeftY, coords.vertexTopRightY, 0.5));
top_right_gizmo->world_pos[0] = QPoint(coords.vertexTopRightX, coords.vertexTopRightY);
right_center_gizmo->world_pos[0] = QPoint(lerp(coords.vertexTopRightX, coords.vertexBottomRightX, 0.5), lerp(coords.vertexTopRightY, coords.vertexBottomRightY, 0.5));
bottom_right_gizmo->world_pos[0] = QPoint(coords.vertexBottomRightX, coords.vertexBottomRightY);
bottom_center_gizmo->world_pos[0] = QPoint(lerp(coords.vertexBottomRightX, coords.vertexBottomLeftX, 0.5), lerp(coords.vertexBottomRightY, coords.vertexBottomLeftY, 0.5));
bottom_left_gizmo->world_pos[0] = QPoint(coords.vertexBottomLeftX, coords.vertexBottomLeftY);
left_center_gizmo->world_pos[0] = QPoint(lerp(coords.vertexBottomLeftX, coords.vertexTopLeftX, 0.5), lerp(coords.vertexBottomLeftY, coords.vertexTopLeftY, 0.5));
top_left_gizmo->world_pos[0] = coords.vertex_top_left;
top_right_gizmo->world_pos[0] = coords.vertex_top_right;
bottom_right_gizmo->world_pos[0] = coords.vertex_bottom_right;
bottom_left_gizmo->world_pos[0] = coords.vertex_bottom_left;
rotate_gizmo->world_pos[0] = QPoint(lerp(top_center_gizmo->world_pos[0].x(), bottom_center_gizmo->world_pos[0].x(), -0.1), lerp(top_center_gizmo->world_pos[0].y(), bottom_center_gizmo->world_pos[0].y(), -0.1));
top_center_gizmo->world_pos[0] = QVector3D(lerp(coords.vertex_top_left.x(), coords.vertex_top_right.x(), 0.5),
lerp(coords.vertex_top_left.y(), coords.vertex_top_right.y(), 0.5),
0.0f);
right_center_gizmo->world_pos[0] = QVector3D(lerp(coords.vertex_top_right.x(), coords.vertex_bottom_right.x(), 0.5),
lerp(coords.vertex_top_right.y(), coords.vertex_bottom_right.y(), 0.5),
0.0f);
bottom_center_gizmo->world_pos[0] = QVector3D(lerp(coords.vertex_bottom_right.x(), coords.vertex_bottom_left.x(), 0.5),
lerp(coords.vertex_bottom_right.y(), coords.vertex_bottom_left.y(), 0.5),
0.0f);
left_center_gizmo->world_pos[0] = QVector3D(lerp(coords.vertex_bottom_left.x(), coords.vertex_top_left.x(), 0.5),
lerp(coords.vertex_bottom_left.y(), coords.vertex_top_left.y(), 0.5),
0.0f);
rect_gizmo->world_pos[0] = QPoint(coords.vertexTopLeftX, coords.vertexTopLeftY);
rect_gizmo->world_pos[1] = QPoint(coords.vertexTopRightX, coords.vertexTopRightY);
rect_gizmo->world_pos[2] = QPoint(coords.vertexBottomRightX, coords.vertexBottomRightY);
rect_gizmo->world_pos[3] = QPoint(coords.vertexBottomLeftX, coords.vertexBottomLeftY);
rotate_gizmo->world_pos[0] = QVector3D(lerp(top_center_gizmo->world_pos[0].x(), bottom_center_gizmo->world_pos[0].x(), -0.1),
lerp(top_center_gizmo->world_pos[0].y(), bottom_center_gizmo->world_pos[0].y(), -0.1),
0.0f);
rect_gizmo->world_pos[0] = coords.vertex_top_left;
rect_gizmo->world_pos[1] = coords.vertex_top_right;
rect_gizmo->world_pos[2] = coords.vertex_bottom_right;
rect_gizmo->world_pos[3] = coords.vertex_bottom_left;
}
+4 -2
View File
@@ -175,7 +175,8 @@ SOURCES += \
undo/undostack.cpp \
effects/internal/richtexteffect.cpp \
ui/blur.cpp \
ui/menu.cpp
ui/menu.cpp \
rendering/qopenglshaderprogramptr.cpp
HEADERS += \
ui/mainwindow.h \
@@ -304,7 +305,8 @@ HEADERS += \
undo/undostack.h \
effects/internal/richtexteffect.h \
ui/blur.h \
ui/menu.h
ui/menu.h \
rendering/qopenglshaderprogramptr.h
FORMS +=
+9 -5
View File
@@ -41,19 +41,23 @@ void FramebufferObject::Create(QOpenGLContext *ctx, int width, int height)
ctx->functions()->glBindTexture(GL_TEXTURE_2D, texture_);
// allocate storage for texture
glTexImage2D(
GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA8, GL_UNSIGNED_BYTE, nullptr
ctx->functions()->glTexImage2D(
GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr
);
// set texture filtering to bilinear
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
ctx->functions()->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
ctx->functions()->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// attach texture to framebuffer
ctx->extraFunctions()->glFramebufferTexture2D(
GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture_, 0
GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture_, 0
);
// clear new texture
ctx->functions()->glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
ctx->functions()->glClear(GL_COLOR_BUFFER_BIT);
// release texture
ctx->functions()->glBindTexture(GL_TEXTURE_2D, 0);
+2
View File
@@ -0,0 +1,2 @@
#include "qopenglshaderprogramptr.h"
+8
View File
@@ -0,0 +1,8 @@
#ifndef QOPENGLSHADERPROGRAMPTR_H
#define QOPENGLSHADERPROGRAMPTR_H
#include <QOpenGLShaderProgram>
using QOpenGLShaderProgramPtr = std::shared_ptr<QOpenGLShaderProgram>;
#endif // QOPENGLSHADERPROGRAMPTR_H
+145 -121
View File
@@ -39,71 +39,111 @@ namespace OCIO = OCIO_NAMESPACE;
#include "effects/effect.h"
#include "project/footage.h"
#include "effects/transition.h"
#include "ui/collapsiblewidget.h"
#include "rendering/audio.h"
#include "global/math.h"
#include "global/config.h"
#include "panels/timeline.h"
#include "panels/viewer.h"
#include "qopenglshaderprogramptr.h"
void full_blit() {
glPushMatrix();
glLoadIdentity();
glOrtho(0, 1, 0, 1, -1, 1);
GLfloat olive::rendering::blit_vertices[] = {
-1.0f, -1.0f, 0.0f,
1.0f, -1.0f, 0.0f,
1.0f, 1.0f, 0.0f,
glBegin(GL_QUADS);
glTexCoord2f(0, 0); // top left
glVertex2f(0, 0); // top left
glTexCoord2f(1, 0); // top right
glVertex2f(1, 0); // top right
glTexCoord2f(1, 1); // bottom right
glVertex2f(1, 1); // bottom right
glTexCoord2f(0, 1); // bottom left
glVertex2f(0, 1); // bottom left
glEnd();
-1.0f, -1.0f, 0.0f,
-1.0f, 1.0f, 0.0f,
1.0f, 1.0f, 0.0f
};
glPopMatrix();
GLfloat olive::rendering::blit_texcoords[] = {
0.0, 0.0,
1.0, 0.0,
1.0, 1.0,
0.0, 0.0,
0.0, 1.0,
1.0, 1.0
};
void olive::rendering::Blit(QOpenGLShaderProgram* pipeline) {
QOpenGLFunctions* func = QOpenGLContext::currentContext()->functions();
pipeline->bind();
pipeline->setUniformValue("mvp_matrix", QMatrix4x4());
pipeline->setUniformValue("texture", 0);
GLuint vertex_location = pipeline->attributeLocation("a_position");
func->glEnableVertexAttribArray(vertex_location);
func->glVertexAttribPointer(vertex_location, 3, GL_FLOAT, GL_FALSE, 0, blit_vertices);
GLuint tex_location = pipeline->attributeLocation("a_texcoord");
func->glEnableVertexAttribArray(tex_location);
func->glVertexAttribPointer(tex_location, 2, GL_FLOAT, GL_FALSE, 0, blit_texcoords);
func->glDrawArrays(GL_TRIANGLES, 0, 6);
pipeline->release();
}
void draw_clip(QOpenGLContext* ctx, GLuint fbo, GLuint texture, bool clear) {
QOpenGLShaderProgramPtr olive::rendering::GetPipeline()
{
QOpenGLShaderProgramPtr program = std::make_shared<QOpenGLShaderProgram>();
program->addShaderFromSourceFile(QOpenGLShader::Vertex, ":/internalshaders/pipeline.vert");
program->addShaderFromSourceFile(QOpenGLShader::Fragment, ":/internalshaders/pipeline.frag");
program->link();
return program;
}
void draw_clip(QOpenGLContext* ctx,
QOpenGLShaderProgram* pipeline,
GLuint fbo,
GLuint texture,
bool clear) {
ctx->functions()->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
if (clear) {
glClear(GL_COLOR_BUFFER_BIT);
ctx->functions()->glClear(GL_COLOR_BUFFER_BIT);
}
glBindTexture(GL_TEXTURE_2D, texture);
ctx->functions()->glBindTexture(GL_TEXTURE_2D, texture);
full_blit();
olive::rendering::Blit(pipeline);
glBindTexture(GL_TEXTURE_2D, 0);
ctx->functions()->glBindTexture(GL_TEXTURE_2D, 0);
ctx->functions()->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
}
GLuint draw_clip(const FramebufferObject& fbo, GLuint texture, bool clear) {
GLuint draw_clip(QOpenGLContext* ctx,
QOpenGLShaderProgram* pipeline,
const FramebufferObject& fbo,
GLuint texture,
bool clear) {
fbo.BindBuffer();
if (clear) {
glClear(GL_COLOR_BUFFER_BIT);
ctx->functions()->glClear(GL_COLOR_BUFFER_BIT);
}
glBindTexture(GL_TEXTURE_2D, texture);
ctx->functions()->glBindTexture(GL_TEXTURE_2D, texture);
full_blit();
olive::rendering::Blit(pipeline);
glBindTexture(GL_TEXTURE_2D, 0);
ctx->functions()->glBindTexture(GL_TEXTURE_2D, 0);
fbo.ReleaseBuffer();
return fbo.texture();
}
void process_effect(Clip* c,
void process_effect(QOpenGLContext* ctx,
QOpenGLShaderProgram* pipeline,
Clip* c,
Effect* e,
double timecode,
GLTextureCoords& coords,
@@ -121,7 +161,7 @@ void process_effect(Clip* c,
if (can_process_shaders && e->is_glsl_linked()) {
for (int i=0;i<e->getIterations();i++) {
e->process_shader(timecode, coords, i);
composite_texture = draw_clip(c->fbo[fbo_switcher], composite_texture, true);
composite_texture = draw_clip(ctx, pipeline, c->fbo[fbo_switcher], composite_texture, true);
fbo_switcher = !fbo_switcher;
}
}
@@ -140,10 +180,10 @@ void process_effect(Clip* c,
// if the source texture is not already a framebuffer texture,
// we'll need to make it one before drawing a superimpose effect on it
if (composite_texture != c->fbo[0].texture() && composite_texture != c->fbo[1].texture()) {
draw_clip(c->fbo[!fbo_switcher], composite_texture, true);
draw_clip(ctx, pipeline, c->fbo[!fbo_switcher], composite_texture, true);
}
composite_texture = draw_clip(c->fbo[!fbo_switcher], superimpose_texture, false);
composite_texture = draw_clip(ctx, pipeline, c->fbo[!fbo_switcher], superimpose_texture, false);
}
}
e->endEffect();
@@ -152,8 +192,6 @@ void process_effect(Clip* c,
}
GLuint compose_sequence(ComposeSequenceParams &params) {
// qint64 time = QDateTime::currentMSecsSinceEpoch();
GLuint final_fbo = params.main_buffer;
Sequence* s = params.seq;
@@ -266,16 +304,19 @@ GLuint compose_sequence(ComposeSequenceParams &params) {
}
}
QMatrix4x4 projection;
if (params.video) {
// set default coordinates based on the sequence, with 0 in the direct center
glPushMatrix();
glLoadIdentity();
//glPushMatrix();
//glLoadIdentity();
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
params.ctx->functions()->glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
int half_width = s->width/2;
int half_height = s->height/2;
glOrtho(-half_width, half_width, -half_height, half_height, -1, 10);
//glOrtho(-half_width, half_width, -half_height, half_height, -1, 10);
projection.ortho(-half_width, half_width, -half_height, half_height, -1, 1);
}
// loop through current clips
@@ -296,9 +337,6 @@ GLuint compose_sequence(ComposeSequenceParams &params) {
// if clip is a video clip
if (c->track() < 0) {
// reset OpenGL to full color
glColor4f(1.0, 1.0, 1.0, 1.0);
// textureID variable contains texture to be drawn on screen at the end
GLuint textureID = 0;
@@ -316,7 +354,6 @@ GLuint compose_sequence(ComposeSequenceParams &params) {
} else {
// retrieve ID from c->texture
textureID = c->texture->textureId();
qDebug() << "tex 1" << textureID;
}
if (textureID == 0) {
@@ -339,15 +376,15 @@ GLuint compose_sequence(ComposeSequenceParams &params) {
// if clip should actually be shown on screen in this frame
if (playhead >= c->timeline_in(true)
&& playhead < c->timeline_out(true)) {
glPushMatrix();
// simple bool for switching between the two framebuffers
bool fbo_switcher = false;
glViewport(0, 0, video_width, video_height);
params.ctx->functions()->glViewport(0, 0, video_width, video_height);
if (c->media() != nullptr) {
if (c->media()->get_type() == MEDIA_TYPE_SEQUENCE) {
// for a nested sequence, run this function again on that sequence and retrieve the texture
// add nested sequence to nest list
@@ -361,6 +398,7 @@ GLuint compose_sequence(ComposeSequenceParams &params) {
// compose_sequence() would have written to this clip's fbo[0], so we switch to fbo[1]
fbo_switcher = !fbo_switcher;
} else if (c->media()->get_type() == MEDIA_TYPE_FOOTAGE) {
if (!c->media()->to_footage()->alpha_is_premultiplied) {
@@ -368,13 +406,11 @@ GLuint compose_sequence(ComposeSequenceParams &params) {
// 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);
qDebug() << "about to draw on" << fbo_switcher;
textureID = draw_clip(c->fbo[fbo_switcher], textureID, true);
textureID = draw_clip(params.ctx, params.pipeline, c->fbo[fbo_switcher], textureID, true);
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
params.ctx->functions()->glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
fbo_switcher = !fbo_switcher;
qDebug() << "tex 3" << textureID << fbo_switcher;
}
@@ -387,14 +423,12 @@ GLuint compose_sequence(ComposeSequenceParams &params) {
params.ocio_shader->setUniformValue("tex1", 0);
params.ocio_shader->setUniformValue("tex2", 2);
qDebug() << "about to draw on" << fbo_switcher;
textureID = draw_clip(c->fbo[fbo_switcher], textureID, true);
textureID = draw_clip(params.ctx, params.pipeline, c->fbo[fbo_switcher], textureID, true);
params.ocio_shader->release();
fbo_switcher = !fbo_switcher;
qDebug() << "tex 4" << textureID << fbo_switcher;
}
#endif
@@ -403,15 +437,14 @@ GLuint compose_sequence(ComposeSequenceParams &params) {
// set up default coordinates for drawing the clip
GLTextureCoords coords;
coords.grid_size = 1;
coords.vertexTopLeftX = coords.vertexBottomLeftX = -video_width/2;
coords.vertexTopLeftY = coords.vertexTopRightY = -video_height/2;
coords.vertexTopRightX = coords.vertexBottomRightX = video_width/2;
coords.vertexBottomLeftY = coords.vertexBottomRightY = video_height/2;
coords.vertexBottomLeftZ = coords.vertexBottomRightZ = coords.vertexTopLeftZ = coords.vertexTopRightZ = 1;
coords.textureTopLeftY = coords.textureTopRightY = coords.textureTopLeftX = coords.textureBottomLeftX = 0.0;
coords.textureBottomLeftY = coords.textureBottomRightY = coords.textureTopRightX = coords.textureBottomRightX = 1.0;
coords.textureTopLeftQ = coords.textureTopRightQ = coords.textureTopLeftQ = coords.textureBottomLeftQ = 1;
coords.vertex_top_left = QVector3D(-video_width/2, -video_height/2, 0.0f);
coords.vertex_top_right = QVector3D(video_width/2, -video_height/2, 0.0f);
coords.vertex_bottom_left = QVector3D(-video_width/2, video_height/2, 0.0f);
coords.vertex_bottom_right = QVector3D(video_width/2, video_height/2, 0.0f);
coords.texture_top_left = QVector2D(0.0f, 0.0f);
coords.texture_top_right = QVector2D(1.0f, 0.0f);
coords.texture_bottom_left = QVector2D(0.0f, 1.0f);
coords.texture_bottom_right = QVector2D(1.0f, 1.0f);
coords.blendmode = -1;
coords.opacity = 1.0;
@@ -424,9 +457,7 @@ GLuint compose_sequence(ComposeSequenceParams &params) {
for (int j=0;j<c->effects.size();j++) {
Effect* e = c->effects.at(j).get();
qDebug() << "about to draw on" << fbo_switcher;
process_effect(c, e, timecode, coords, textureID, fbo_switcher, params.texture_failed, kTransitionNone);
qDebug() << "tex 5" << textureID << fbo_switcher;
process_effect(params.ctx, params.pipeline, c, e, timecode, coords, textureID, fbo_switcher, params.texture_failed, kTransitionNone);
}
@@ -435,7 +466,7 @@ GLuint compose_sequence(ComposeSequenceParams &params) {
if (c->opening_transition != nullptr) {
int transition_progress = playhead - c->timeline_in(true);
if (transition_progress < c->opening_transition->get_length()) {
process_effect(c, c->opening_transition.get(), double(transition_progress)/double(c->opening_transition->get_length()), coords, textureID, fbo_switcher, params.texture_failed, kTransitionOpening);
process_effect(params.ctx, params.pipeline, c, c->opening_transition.get(), double(transition_progress)/double(c->opening_transition->get_length()), coords, textureID, fbo_switcher, params.texture_failed, kTransitionOpening);
}
}
@@ -443,14 +474,16 @@ GLuint compose_sequence(ComposeSequenceParams &params) {
if (c->closing_transition != nullptr) {
int transition_progress = playhead - (c->timeline_out(true) - c->closing_transition->get_length());
if (transition_progress >= 0 && transition_progress < c->closing_transition->get_length()) {
process_effect(c, c->closing_transition.get(), double(transition_progress)/double(c->closing_transition->get_length()), coords, textureID, fbo_switcher, params.texture_failed, kTransitionClosing);
process_effect(params.ctx, params.pipeline, c, c->closing_transition.get(), double(transition_progress)/double(c->closing_transition->get_length()), coords, textureID, fbo_switcher, params.texture_failed, kTransitionClosing);
}
}
// == EFFECT CODE END ==
// Check whether the parent clip is auto-scaledc
// Check whether the parent clip is auto-scaled
// TODO redo this
/*
if (c->autoscaled()
&& (video_width != s->width
&& video_height != s->height)) {
@@ -459,6 +492,7 @@ GLuint compose_sequence(ComposeSequenceParams &params) {
float scale_multiplier = qMin(width_multiplier, height_multiplier);
glScalef(scale_multiplier, scale_multiplier, 1);
}
*/
// Configure effect gizmos if they exist
if (params.gizmos != nullptr) {
@@ -468,7 +502,6 @@ GLuint compose_sequence(ComposeSequenceParams &params) {
qDebug() << "final texture ID" << textureID;
if (textureID > 0) {
// set viewport to sequence size
params.ctx->functions()->glViewport(0, 0, s->width, s->height);
@@ -496,32 +529,57 @@ GLuint compose_sequence(ComposeSequenceParams &params) {
// render a backbuffer
params.ctx->functions()->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, back_buffer_1);
glClearColor(0.0, 0.0, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT);
params.ctx->functions()->glClearColor(0.0, 0.0, 0.0, 0.0);
params.ctx->functions()->glClear(GL_COLOR_BUFFER_BIT);
// bind final clip texture
glBindTexture(GL_TEXTURE_2D, textureID);
params.ctx->functions()->glBindTexture(GL_TEXTURE_2D, textureID);
// set texture filter to bilinear
params.ctx->functions()->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
params.ctx->functions()->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// draw clip on screen according to gl coordinates
glBegin(GL_QUADS);
params.pipeline->bind();
glTexCoord2f(coords.textureTopLeftX, coords.textureTopLeftY); // top left
glVertex2f(coords.vertexTopLeftX, coords.vertexTopLeftY); // top left
glTexCoord2f(coords.textureTopRightX, coords.textureTopRightY); // top right
glVertex2f(coords.vertexTopRightX, coords.vertexTopRightY); // top right
glTexCoord2f(coords.textureBottomRightX, coords.textureBottomRightY); // bottom right
glVertex2f(coords.vertexBottomRightX, coords.vertexBottomRightY); // bottom right
glTexCoord2f(coords.textureBottomLeftX, coords.textureBottomLeftY); // bottom left
glVertex2f(coords.vertexBottomLeftX, coords.vertexBottomLeftY); // bottom left
params.pipeline->setUniformValue("mvp_matrix", projection);
params.pipeline->setUniformValue("texture", 0);
glEnd();
GLfloat vertices[] = {
coords.vertex_top_left.x(), coords.vertex_top_left.y(), 0.0f,
coords.vertex_top_right.x(), coords.vertex_top_right.y(), 0.0f,
coords.vertex_bottom_right.x(), coords.vertex_bottom_right.y(), 0.0f,
coords.vertex_top_left.x(), coords.vertex_top_left.y(), 0.0f,
coords.vertex_bottom_left.x(), coords.vertex_bottom_left.y(), 0.0f,
coords.vertex_bottom_right.x(), coords.vertex_bottom_right.y(), 0.0f,
};
GLfloat texcoords[] = {
coords.texture_top_left.x(), coords.texture_top_left.y(),
coords.texture_top_right.x(), coords.texture_top_right.y(),
coords.texture_bottom_right.x(), coords.texture_bottom_right.y(),
coords.texture_top_left.x(), coords.texture_top_left.y(),
coords.texture_bottom_left.x(), coords.texture_bottom_left.y(),
coords.texture_bottom_right.x(), coords.texture_bottom_right.y(),
};
GLuint vertex_location = params.pipeline->attributeLocation("a_position");
params.ctx->functions()->glEnableVertexAttribArray(vertex_location);
params.ctx->functions()->glVertexAttribPointer(vertex_location, 3, GL_FLOAT, GL_FALSE, 0, vertices);
GLuint tex_location = params.pipeline->attributeLocation("a_texcoord");
params.ctx->functions()->glEnableVertexAttribArray(tex_location);
params.ctx->functions()->glVertexAttribPointer(tex_location, 2, GL_FLOAT, GL_FALSE, 0, texcoords);
params.ctx->functions()->glDrawArrays(GL_TRIANGLES, 0, 6);
params.pipeline->release();
// release final clip texture
glBindTexture(GL_TEXTURE_2D, 0);
params.ctx->functions()->glBindTexture(GL_TEXTURE_2D, 0);
params.ctx->functions()->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
@@ -542,9 +600,9 @@ GLuint compose_sequence(ComposeSequenceParams &params) {
// copy front buffer to back buffer (only if we're using a blending mode)
if (coords.blendmode >= 0) {
if (params.nests.size() > 0) {
draw_clip(params.ctx, params.nests.last()->fbo[2].buffer(), params.nests.last()->fbo[0].texture(), true);
draw_clip(params.ctx, params.pipeline, params.nests.last()->fbo[2].buffer(), params.nests.last()->fbo[0].texture(), true);
} else {
draw_clip(params.ctx, params.backend_buffer2, params.main_attachment, true);
draw_clip(params.ctx, params.pipeline, params.backend_buffer2, params.main_attachment, true);
}
}
@@ -561,20 +619,14 @@ GLuint compose_sequence(ComposeSequenceParams &params) {
// Check if we're using a blend mode (< 0 means no blend mode)
if (coords.blendmode < 0) {
qDebug() << "normal blending";
params.ctx->functions()->glBindTexture(GL_TEXTURE_2D, backend_tex_1);
glColor4f(coords.opacity, coords.opacity, coords.opacity, coords.opacity);
full_blit();
olive::rendering::Blit(params.pipeline);
params.ctx->functions()->glBindTexture(GL_TEXTURE_2D, 0);
} else {
qDebug() << "blending mode?";
// load background texture into texture unit 0
params.ctx->functions()->glActiveTexture(GL_TEXTURE0 + 0); // Texture unit 0
params.ctx->functions()->glBindTexture(GL_TEXTURE_2D, backend_tex_2);
@@ -590,9 +642,9 @@ GLuint compose_sequence(ComposeSequenceParams &params) {
params.blend_mode_program->setUniformValue("background", 0);
params.blend_mode_program->setUniformValue("foreground", 1);
glClear(GL_COLOR_BUFFER_BIT);
params.ctx->functions()->glClear(GL_COLOR_BUFFER_BIT);
full_blit();
olive::rendering::Blit(params.pipeline);
// release blend mode shader
params.blend_mode_program->release();
@@ -615,18 +667,6 @@ GLuint compose_sequence(ComposeSequenceParams &params) {
// == END FINAL DRAW ON SEQUENCE BUFFER ==
}
// prepare gizmos
/*
if ((*params.gizmos) != nullptr
&& params.nests.isEmpty()
&& ((*params.gizmos) == first_gizmo_effect
|| (*params.gizmos) == selected_effect)) {
(*params.gizmos)->gizmo_draw(timecode, coords); // set correct gizmo coords
(*params.gizmos)->gizmo_world_to_screen(); // convert gizmo coords to screen coords
}
*/
glPopMatrix();
}
} else {
if (c->media() != nullptr && c->media()->get_type() == MEDIA_TYPE_SEQUENCE) {
@@ -646,22 +686,6 @@ GLuint compose_sequence(ComposeSequenceParams &params) {
}
}
/*
// visually update all the keyframe values
if (c->sequence == params.seq) { // only if you can currently see them
double ts = (playhead - c->timeline_in(true) + c->clip_in(true))/s->frame_rate;
for (int i=0;i<c->effects.size();i++) {
EffectPtr e = c->effects.at(i);
for (int j=0;j<e->row_count();j++) {
EffectRow* r = e->row(j);
for (int k=0;k<r->fieldCount();k++) {
r->field(k)->validate_keyframe_data(ts);
}
}
}
}
*/
}
} else {
params.texture_failed = true;
+16
View File
@@ -52,6 +52,13 @@ struct ComposeSequenceParams {
*/
QOpenGLContext* ctx;
/**
* @brief The OpenGL pipeline used for rendering
*
* \see olive::rendering::GetPipeline().
*/
QOpenGLShaderProgram* pipeline;
/**
* @brief The sequence to compose
*
@@ -403,4 +410,13 @@ void close_active_clips(Sequence* s);
void UpdateOCIOGLState(const ComposeSequenceParams &params);
namespace olive {
namespace rendering {
extern GLfloat blit_vertices[];
extern GLfloat blit_texcoords[];
void Blit(QOpenGLShaderProgram* pipeline);
QOpenGLShaderProgramPtr GetPipeline();
}
}
#endif // RENDERFUNCTIONS_H
+33 -41
View File
@@ -32,10 +32,10 @@
namespace OCIO = OCIO_NAMESPACE;
#endif
#include "rendering/renderfunctions.h"
#include "timeline/sequence.h"
#include "effects/effectloaders.h"
#include "global/config.h"
#include "rendering/renderfunctions.h"
RenderThread::RenderThread() :
gizmos(nullptr),
@@ -102,12 +102,14 @@ void RenderThread::run() {
if (blend_mode_program == nullptr) {
delete_shaders();
blend_mode_program = new QOpenGLShaderProgram();
blend_mode_program = std::make_shared<QOpenGLShaderProgram>();
blend_mode_program->addShaderFromSourceFile(QOpenGLShader::Vertex, ":/internalshaders/common.vert");
olive::effects_loaded.lock();
blend_mode_program->addShaderFromSourceCode(QOpenGLShader::Fragment, olive::generated_blending_shader);
olive::effects_loaded.unlock();
blend_mode_program->link();
pipeline_program = olive::rendering::GetPipeline();
}
#ifndef NO_OCIO
@@ -148,15 +150,15 @@ const GLuint &RenderThread::get_texture()
}
const char * g_fragShaderText = ""
"\n"
"uniform sampler2D tex1;\n"
"uniform sampler3D tex2;\n"
"\n"
"void main()\n"
"{\n"
" vec4 col = texture2D(tex1, gl_TexCoord[0].st);\n"
" gl_FragColor = OCIODisplay(col, tex2);\n"
"}\n";
"\n"
"uniform sampler2D tex1;\n"
"uniform sampler3D tex2;\n"
"\n"
"void main()\n"
"{\n"
" vec4 col = texture2D(tex1, gl_TexCoord[0].st);\n"
" gl_FragColor = OCIODisplay(col, tex2);\n"
"}\n";
#ifndef NO_OCIO
void RenderThread::set_up_ocio()
@@ -182,8 +184,8 @@ void RenderThread::set_up_ocio()
// Allocate storage for texture
ctx->extraFunctions()->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, ocio_lut_data);
OCIO_LUT3D_EDGE_SIZE, OCIO_LUT3D_EDGE_SIZE, OCIO_LUT3D_EDGE_SIZE,
0, GL_RGB,GL_FLOAT, ocio_lut_data);
//
// SET UP OCIO DISPLAY
@@ -240,17 +242,17 @@ void RenderThread::set_up_ocio()
processor->getGpuLut3D(ocio_lut_data, shaderDesc);
glBindTexture(GL_TEXTURE_3D, ocio_lut_texture);
ctx->extraFunctions()->glBindTexture(GL_TEXTURE_3D, ocio_lut_texture);
ctx->extraFunctions()->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);
0, 0, 0,
OCIO_LUT3D_EDGE_SIZE, OCIO_LUT3D_EDGE_SIZE, OCIO_LUT3D_EDGE_SIZE,
GL_RGB,GL_FLOAT, ocio_lut_data);
QString shader_text = processor->getGpuShaderText(shaderDesc);
shader_text.append("\n");
shader_text.append(g_fragShaderText);
ocio_shader = new QOpenGLShaderProgram();
ocio_shader = std::make_shared<QOpenGLShaderProgram>();
ocio_shader->addShaderFromSourceCode(QOpenGLShader::Fragment, shader_text);
ocio_shader->link();
@@ -264,7 +266,6 @@ void RenderThread::destroy_ocio()
ctx->functions()->glDeleteTextures(1, &ocio_lut_texture);
ocio_lut_texture = 0;
delete ocio_shader;
ocio_shader = nullptr;
}
#endif
@@ -279,9 +280,10 @@ void RenderThread::paint() {
params.texture_failed = false;
params.wait_for_mutexes = true;
params.playback_speed = 1;
params.blend_mode_program = blend_mode_program;
params.blend_mode_program = blend_mode_program.get();
params.pipeline = pipeline_program.get();
#ifndef NO_OCIO
params.ocio_shader = ocio_shader;
params.ocio_shader = ocio_shader.get();
#endif
params.backend_buffer1 = back_buffer_1.buffer();
params.backend_buffer2 = back_buffer_2.buffer();
@@ -300,15 +302,8 @@ void RenderThread::paint() {
// bind framebuffer for drawing
ctx->functions()->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, params.main_buffer);
glLoadIdentity();
glClearColor(0.0, 0.0, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
ctx->functions()->glClearColor(0.0, 0.0, 0.0, 0.0);
ctx->functions()->glClear(GL_COLOR_BUFFER_BIT);
compose_sequence(params);
@@ -339,13 +334,13 @@ void RenderThread::paint() {
ctx->functions()->glBindFramebuffer(GL_READ_FRAMEBUFFER, params.main_buffer);
// store pixels in buffer
glReadPixels(0,
0,
pixel_buffer_linesize == 0 ? tex_width : pixel_buffer_linesize,
tex_height,
GL_RGBA,
GL_UNSIGNED_BYTE,
pixel_buffer);
ctx->functions()->glReadPixels(0,
0,
pixel_buffer_linesize == 0 ? tex_width : pixel_buffer_linesize,
tex_height,
GL_RGBA,
GL_UNSIGNED_BYTE,
pixel_buffer);
// release current read buffer
ctx->functions()->glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
@@ -353,9 +348,6 @@ void RenderThread::paint() {
pixel_buffer = nullptr;
}
glDisable(GL_BLEND);
glDisable(GL_TEXTURE_2D);
// release
ctx->functions()->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
}
@@ -410,8 +402,8 @@ void RenderThread::delete_buffers() {
}
void RenderThread::delete_shaders() {
delete blend_mode_program;
blend_mode_program = nullptr;
pipeline_program = nullptr;
}
void RenderThread::delete_ctx() {
+4 -2
View File
@@ -32,6 +32,7 @@
#include "timeline/sequence.h"
#include "effects/effect.h"
#include "rendering/framebufferobject.h"
#include "qopenglshaderprogramptr.h"
#ifndef NO_OCIO
// copied from source code to OCIODisplay
@@ -81,7 +82,7 @@ private:
// OpenColorIO variables
float ocio_lut_data[OCIO_NUM_3D_ENTRIES];
GLuint ocio_lut_texture;
QOpenGLShaderProgram* ocio_shader;
QOpenGLShaderProgramPtr ocio_shader;
QString ocio_loaded_config;
#endif
@@ -102,7 +103,8 @@ private:
QOffscreenSurface surface;
QOpenGLContext* share_ctx;
QOpenGLContext* ctx;
QOpenGLShaderProgram* blend_mode_program;
QOpenGLShaderProgramPtr blend_mode_program;
QOpenGLShaderProgramPtr pipeline_program;
FramebufferObject back_buffer_1;
FramebufferObject back_buffer_2;
+4 -2
View File
@@ -573,7 +573,9 @@ bool Clip::Retrieve()
texture->allocateStorage(QOpenGLTexture::RGBA, QOpenGLTexture::UInt8);
}
glPixelStorei(GL_UNPACK_ROW_LENGTH, frame->linesize[0]/kRGBAComponentCount);
QOpenGLFunctions* f = QOpenGLContext::currentContext()->functions();
f->glPixelStorei(GL_UNPACK_ROW_LENGTH, frame->linesize[0]/kRGBAComponentCount);
// 2 data buffers to ping-pong between
bool using_db_1 = true;
@@ -611,7 +613,7 @@ bool Clip::Retrieve()
delete [] data_buffer_2;
}
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
f->glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
ret = true;
} else {
+25 -104
View File
@@ -71,8 +71,7 @@ ViewerWidget::ViewerWidget(QWidget *parent) :
gizmos(nullptr),
selected_gizmo(nullptr),
x_scroll(0),
y_scroll(0),
pipeline_(nullptr)
y_scroll(0)
{
setMouseTracking(true);
setFocusPolicy(Qt::ClickFocus);
@@ -80,19 +79,14 @@ ViewerWidget::ViewerWidget(QWidget *parent) :
setContextMenuPolicy(Qt::CustomContextMenu);
connect(this, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(show_context_menu()));
renderer = new RenderThread();
renderer->start(QThread::HighestPriority);
connect(renderer, SIGNAL(ready()), this, SLOT(queue_repaint()));
connect(renderer, SIGNAL(finished()), renderer, SLOT(deleteLater()));
renderer.start(QThread::HighestPriority);
connect(&renderer, SIGNAL(ready()), this, SLOT(queue_repaint()));
window = new ViewerWindow(this);
projection_.setToIdentity();
}
ViewerWidget::~ViewerWidget() {
renderer->cancel();
delete renderer;
renderer.cancel();
}
void ViewerWidget::delete_function() {
@@ -174,7 +168,7 @@ void ViewerWidget::save_frame() {
fn += selected_ext;
}
renderer->start_render(context(), viewer->seq.get(), fn);
renderer.start_render(context(), viewer->seq.get(), fn);
}
}
@@ -226,10 +220,7 @@ void ViewerWidget::initializeGL() {
connect(context(), SIGNAL(aboutToBeDestroyed()), this, SLOT(context_destroy()), Qt::DirectConnection);
pipeline_ = new QOpenGLShaderProgram();
pipeline_->addShaderFromSourceFile(QOpenGLShader::Vertex, ":/internalshaders/pipeline.vert");
pipeline_->addShaderFromSourceFile(QOpenGLShader::Fragment, ":/internalshaders/pipeline.frag");
pipeline_->link();
pipeline_ = olive::rendering::GetPipeline();
}
void ViewerWidget::frame_update() {
@@ -239,7 +230,7 @@ void ViewerWidget::frame_update() {
update();
} else {
doneCurrent();
renderer->start_render(context(), viewer->seq.get());
renderer.start_render(context(), viewer->seq.get());
}
// render the audio
@@ -248,7 +239,7 @@ void ViewerWidget::frame_update() {
}
RenderThread *ViewerWidget::get_renderer() {
return renderer;
return &renderer;
}
void ViewerWidget::set_scroll(double x, double y) {
@@ -268,9 +259,8 @@ void ViewerWidget::context_destroy() {
close_active_clips(viewer->seq.get());
}
renderer->delete_ctx();
renderer.delete_ctx();
delete pipeline_;
pipeline_ = nullptr;
doneCurrent();
@@ -556,86 +546,28 @@ void ViewerWidget::draw_gizmos() {
}
void ViewerWidget::paintGL() {
QOpenGLFunctions* f = context()->functions();
QOpenGLExtraFunctions* xf = context()->extraFunctions();
f->glClearColor(0.0, 0.0, 0.0, 0.0);
GLfloat vertices[] = {
-1.0f, -1.0f, -1.0f,
1.0f, -1.0f, -1.0f,
1.0f, 1.0f, -1.0f,
-1.0f, -1.0f, -1.0f,
-1.0f, 1.0f, -1.0f,
1.0f, 1.0f, -1.0f,
};
GLfloat tex_coords[] = {
0.0, 0.0,
1.0, 0.0,
1.0, 1.0,
0.0, 0.0,
0.0, 1.0,
1.0, 1.0
};
f->glViewport(0, 0, width(), height());
f->glClear(GL_COLOR_BUFFER_BIT);
QOpenGLTexture texture(QImage("C:/Users/Matt/Desktop/bliss.png"));
pipeline_->bind();
texture.bind();
pipeline_->setUniformValue("mvp_matrix", projection_);
pipeline_->setUniformValue("texture", 0);
GLuint vertex_location = pipeline_->attributeLocation("a_position");
f->glEnableVertexAttribArray(vertex_location);
f->glVertexAttribPointer(vertex_location, 3, GL_FLOAT, GL_FALSE, 0, vertices);
GLuint tex_location = pipeline_->attributeLocation("a_texcoord");
f->glEnableVertexAttribArray(tex_location);
f->glVertexAttribPointer(tex_location, 2, GL_FLOAT, GL_FALSE, 0, tex_coords);
f->glDrawArrays(GL_TRIANGLES, 0, 6);
texture.release();
pipeline_->release();
/*
if (waveform) {
draw_waveform_func();
} else {
const GLuint tex = renderer->get_texture();
QMutex* tex_lock = renderer->get_texture_mutex();
const GLuint tex = renderer.get_texture();
QMutex* tex_lock = renderer.get_texture_mutex();
tex_lock->lock();
QOpenGLFunctions* f = context()->functions();
//QOpenGLExtraFunctions* xf = context()->extraFunctions();
makeCurrent();
// clear to solid black
glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT);
f->glClearColor(0.0, 0.0, 0.0, 0.0);
f->glClear(GL_COLOR_BUFFER_BIT);
// set color multipler to straight white
glColor4f(1.0, 1.0, 1.0, 1.0);
glEnable(GL_TEXTURE_2D);
// set screen coords to widget size
glLoadIdentity();
glOrtho(-1, 1, -1, 1, -1, 1);
// draw texture from render thread
glBindTexture(GL_TEXTURE_2D, tex);
glBegin(GL_QUADS);
// TODO fix zooming
double zoom_factor = container->zoom/(double(width())/double(viewer->seq->width));
double zoom_size = (zoom_factor*2.0) - 2.0;
double zoom_left = -zoom_size*x_scroll - 1.0;
@@ -643,45 +575,34 @@ void ViewerWidget::paintGL() {
double zoom_bottom = -zoom_size*(1.0-y_scroll) - 1.0;
double zoom_top = zoom_size*(y_scroll) + 1.0;
//zoom_left *= ar_diff;
//zoom_right *= ar_diff;
glVertex2d(zoom_left, zoom_bottom);
glTexCoord2d(0, 0);
glVertex2d(zoom_left, zoom_top);
glTexCoord2d(1, 0);
glVertex2d(zoom_right, zoom_top);
glTexCoord2d(1, 1);
glVertex2d(zoom_right, zoom_bottom);
glTexCoord2d(0, 1);
f->glViewport(0, 0, width(), height());
glEnd();
f->glBindTexture(GL_TEXTURE_2D, tex);
glBindTexture(GL_TEXTURE_2D, 0);
olive::rendering::Blit(pipeline_.get());
f->glBindTexture(GL_TEXTURE_2D, 0);
// draw title/action safe area
if (olive::CurrentConfig.show_title_safe_area) {
draw_title_safe_area();
}
gizmos = renderer->gizmos;
gizmos = renderer.gizmos;
if (gizmos != nullptr) {
draw_gizmos();
}
glDisable(GL_TEXTURE_2D);
glFinish();
if (window->isVisible()) {
window->set_texture(tex, double(viewer->seq->width)/double(viewer->seq->height), tex_lock);
}
tex_lock->unlock();
if (renderer->did_texture_fail() && !viewer->playing) {
if (renderer.did_texture_fail() && !viewer->playing) {
doneCurrent();
renderer->start_render(context(), viewer->seq.get());
renderer.start_render(context(), viewer->seq.get());
}
}
*/
}
+2 -3
View File
@@ -87,13 +87,12 @@ private:
int gizmo_x_mvmt;
int gizmo_y_mvmt;
EffectGizmo* selected_gizmo;
RenderThread* renderer;
RenderThread renderer;
ViewerWindow* window;
double x_scroll;
double y_scroll;
QMatrix4x4 projection_;
QOpenGLShaderProgram* pipeline_;
QOpenGLShaderProgramPtr pipeline_;
private slots:
void context_destroy();