nearly finished gles transition
This commit is contained in:
+26
-31
@@ -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
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 +=
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
#include "qopenglshaderprogramptr.h"
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
#ifndef QOPENGLSHADERPROGRAMPTR_H
|
||||
#define QOPENGLSHADERPROGRAMPTR_H
|
||||
|
||||
#include <QOpenGLShaderProgram>
|
||||
|
||||
using QOpenGLShaderProgramPtr = std::shared_ptr<QOpenGLShaderProgram>;
|
||||
|
||||
#endif // QOPENGLSHADERPROGRAMPTR_H
|
||||
+145
-121
@@ -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 ¶ms) {
|
||||
// qint64 time = QDateTime::currentMSecsSinceEpoch();
|
||||
|
||||
GLuint final_fbo = params.main_buffer;
|
||||
|
||||
Sequence* s = params.seq;
|
||||
@@ -266,16 +304,19 @@ GLuint compose_sequence(ComposeSequenceParams ¶ms) {
|
||||
}
|
||||
}
|
||||
|
||||
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 ¶ms) {
|
||||
// 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 ¶ms) {
|
||||
} 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 ¶ms) {
|
||||
// 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 ¶ms) {
|
||||
|
||||
// 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 ¶ms) {
|
||||
// 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 ¶ms) {
|
||||
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 ¶ms) {
|
||||
|
||||
// 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 ¶ms) {
|
||||
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 ¶ms) {
|
||||
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 ¶ms) {
|
||||
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 ¶ms) {
|
||||
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 ¶ms) {
|
||||
|
||||
|
||||
|
||||
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 ¶ms) {
|
||||
// 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 ¶ms) {
|
||||
// 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 ¶ms) {
|
||||
// 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 ¶ms) {
|
||||
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 ¶ms) {
|
||||
// == 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 ¶ms) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
// 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;
|
||||
|
||||
@@ -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 ¶ms);
|
||||
|
||||
namespace olive {
|
||||
namespace rendering {
|
||||
extern GLfloat blit_vertices[];
|
||||
extern GLfloat blit_texcoords[];
|
||||
void Blit(QOpenGLShaderProgram* pipeline);
|
||||
QOpenGLShaderProgramPtr GetPipeline();
|
||||
}
|
||||
}
|
||||
|
||||
#endif // RENDERFUNCTIONS_H
|
||||
|
||||
+33
-41
@@ -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() {
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user