Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions app/node/distort/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ add_subdirectory(ripple)
add_subdirectory(swirl)
add_subdirectory(tile)
add_subdirectory(transform)
add_subdirectory(transformwrap)
add_subdirectory(wave)

set(OLIVE_SOURCES
Expand Down
22 changes: 22 additions & 0 deletions app/node/distort/transformwrap/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Olive - Non-Linear Video Editor
# Copyright (C) 2022 Olive Team
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

set(OLIVE_SOURCES
${OLIVE_SOURCES}
node/distort/transformwrap/transformwrap.h
node/distort/transformwrap/transformwrap.cpp
PARENT_SCOPE
)
111 changes: 111 additions & 0 deletions app/node/distort/transformwrap/transformwrap.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
/***

Olive - Non-Linear Video Editor
Copyright (C) 2024 Johann JEG (johannjeg1057@gmail.com)

This program is free software: you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.

***/

#include "transformwrap.h"
#include "widget/slider/floatslider.h"

namespace olive {

const QString TransformWrap::kTextureInput = QStringLiteral("tex_in");

const QString TransformWrap::kTranslationX = QStringLiteral("u_translation_x");
const QString TransformWrap::kTranslationY = QStringLiteral("u_translation_y");
const QString TransformWrap::kRotation = QStringLiteral("u_rotation");
const QString TransformWrap::kScale = QStringLiteral("u_scale");
const QString TransformWrap::kTextureWrapMode = QStringLiteral("texture_wrap_mode");

#define super Node

TransformWrap::TransformWrap() {
AddInput(kTextureInput, NodeValue::kTexture, InputFlags(kInputFlagNotKeyframable));

AddInput(kTranslationX, NodeValue::kFloat, 0.0);
AddInput(kTranslationY, NodeValue::kFloat, 0.0);
AddInput(kRotation, NodeValue::kFloat, 0.0);
AddInput(kScale, NodeValue::kFloat, 100.0);
AddInput(kTextureWrapMode, NodeValue::kCombo, 2, InputFlags(kInputFlagNotConnectable | kInputFlagNotKeyframable));

SetFlag(kVideoEffect);
SetEffectInput(kTextureInput);
}

QString TransformWrap::Name() const {
return tr("Transform Wrap");
}

QString TransformWrap::id() const {
return QStringLiteral("org.olivevideoeditor.Olive.TransformWrap");
}

QVector<Node::CategoryID> TransformWrap::Category() const {
return {kCategoryDistort};
}

QString TransformWrap::Description() const {
return tr("Transformations with wrap mode selection");
}

void TransformWrap::Retranslate() {
super::Retranslate();
SetInputName(kTextureInput, tr("Input Texture"));

SetInputName(kTranslationX, tr("Translation X"));
SetInputName(kTranslationY, tr("Translation Y"));
SetInputName(kRotation, tr("Rotation"));
SetInputName(kScale, tr("Scale"));

SetInputName(kTextureWrapMode, tr("Wrap Mode"));
SetComboBoxStrings(kTextureWrapMode, {tr("Clamp"), tr("Repeat"), tr("Mirrored Repeat")});
}

void TransformWrap::Value(const NodeValueRow &value, const NodeGlobals &globals, NodeValueTable *table) const {

NodeValue texture_meta = value[kTextureInput];

if (TexturePtr tex = texture_meta.toTexture()) {

ShaderJob job(value);

job.Insert(QStringLiteral("resolution_in"), NodeValue(NodeValue::kVec2, tex->virtual_resolution(), this));

int wrapMode = static_cast<Texture::WrapMode>(value[kTextureWrapMode].toInt());

switch (wrapMode) {
case 0:
job.SetWrapMode(QStringLiteral("tex_in"), Texture::kClamp);
break;
case 1:
job.SetWrapMode(QStringLiteral("tex_in"), Texture::kRepeat);
break;
case 2:
job.SetWrapMode(QStringLiteral("tex_in"), Texture::kMirroredRepeat);
break;
}


table->Push(NodeValue::kTexture, tex->toJob(job), this);
}
}

ShaderCode TransformWrap::GetShaderCode(const ShaderRequest &request) const {
Q_UNUSED(request)
return ShaderCode(FileFunctions::ReadFileAsString(":/shaders/transformation.frag"));
}
}
59 changes: 59 additions & 0 deletions app/node/distort/transformwrap/transformwrap.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/***

Olive - Non-Linear Video Editor
Copyright (C) 2024 Johann JEG (johannjeg1057@gmail.com)

This program is free software: you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation, either version 3 of
the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.

***/

#ifndef TRANSFORM_WRAP_H
#define TRANSFORM_WRAP_H

#include "node/node.h"

namespace olive {

class TransformWrap : public Node {

Q_OBJECT

public:

TransformWrap();

NODE_DEFAULT_FUNCTIONS(TransformWrap)

virtual QString Name() const override;
virtual QString id() const override;
virtual QVector<CategoryID> Category() const override;
virtual QString Description() const override;

virtual void Retranslate() override;

virtual void Value(const NodeValueRow& value, const NodeGlobals &globals, NodeValueTable *table) const override;
virtual ShaderCode GetShaderCode(const ShaderRequest &request) const override;

static const QString kTextureInput;

static const QString kTranslationX;
static const QString kTranslationY;
static const QString kRotation;
static const QString kScale;
static const QString kTextureWrapMode;
};

}

#endif // TRANSFORM_WRAP_H
4 changes: 4 additions & 0 deletions app/node/factory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
#include "distort/swirl/swirldistortnode.h"
#include "distort/tile/tiledistortnode.h"
#include "distort/transform/transformdistortnode.h"
#include "distort/transformwrap/transformwrap.h"
#include "distort/wave/wavedistortnode.h"
#include "effect/opacity/opacityeffect.h"
#include "filter/blur/blur.h"
Expand Down Expand Up @@ -71,6 +72,7 @@
#include "time/timeoffset/timeoffsetnode.h"
#include "time/timeremap/timeremap.h"


namespace olive {

QList<Node*> NodeFactory::library_;
Expand Down Expand Up @@ -221,6 +223,8 @@ Node *NodeFactory::CreateFromFactoryIndex(const NodeFactory::InternalID &id)
return new MatrixGenerator();
case kTransformDistort:
return new TransformDistortNode();
case kTransformWrap:
return new TransformWrap();
case kTrackOutput:
return new Track();
case kViewerOutput:
Expand Down
1 change: 1 addition & 0 deletions app/node/factory.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ class NodeFactory
kPolygonGenerator,
kMatrixGenerator,
kTransformDistort,
kTransformWrap,
kTrackOutput,
kAudioVolume,
kAudioPanning,
Expand Down
16 changes: 16 additions & 0 deletions app/render/job/shaderjob.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,11 @@ class ShaderJob : public AcceleratedJob
return interpolation_.value(id, Texture::kDefaultInterpolation);
}

Texture::WrapMode GetWrapMode(const QString& id) const
{
return wrap_.value(id, Texture::kDefaultWrapMode);
}

const QHash<QString, Texture::Interpolation> &GetInterpolationMap() const
{
return interpolation_;
Expand All @@ -95,6 +100,16 @@ class ShaderJob : public AcceleratedJob
interpolation_.insert(id, interp);
}

void SetWrapMode(const NodeInput& input, Texture::WrapMode wrap)
{
wrap_.insert(input.input(), wrap);
}

void SetWrapMode(const QString& id, Texture::WrapMode wrap)
{
wrap_.insert(id, wrap);
}

void SetVertexCoordinates(const QVector<float> &vertex_coords)
{
vertex_overrides_ = vertex_coords;
Expand All @@ -113,6 +128,7 @@ class ShaderJob : public AcceleratedJob
QString iterative_input_;

QHash<QString, Texture::Interpolation> interpolation_;
QHash<QString, Texture::WrapMode> wrap_;

QVector<float> vertex_overrides_;

Expand Down
37 changes: 29 additions & 8 deletions app/render/opengl/openglrenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,7 @@ Color OpenGLRenderer::GetPixelFromTexture(Texture *texture, const QPointF &pt)
struct TextureToBind {
TexturePtr texture;
Texture::Interpolation interpolation;
Texture::WrapMode wrap;
};

void OpenGLRenderer::Blit(QVariant s, ShaderJob job, Texture *destination, VideoParams destination_params, bool clear_destination)
Expand Down Expand Up @@ -478,7 +479,7 @@ void OpenGLRenderer::Blit(QVariant s, ShaderJob job, Texture *destination, Video

texture_index_map.insert(it.key(), textures_to_bind.size());

textures_to_bind.append({texture, job.GetInterpolation(it.key())});
textures_to_bind.append({texture, job.GetInterpolation(it.key()), job.GetWrapMode(it.key())});

// Set enable flag if shader wants it
GLuint tex_id = texture ? texture->id().value<GLuint>() : 0;
Expand Down Expand Up @@ -517,7 +518,7 @@ void OpenGLRenderer::Blit(QVariant s, ShaderJob job, Texture *destination, Video
functions_->glBindTexture(target, tex_id);

if (tex_id) {
PrepareInputTexture(target, t.interpolation);
PrepareInputTexture(target, t.interpolation, t.wrap);

if (texture->channel_count() == 1 && destination_params.channel_count() != 1) {
// Interpret this texture as a grayscale texture
Expand Down Expand Up @@ -638,7 +639,7 @@ void OpenGLRenderer::Blit(QVariant s, ShaderJob job, Texture *destination, Video
functions_->glBindTexture(GL_TEXTURE_2D, input_tex->id().value<GLuint>());

// At this time, we only support iterating 2D textures
PrepareInputTexture(GL_TEXTURE_2D, job.GetInterpolation(iterative_input));
PrepareInputTexture(GL_TEXTURE_2D, job.GetInterpolation(iterative_input), job.GetWrapMode(iterative_input));
}

// Swap so that the next iteration, the texture we draw now will be the input texture next
Expand Down Expand Up @@ -767,7 +768,7 @@ GLenum OpenGLRenderer::GetPixelFormat(int channel_count)
}
}

void OpenGLRenderer::PrepareInputTexture(GLenum target, Texture::Interpolation interp)
void OpenGLRenderer::PrepareInputTexture(GLenum target, Texture::Interpolation interp, Texture::WrapMode wrap)
{
switch (interp) {
case Texture::kNearest:
Expand All @@ -785,11 +786,31 @@ void OpenGLRenderer::PrepareInputTexture(GLenum target, Texture::Interpolation i
break;
}

functions_->glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
functions_->glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
switch (wrap) {
case Texture::kClamp:
functions_->glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
functions_->glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

if (target == GL_TEXTURE_3D) {
functions_->glTexParameteri(target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
if (target == GL_TEXTURE_3D) {
functions_->glTexParameteri(target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
}
break;
case Texture::kRepeat:
functions_->glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_REPEAT);
functions_->glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_REPEAT);

if (target == GL_TEXTURE_3D) {
functions_->glTexParameteri(target, GL_TEXTURE_WRAP_R, GL_REPEAT);
}
break;
case Texture::kMirroredRepeat:
functions_->glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
functions_->glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);

if (target == GL_TEXTURE_3D) {
functions_->glTexParameteri(target, GL_TEXTURE_WRAP_R, GL_MIRRORED_REPEAT);
}
break;
}
}

Expand Down
2 changes: 1 addition & 1 deletion app/render/opengl/openglrenderer.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ class OpenGLRenderer : public Renderer

void DetachTextureAsDestination();

void PrepareInputTexture(GLenum target, Texture::Interpolation interp);
void PrepareInputTexture(GLenum target, Texture::Interpolation interp, Texture::WrapMode wrap);

void ClearDestinationInternal(double r = 0.0, double g = 0.0, double b = 0.0, double a = 0.0);

Expand Down
1 change: 1 addition & 0 deletions app/render/texture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
namespace olive {

const Texture::Interpolation Texture::kDefaultInterpolation = Texture::kMipmappedLinear;
const Texture::WrapMode Texture::kDefaultWrapMode = Texture::kClamp;

Texture::~Texture()
{
Expand Down
7 changes: 7 additions & 0 deletions app/render/texture.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,14 @@ class Texture
kMipmappedLinear
};

enum WrapMode {
kClamp,
kRepeat,
kMirroredRepeat
};

static const Interpolation kDefaultInterpolation;
static const WrapMode kDefaultWrapMode;

/**
* @brief Construct a dummy texture with no renderer backend
Expand Down
Loading