├── .gitignore
├── 3d
├── fshader.glsl
└── vshader.glsl
├── Info.plist
├── JavascriptTextureGenerators
└── lines.js
├── LICENSE
├── ProceduralTextureMaker.pro
├── README.md
├── base
├── settingsmanager.cpp
├── settingsmanager.h
├── textureimage.cpp
├── textureimage.h
├── texturenode.cpp
├── texturenode.h
├── textureproject.cpp
├── textureproject.h
├── texturerenderthread.cpp
└── texturerenderthread.h
├── examples
├── rose.txl
└── wall.txl
├── generators
├── blending.cpp
├── blending.h
├── boxblur.cpp
├── boxblur.h
├── bricks.cpp
├── bricks.h
├── checkboard.cpp
├── checkboard.h
├── circle.cpp
├── circle.h
├── cutout.cpp
├── cutout.h
├── displacementmap.cpp
├── displacementmap.h
├── empty.cpp
├── empty.h
├── fill.cpp
├── fill.h
├── fire.cpp
├── fire.h
├── gaussianblur.cpp
├── gaussianblur.h
├── glow.cpp
├── glow.h
├── gradient.cpp
├── gradient.h
├── greyscale.cpp
├── greyscale.h
├── invert.cpp
├── invert.h
├── javascript.cpp
├── javascript.h
├── lens.cpp
├── lens.h
├── lines.cpp
├── lines.h
├── merge.cpp
├── merge.h
├── mirror.cpp
├── mirror.h
├── modifylevels.cpp
├── modifylevels.h
├── noise.cpp
├── noise.h
├── normalmap.cpp
├── normalmap.h
├── perlinnoise.cpp
├── perlinnoise.h
├── pixelate.cpp
├── pixelate.h
├── pointillism.cpp
├── pointillism.h
├── setchannels.cpp
├── setchannels.h
├── shadow.cpp
├── shadow.h
├── sineplasma.cpp
├── sineplasma.h
├── sinetransform.cpp
├── sinetransform.h
├── square.cpp
├── square.h
├── stackblur.cpp
├── stackblur.h
├── star.cpp
├── star.h
├── text.cpp
├── text.h
├── texturegenerator.cpp
├── texturegenerator.h
├── transform.cpp
├── transform.h
├── whirl.cpp
└── whirl.h
├── global.h
├── gui
├── addnodepanel.cpp
├── addnodepanel.h
├── connectionwidget.cpp
├── connectionwidget.h
├── cubewidget.cpp
├── cubewidget.h
├── iteminfopanel.cpp
├── iteminfopanel.h
├── mainwindow.cpp
├── mainwindow.h
├── menuactions.cpp
├── menuactions.h
├── nodesettingswidget.cpp
├── nodesettingswidget.h
├── previewimagepanel.cpp
├── previewimagepanel.h
├── qdoubleslider.h
├── sceneinfowidget.cpp
├── sceneinfowidget.h
├── settingspanel.cpp
└── settingspanel.h
├── images
├── copyicon.png
├── cuticon.png
├── mainicon.icns
├── mainicon.ico
├── mainicon.png
├── new.png
├── open.png
├── pasteicon.png
└── save.png
├── main.cpp
├── sceneview
├── viewnodeitem.cpp
├── viewnodeitem.h
├── viewnodeline.cpp
├── viewnodeline.h
├── viewnodescene.cpp
├── viewnodescene.h
├── viewnodeview.cpp
└── viewnodeview.h
├── shaders.qrc
├── texgen.qrc
├── texgenapplication.cpp
└── texgenapplication.h
/.gitignore:
--------------------------------------------------------------------------------
1 | # C++ objects and libs
2 |
3 | *.slo
4 | *.lo
5 | *.o
6 | *.a
7 | *.la
8 | *.lai
9 | *.so
10 | *.dll
11 | *.dylib
12 |
13 | # Qt-es
14 |
15 | /.qmake.cache
16 | /.qmake.stash
17 | *.pro.user
18 | *.pro.user.*
19 | *.qbs.user
20 | *.qbs.user.*
21 | *.moc
22 | moc_*.cpp
23 | moc_*.h
24 | qrc_*.cpp
25 | ui_*.h
26 | Makefile*
27 | *build-*
28 |
29 | # QtCreator
30 |
31 | *.autosave
32 |
33 | # QtCtreator Qml
34 | *.qmlproject.user
35 | *.qmlproject.user.*
36 |
37 | # QtCtreator CMake
38 | CMakeLists.txt.user*
39 |
40 | /debug
41 | /release
42 |
43 | .DS_store
44 | *~
45 | *.rc
46 | *plugin_import.cpp
47 |
48 | ProceduralTextureMaker
--------------------------------------------------------------------------------
/3d/fshader.glsl:
--------------------------------------------------------------------------------
1 | #ifdef GL_ES
2 | // Set default precision to medium
3 | precision mediump int;
4 | precision mediump float;
5 | #endif
6 |
7 | uniform sampler2D texture;
8 | varying vec2 v_texcoord;
9 |
10 | void main()
11 | {
12 | // Set fragment color from texture
13 | gl_FragColor = texture2D(texture, v_texcoord);
14 | }
15 |
16 |
--------------------------------------------------------------------------------
/3d/vshader.glsl:
--------------------------------------------------------------------------------
1 | #ifdef GL_ES
2 | // Set default precision to medium
3 | precision mediump int;
4 | precision mediump float;
5 | #endif
6 |
7 | uniform mat4 mvp_matrix;
8 | attribute vec4 a_position;
9 | attribute vec2 a_texcoord;
10 | varying vec2 v_texcoord;
11 |
12 | void main()
13 | {
14 | // Calculate vertex position in screen space
15 | gl_Position = mvp_matrix * a_position;
16 | // Pass texture coordinate to fragment shader
17 | // Value will be automatically interpolated to fragments inside polygon faces
18 | v_texcoord = a_texcoord;
19 | }
20 |
--------------------------------------------------------------------------------
/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | NSPrincipalClass
6 | NSApplication
7 | CFBundleIconFile
8 | mainicon.icns
9 | CFBundlePackageType
10 | APPL
11 | CFBundleGetInfoString
12 | ProceduralTextureMaker
13 | CFBundleSignature
14 | ????
15 | CFBundleExecutable
16 | ProceduralTextureMaker
17 | CFBundleIdentifier
18 | com.github.johanokl.ProceduralTextureMaker
19 | NOTE
20 | Don't edit
21 | CFBundleDocumentTypes
22 |
23 |
24 | CFBundleTypeExtensions
25 |
26 | txl
27 |
28 | CFBundleTypeRole
29 | Editor
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/JavascriptTextureGenerators/lines.js:
--------------------------------------------------------------------------------
1 | var name = "LinesJS";
2 | var numSlots = 1;
3 | // Set separateColorChannels to true to have one array index per color
4 | // If set to false all four channels are interleaved in one 32 bit value.
5 | var separateColorChannels = false;
6 |
7 | function generate(data, sourceImg) {
8 | var obj = JSON.parse(data);
9 | var color = obj.color.a +
10 | (obj.color.b << 8) +
11 | (obj.color.g << 16) +
12 | (obj.color.r << 24);
13 | obj.imagewidth = parseInt(obj.imagewidth);
14 | obj.imageheight = parseInt(obj.imageheight);
15 | obj.distance = Math.round(obj.distance * obj.imageheight / 100);
16 | obj.height = Math.round(obj.height * obj.imageheight / 100);
17 | obj.offset = Math.round(obj.offset * obj.imageheight / 100);
18 |
19 | if (obj.imageheight > 0) {
20 | var x, y;
21 | for (y = 0; y < obj.imageheight; y++) {
22 | var linestart = y * obj.imagewidth;
23 | if (((y + obj.offset) % (obj.height + obj.distance)) > obj.distance) {
24 | for (x = 0; x < obj.imagewidth; x++) {
25 | dest[linestart + x] = color;
26 | }
27 | } else if (sourceImg) {
28 | for (x = 0; x < obj.imagewidth; x++) {
29 | dest[linestart + x] = sourceImg[linestart + x];
30 | }
31 | } else {
32 | for (x = 0; x < obj.imagewidth; x++) {
33 | dest[linestart + x] = 0;
34 | }
35 | }
36 | }
37 | }
38 | return dest;
39 | }
40 |
41 | function getSettings() {
42 | return {
43 | color: {
44 | name: "Line color",
45 | defaultvalue: {
46 | r: 255,
47 | g: 100,
48 | b: 50,
49 | a: 255
50 | },
51 | type: "color",
52 | order: 1
53 | },
54 | height: {
55 | name: "Line height",
56 | defaultvalue: 10,
57 | min: 0,
58 | max: 100,
59 | type: "integer",
60 | order: 2
61 | },
62 | distance: {
63 | name: "Distance",
64 | defaultvalue: 10,
65 | min: 0,
66 | max: 100,
67 | type: "integer",
68 | order: 3
69 | },
70 | offset: {
71 | name: "Offset",
72 | defaultvalue: 0,
73 | min: 0,
74 | max: 100,
75 | type: "integer",
76 | order: 4
77 | }
78 | };
79 | }
80 |
--------------------------------------------------------------------------------
/ProceduralTextureMaker.pro:
--------------------------------------------------------------------------------
1 | TEMPLATE = app
2 | TARGET = "ProceduralTextureMaker"
3 |
4 | macx {
5 | # Possible to include spaces in the file name if on Mac OS X.
6 | TARGET = "ProceduralTextureMaker"
7 | QMAKE_MAC_SDK = 10.13
8 | QMAKE_INFO_PLIST += Info.plist
9 | OTHER_FILES += Info.plist
10 | }
11 |
12 | # Select which Javascript engine to include
13 | # -----------------------------------------
14 | # Qt's QScriptEngine is deprecated and might be removed
15 | # while QJSEngine (in Qt 5.9 and 5.10) still has some
16 | # strange bugs releated to memory management.
17 | # Uncomment the line "#defines USE_QJSENGINE" below if QtScript isn't
18 | # available or QJSEngine is stable and enough to be a viable alternative.
19 | # For QScriptEngine, remember to also include module script.
20 | # For QJSEngine, remember to also include module qml.
21 | # It is also possible to disable Javascript support, if both
22 | # QML/QJSEngine and QtScript/QScriptEngine are missing from the system.
23 | # To do so, uncomment the line "#defines DISABLE_JAVASCRIPT".
24 | # -----------------------------------------
25 | #DEFINES += "DISABLE_JAVASCRIPT"
26 |
27 | qtHaveModule(qml) {
28 | QT += qml
29 | DEFINES += "USE_QJSENGINE"
30 | }
31 | else { qtHaveModule(script) {
32 | QT += script
33 | }
34 | else {
35 | DEFINES += "DISABLE_JAVASCRIPT"
36 | }}
37 |
38 | QT += xml \
39 | widgets \
40 | gui \
41 | core
42 |
43 | CONFIG += c++11
44 |
45 | INCLUDEPATH += src
46 |
47 | SOURCES = \
48 | main.cpp \
49 | texgenapplication.cpp \
50 | base/texturenode.cpp \
51 | base/textureimage.cpp \
52 | base/texturerenderthread.cpp \
53 | base/settingsmanager.cpp \
54 | base/textureproject.cpp \
55 | gui/nodesettingswidget.cpp \
56 | gui/mainwindow.cpp \
57 | gui/addnodepanel.cpp \
58 | gui/settingspanel.cpp \
59 | gui/menuactions.cpp \
60 | gui/connectionwidget.cpp \
61 | gui/sceneinfowidget.cpp \
62 | gui/iteminfopanel.cpp \
63 | gui/previewimagepanel.cpp \
64 | gui/cubewidget.cpp \
65 | sceneview/viewnodeview.cpp \
66 | sceneview/viewnodeitem.cpp \
67 | sceneview/viewnodescene.cpp \
68 | sceneview/viewnodeline.cpp \
69 | generators/blending.cpp \
70 | generators/boxblur.cpp \
71 | generators/bricks.cpp \
72 | generators/checkboard.cpp \
73 | generators/circle.cpp \
74 | generators/cutout.cpp \
75 | generators/displacementmap.cpp \
76 | generators/empty.cpp \
77 | generators/fill.cpp \
78 | generators/fire.cpp \
79 | generators/gaussianblur.cpp \
80 | generators/glow.cpp \
81 | generators/greyscale.cpp \
82 | generators/gradient.cpp \
83 | generators/invert.cpp \
84 | generators/javascript.cpp \
85 | generators/lens.cpp \
86 | generators/lines.cpp \
87 | generators/mirror.cpp \
88 | generators/merge.cpp \
89 | generators/modifylevels.cpp \
90 | generators/noise.cpp \
91 | generators/normalmap.cpp \
92 | generators/perlinnoise.cpp \
93 | generators/pixelate.cpp \
94 | generators/pointillism.cpp \
95 | generators/shadow.cpp \
96 | generators/sinetransform.cpp \
97 | generators/sineplasma.cpp \
98 | generators/stackblur.cpp \
99 | generators/square.cpp \
100 | generators/star.cpp \
101 | generators/setchannels.cpp \
102 | generators/texturegenerator.cpp \
103 | generators/transform.cpp \
104 | generators/text.cpp \
105 | generators/whirl.cpp
106 |
107 | HEADERS += \
108 | global.h \
109 | texgenapplication.h \
110 | base/texturenode.h \
111 | base/textureimage.h \
112 | base/texturerenderthread.h \
113 | base/settingsmanager.h \
114 | base/textureproject.h \
115 | gui/addnodepanel.h \
116 | gui/qdoubleslider.h \
117 | gui/nodesettingswidget.h \
118 | gui/settingspanel.h \
119 | gui/mainwindow.h \
120 | gui/menuactions.h \
121 | gui/connectionwidget.h \
122 | gui/sceneinfowidget.h \
123 | gui/iteminfopanel.h \
124 | gui/previewimagepanel.h \
125 | gui/cubewidget.h \
126 | sceneview/viewnodeitem.h \
127 | sceneview/viewnodescene.h \
128 | sceneview/viewnodeline.h \
129 | sceneview/viewnodeview.h \
130 | generators/texturegenerator.h \
131 | generators/blending.h \
132 | generators/bricks.h \
133 | generators/boxblur.h \
134 | generators/checkboard.h \
135 | generators/cutout.h \
136 | generators/circle.h \
137 | generators/displacementmap.h \
138 | generators/empty.h \
139 | generators/fill.h \
140 | generators/fire.h \
141 | generators/gaussianblur.h \
142 | generators/glow.h \
143 | generators/gradient.h \
144 | generators/greyscale.h \
145 | generators/invert.h \
146 | generators/javascript.h \
147 | generators/lens.h \
148 | generators/lines.h \
149 | generators/merge.h \
150 | generators/mirror.h \
151 | generators/modifylevels.h \
152 | generators/noise.h \
153 | generators/normalmap.h \
154 | generators/perlinnoise.h \
155 | generators/pixelate.h \
156 | generators/pointillism.h \
157 | generators/shadow.h \
158 | generators/sineplasma.h \
159 | generators/sinetransform.h \
160 | generators/setchannels.h \
161 | generators/square.h \
162 | generators/stackblur.h \
163 | generators/star.h \
164 | generators/text.h \
165 | generators/transform.h \
166 | generators/whirl.h
167 |
168 | RESOURCES += \
169 | texgen.qrc \
170 | shaders.qrc
171 |
172 | RC_ICONS += images/mainicon.ico
173 | ICON += images/mainicon.icns
174 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ProceduralTextureMaker
2 | ========================
3 |
4 | ### Introduction
5 | ProceduralTextureMaker generates texture images in arbitrary sizes based on graphs of nodes that take other nodes' output as input and transform them into new images.
6 |
7 | Nodes are added dynamically and connected to each other graphically.
8 | Custom UI widgets are created for each node based on the texture generator's user configurable settings, making it easy to try out new configurations and watch how changes affect the final output.
9 | The project files with texture graphs can be saved to and loaded from XML files, and images can be exported to PNG files.
10 |
11 | A number of texture generators written in C++ and Javascript are included with the project.
12 |
13 | For more general information about procedural textures, see https://en.wikipedia.org/wiki/Procedural_texture
14 |
15 | ### Screenshot
16 | 
17 |
18 | ### Examples
19 | Two example textures have been added to the repository:
20 | * [Rose](examples/rose.txl)
21 | * [Wall](examples/wall.txl)
22 |
23 | ### Technical Details
24 | The application is written in C++ and uses the Qt framework.
25 | It has been tested with Qt versions 5.9, 5.10, 5.12 and 5.15 on Mac OS, Ubuntu and Windows 10.
26 | It uses multiple threads on multiple CPU cores where supported, so that CPU intensive texture calculations don't affect the UI performance.
27 | It's easy to extend the application by adding new generators, especially ones written in Javacript as those are loaded dynamically from external files.
28 |
29 | ### Javascript
30 | One example Javascript texture generator is included in the directory _JavascriptTextureGenerators_.
31 | The external Javascript texture generators are parsed and run using the QtScript engine.
32 | As the QtScript module is listed as deprecated and not installed by default by the Qt installer there is also support for running the scripts with the newer QJSEngine class.
33 | QScriptEngine and not QJSEngine is still enabled by default as there were some strange unresolved bugs related to QJSEngine version 5.10's memory management encountered during development.
34 | Changing which engine that should be used is done by adding or removing `DEFINES += "USE_QJSENGINE"` in _ProceduralTextureMaker.pro_.
35 |
36 | ### How to build
37 | Install and configure Qt 5.15, available at https://www.qt.io/download-open-source
38 | If you're compiling with the QScript engine (see the Javascript section above) make sure that the Qt installation includes that module.
39 | If Qt Creator was installed, use it to open and build the project file `ProceduralTextureMaker.pro`.
40 | If Qt Creator isn't available, use a terminal to browse to the project root directory and run `qmake && make && make install`.
41 |
42 | ### License
43 | Released under GPL version 3.
44 |
45 | ### Author
46 | Johan Lindqvist
47 | johan.lindqvist@gmail.com
48 | https://github.com/johanokl
49 |
50 | Icon from https://www.iconfinder.com/icons/28730/
51 |
--------------------------------------------------------------------------------
/base/settingsmanager.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Part of the ProceduralTextureMaker project.
3 | * http://github.com/johanokl/ProceduralTextureMaker
4 | * Released under GPLv3.
5 | * Johan Lindqvist (johan.lindqvist@gmail.com)
6 | */
7 |
8 | #ifndef SETTINGSMANAGER_H
9 | #define SETTINGSMANAGER_H
10 |
11 | #include
12 | #include
13 | #include
14 |
15 | /**
16 | * @brief The SettingsManager class
17 | *
18 | * Manages the global settings. Settings are written to
19 | * and loaded from persistent storage using the QSettings class.
20 | */
21 | class SettingsManager : public QObject
22 | {
23 | Q_OBJECT
24 |
25 | public:
26 | SettingsManager() = default;
27 | ~SettingsManager() override = default;
28 | QSize getPreviewSize() const;
29 | QSize getThumbnailSize() const;
30 | QString getJSTextureGeneratorsPath() const;
31 | bool getJSTextureGeneratorsEnabled() const;
32 | QColor getPreviewBackgroundColor() const;
33 | QColor getBackgroundColor() const;
34 | int getBackgroundBrush() const;
35 | int getDefaultZoom() const;
36 |
37 | signals:
38 | void settingsUpdated();
39 |
40 | public slots:
41 | void setDefaultZoom(int);
42 | void setPreviewSize(const QSize&);
43 | void setThumbnailSize(const QSize&);
44 | void setPreviewBackgroundColor(const QColor&);
45 | void setBackgroundColor(const QColor&);
46 | void setBackgroundBrush(int val);
47 | void setJSTextureGeneratorsPath(const QString&);
48 | void setJSTextureGeneratorsEnabled(bool);
49 | };
50 |
51 | #endif // SETTINGSMANAGER_H
52 |
--------------------------------------------------------------------------------
/base/textureimage.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Part of the ProceduralTextureMaker project.
3 | * http://github.com/johanokl/ProceduralTextureMaker
4 | * Released under GPLv3.
5 | * Johan Lindqvist (johan.lindqvist@gmail.com)
6 | */
7 |
8 | #include "textureimage.h"
9 | #include
10 | #include
11 |
12 | /**
13 | * @brief TextureImage::TextureImage
14 | * @param size Image pixel dimensions
15 | * @param data TexturePixels, size must be at least width*height
16 | */
17 | TextureImage::TextureImage(QSize size, TexturePixel* data)
18 | {
19 | this->size = size;
20 | this->data = data;
21 | }
22 |
23 | /**
24 | * @brief TextureImage::~TextureImage
25 | */
26 | TextureImage::~TextureImage()
27 | {
28 | if (data != nullptr) {
29 | delete data;
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/base/textureimage.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Part of the ProceduralTextureMaker project.
3 | * http://github.com/johanokl/ProceduralTextureMaker
4 | * Released under GPLv3.
5 | * Johan Lindqvist (johan.lindqvist@gmail.com)
6 | */
7 |
8 | #ifndef TEXTUREIMAGE_H
9 | #define TEXTUREIMAGE_H
10 |
11 | #include "global.h"
12 | #include
13 | #include
14 |
15 | /**
16 | * @brief The TextureImage class
17 | *
18 | * Holds the data for an image
19 | */
20 | class TextureImage
21 | {
22 | public:
23 | TextureImage(QSize size, TexturePixel* data);
24 | virtual ~TextureImage();
25 | QSize getSize() const { return size; }
26 | TexturePixel* getData() const { return data; }
27 |
28 | private:
29 | QSize size;
30 | TexturePixel* data;
31 | };
32 |
33 | /**
34 | * @brief TextureImagePtr
35 | *
36 | * Thread-safe smart pointer for TextureImage
37 | */
38 | using TextureImagePtr = QSharedPointer;
39 |
40 |
41 | #endif // TEXTUREIMAGE_H
42 |
--------------------------------------------------------------------------------
/base/texturenode.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Part of the ProceduralTextureMaker project.
3 | * http://github.com/johanokl/ProceduralTextureMaker
4 | * Released under GPLv3.
5 | * Johan Lindqvist (johan.lindqvist@gmail.com)
6 | */
7 |
8 | #ifndef TEXTURENODE_H
9 | #define TEXTURENODE_H
10 |
11 | #include "generators/texturegenerator.h"
12 | #include "global.h"
13 | #include "textureimage.h"
14 | #include
15 | #include
16 | #include
17 | #include
18 | #include
19 |
20 | class TextureProject;
21 | class TextureNode;
22 |
23 | /**
24 | * @brief TextureNodePtr
25 | * Thread-safe smart pointer for TextureNode objects.
26 | */
27 | using TextureNodePtr = QSharedPointer;
28 |
29 | /**
30 | * @brief The TextureNode class
31 | *
32 | * A node in the graph with its settings, attributes
33 | * and links to its source and receiver nodes.
34 | */
35 | class TextureNode : public QObject
36 | {
37 | Q_OBJECT
38 | friend class TextureProject;
39 |
40 | public:
41 | ~TextureNode() override;
42 | void release();
43 | int getId() const { return id; }
44 | QString getName() const { return name; }
45 | void setName(const QString& name);
46 | bool setGenerator(const QString& name);
47 | bool setGenerator(TextureGeneratorPtr gen);
48 | TextureGeneratorPtr getGenerator() const { return gen; }
49 | QString getGeneratorName() const;
50 | int getNumSourceSlots() const;
51 | int getNumReceivers() const { return receivers.size(); }
52 | QSetIterator getReceivers() const { return QSetIterator(receivers); }
53 | bool slotAvailable(int slot) const;
54 | bool setSourceSlot(int slot, int value);
55 | bool findLoop() const;
56 | QPointF getPos() const { return pos; }
57 | void setPos(QPointF pos);
58 | TextureImagePtr getImage(QSize size);
59 | void setUpdated();
60 | bool isTextureInCache(QSize size) const;
61 | int waitingFor(QSize size) const;
62 | const TextureNodeSettings getSettings() const { return settings; }
63 | void setSettings(const TextureNodeSettings& settings);
64 | const QMap getSources() const { return sources; }
65 |
66 | signals:
67 | void positionUpdated(int id);
68 | void imageUpdated(int id);
69 | void slotsUpdated(int id);
70 | void imageAvailable(int id, QSize size);
71 | void settingsUpdated(int id);
72 | void generatorUpdated(int id);
73 | void nodesConnected(int sourceId, int receiverId, int slot);
74 | void nodesDisconnected(int sourceId, int receiverId, int slot);
75 |
76 | private:
77 | TextureNode(TextureProject* project, const TextureGeneratorPtr& generator, int id);
78 | void loadFromXML(const QDomNode& xmlnode, const QMap idMapping = QMap());
79 | QDomElement saveAsXML(QDomDocument targetdoc);
80 | bool findLoop(QList visited) const;
81 | void removeSource(int id);
82 |
83 | int id;
84 | QString name;
85 | QPointF pos;
86 |
87 | QMap sources;
88 | QSet receivers;
89 | TextureNodeSettings settings;
90 |
91 | TextureGeneratorPtr gen;
92 | TextureProject* project;
93 |
94 | // Contains all the generated images
95 | QMap texturecache;
96 | // Set to true after releasing all connections, before delete
97 | bool deleted;
98 | QMap validImage;
99 |
100 | // Mutexes to make it thread-safe.
101 | mutable QReadWriteLock sourcemutex;
102 | mutable QReadWriteLock receivermutex;
103 | mutable QReadWriteLock imagemutex;
104 | mutable QReadWriteLock settingsmutex;
105 | };
106 |
107 | #endif // TEXTURENODE_H
108 |
--------------------------------------------------------------------------------
/base/textureproject.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Part of the ProceduralTextureMaker project.
3 | * http://github.com/johanokl/ProceduralTextureMaker
4 | * Released under GPLv3.
5 | * Johan Lindqvist (johan.lindqvist@gmail.com)
6 | */
7 |
8 | #ifndef TEXTUREPROJECT_H
9 | #define TEXTUREPROJECT_H
10 |
11 | #include "texturenode.h"
12 | #include
13 | #include
14 | #include
15 | #include
16 | #include
17 |
18 | class TextureRenderThread;
19 | class TextureGenerator;
20 | class SettingsManager;
21 |
22 | /**
23 | * @brief The TextureProject class
24 | *
25 | * Manages all the texture generators, TextureNode instances and
26 | * the connections between them.
27 | */
28 | class TextureProject : public QObject
29 | {
30 | Q_OBJECT
31 | friend class TextureNode;
32 |
33 | public:
34 | TextureProject();
35 | ~TextureProject() override;
36 | QDomDocument saveAsXML(bool includegenerators = false);
37 | void loadFromXML(const QDomDocument& xmlfile);
38 | QString getName() const { return name; }
39 | void setName(const QString&);
40 | TextureNodePtr getNode(int id) const;
41 | bool findLoops() const;
42 | void removeNode(int id);
43 | TextureNodePtr newNode(int id = 0, TextureGeneratorPtr generator = TextureGeneratorPtr(nullptr));
44 | void clear();
45 | bool isModified() const;
46 | int getNumNodes() const;
47 | TextureGeneratorPtr getGenerator(const QString& name) const;
48 | QMap getGenerators() const { return generators; }
49 | QSize getThumbnailSize() const { return thumbnailSize; }
50 | QSize getPreviewSize() const { return previewSize; }
51 | void setSettingsManager(SettingsManager* manager);
52 | SettingsManager* getSettingsManager() const { return settingsManager; }
53 |
54 | public slots:
55 | void addGenerator(const TextureGeneratorPtr& gen);
56 | void removeGenerator(const TextureGeneratorPtr& gen);
57 | void notifyNodesConnected(int sourceId, int receiverId, int slot);
58 | void notifyNodesDisconnected(int sourceId, int receiverId, int slot);
59 | void notifyImageUpdated(int id);
60 | void notifyImageAvailable(int id, QSize size);
61 | void copyNode(int id);
62 | void cutNode(int id);
63 | void pasteNode();
64 | void settingsUpdated();
65 |
66 | signals:
67 | void nodeAdded(TextureNodePtr);
68 | void nodeRemoved(int);
69 | void nodesConnected(int, int, int);
70 | void nodesDisconnected(int, int, int);
71 | void imageUpdated(int);
72 | void imageAvailable(int, QSize);
73 | void nameUpdated(QString);
74 | void generatorAdded(TextureGeneratorPtr);
75 | void generatorRemoved(TextureGeneratorPtr);
76 | void generatorNameCollision(TextureGeneratorPtr, TextureGeneratorPtr);
77 |
78 | private:
79 | TextureGeneratorPtr getEmptyGenerator() const { return emptygenerator; }
80 | void startRenderThread(QSize renderSize, QThread::Priority = QThread::NormalPriority);
81 | void stopRenderThread(QSize renderSize);
82 | int getNewId();
83 |
84 | QString name;
85 | int newIdCounter;
86 | TextureGeneratorPtr emptygenerator;
87 | QMap renderThreads;
88 | QMap nodes;
89 | QMap generators;
90 | mutable QReadWriteLock nodesmutex;
91 |
92 | QSize thumbnailSize;
93 | QSize previewSize;
94 | SettingsManager* settingsManager;
95 | bool modified;
96 | };
97 |
98 | #endif // TEXTUREPROJECT_H
99 |
--------------------------------------------------------------------------------
/base/texturerenderthread.cpp:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | /**
4 | * Part of the ProceduralTextureMaker project.
5 | * http://github.com/johanokl/ProceduralTextureMaker
6 | * Released under GPLv3.
7 | * Johan Lindqvist (johan.lindqvist@gmail.com)
8 | */
9 |
10 | #include "texturerenderthread.h"
11 | #include "global.h"
12 | #include "texturenode.h"
13 |
14 | /**
15 | * @brief TextureRenderThread::TextureRenderThread
16 | * @param renderSize Static rendersize.
17 | * @param nodes
18 | */
19 | TextureRenderThread::TextureRenderThread(const QSize inRendersize, QMap inNodesMap)
20 | : renderSize(inRendersize), nodes(std::move(inNodesMap))
21 | {
22 | aborted = false;
23 | }
24 |
25 | /**
26 | * @brief TextureRenderThread::abort
27 | *
28 | * Stops a thread from rendering more images.
29 | * Finishes the current one and then stops.
30 | */
31 | void TextureRenderThread::abort()
32 | {
33 | aborted = true;
34 | }
35 |
36 | /**
37 | * @brief TextureRenderThread::generate
38 | *
39 | * Loops through the node list and generates images until all nodes
40 | * have an image this thread's image size in their cache.
41 | */
42 | void TextureRenderThread::generate()
43 | {
44 | bool someGenerated;
45 | do {
46 | someGenerated = false;
47 | QMapIterator nodeIterator(nodes);
48 | while (!aborted && nodeIterator.hasNext()) {
49 | TextureNodePtr currNode = nodeIterator.next().value();
50 | if (currNode->waitingFor(renderSize) == 0
51 | && !currNode->isTextureInCache(renderSize)) {
52 | currNode->getImage(renderSize);
53 | someGenerated = true;
54 | }
55 | }
56 | } while (!aborted && someGenerated);
57 | }
58 |
59 | /**
60 | * @brief TextureRenderThread::imageUpdated
61 | * @param id Node id.
62 | *
63 | * Callback function for when a node has been updated
64 | * and a new image needs to be rendered for it.
65 | */
66 | void TextureRenderThread::imageUpdated()
67 | {
68 | generate();
69 | }
70 |
71 | /**
72 | * @brief TextureRenderThread::nodeAdded
73 | * @param newNode
74 | *
75 | * Adds a node to the internal node list.
76 | */
77 | void TextureRenderThread::nodeAdded(const TextureNodePtr& newNode)
78 | {
79 | if (!nodes.contains(newNode->getId())) {
80 | nodes.insert(newNode->getId(), newNode);
81 | generate();
82 | }
83 | }
84 |
85 | /**
86 | * @brief TextureRenderThread::nodeRemoved
87 | * @param id Node id
88 | *
89 | * Removes a node from the internal node list, thus no longer
90 | * rendering images for that node.
91 | */
92 | void TextureRenderThread::nodeRemoved(int id)
93 | {
94 | if (nodes.contains(id)) {
95 | nodes.remove(id);
96 | generate();
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/base/texturerenderthread.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Part of the ProceduralTextureMaker project.
3 | * http://github.com/johanokl/ProceduralTextureMaker
4 | * Released under GPLv3.
5 | * Johan Lindqvist (johan.lindqvist@gmail.com)
6 | */
7 |
8 | #ifndef TEXTURERENDERTHREAD_H
9 | #define TEXTURERENDERTHREAD_H
10 |
11 | #include "texturenode.h"
12 | #include
13 |
14 | class TextureProject;
15 |
16 | /**
17 | * @brief The TextureRenderThread class
18 | *
19 | * Class for moving the image rendering to a separate CPU thread.
20 | * Stays idle when no image needs to be generated.
21 | * One thread only handles one image size, so create one instance for each size.
22 | */
23 | class TextureRenderThread : public QObject
24 | {
25 | Q_OBJECT
26 |
27 | public:
28 | TextureRenderThread(const QSize renderSize, QMap nodes);
29 | ~TextureRenderThread() override = default;
30 | void abort();
31 |
32 | public slots:
33 | void imageUpdated();
34 | void nodeRemoved(int remNode);
35 | void nodeAdded(const TextureNodePtr& newNode);
36 |
37 | private:
38 | void generate();
39 | bool noneGenerated;
40 | const QSize renderSize;
41 | QMap nodes;
42 | bool aborted;
43 | };
44 |
45 | #endif // TEXTURERENDERTHREAD_H
46 |
--------------------------------------------------------------------------------
/generators/blending.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Part of the ProceduralTextureMaker project.
3 | * http://github.com/johanokl/ProceduralTextureMaker
4 | * Released under GPLv3.
5 | * Johan Lindqvist (johan.lindqvist@gmail.com)
6 | */
7 |
8 | #ifndef BLENDINGTEXTUREGENERATOR_H
9 | #define BLENDINGTEXTUREGENERATOR_H
10 |
11 | #include "texturegenerator.h"
12 |
13 | /**
14 | * @brief The BlendingTextureGenerator class
15 | */
16 | class BlendingTextureGenerator : public TextureGenerator
17 | {
18 | public:
19 | enum BlendModes {
20 | Normal = 1,
21 | Darken = 2,
22 | Multiply = 3,
23 | Lighten = 4,
24 | Screen = 5,
25 | ColorDodge = 6,
26 | ColorBurn = 7,
27 | Overlay = 8,
28 | SoftLight = 9,
29 | HardLight = 10,
30 | Difference = 11,
31 | Exclusion = 12
32 | };
33 |
34 | BlendingTextureGenerator();
35 | ~BlendingTextureGenerator() override = default;
36 | void generate(QSize size,
37 | TexturePixel* destimage,
38 | QMap sourceimages,
39 | TextureNodeSettings* settings) const override;
40 | int getNumSourceSlots() const override { return 2; }
41 | QString getName() const override { return QString("Blending"); }
42 | const TextureGeneratorSettings& getSettings() const override { return configurables; }
43 | QString getDescription() const override { return QString("Blends two textures together."); }
44 | TextureGenerator::Type getType() const override { return TextureGenerator::Type::Combiner; }
45 |
46 | private:
47 | TextureGeneratorSettings configurables;
48 | double blendColors(BlendModes mode, double originColor, double addColor) const;
49 | int alphaCompose(double originAlpha, double addAlpha, double compositeAlpha,
50 | double originColor, double addColor, double compositeColor) const;
51 | };
52 |
53 | #endif // BLENDINGTEXTUREGENERATOR_H
54 |
55 |
56 |
--------------------------------------------------------------------------------
/generators/boxblur.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Part of the ProceduralTextureMaker project.
3 | * http://github.com/johanokl/ProceduralTextureMaker
4 | * Released under GPLv3.
5 | * Johan Lindqvist (johan.lindqvist@gmail.com)
6 | */
7 |
8 | #include "boxblur.h"
9 |
10 | BoxBlurTextureGenerator::BoxBlurTextureGenerator()
11 | {
12 | TextureGeneratorSetting neighbourssetting;
13 | neighbourssetting.defaultvalue = QVariant((int) 5);
14 | neighbourssetting.name = "Blur level";
15 | neighbourssetting.min = QVariant(0);
16 | neighbourssetting.max = QVariant(30);
17 | configurables.insert("numneighbours", neighbourssetting);
18 | }
19 |
20 |
21 | void BoxBlurTextureGenerator::generate(QSize size,
22 | TexturePixel* destimage,
23 | QMap sourceimages,
24 | TextureNodeSettings* settings) const
25 | {
26 | if (!settings || !destimage || !size.isValid()) {
27 | return;
28 | }
29 | if (!sourceimages.contains(0)) {
30 | memset(destimage, 0, size.width() * size.height() * sizeof(TexturePixel));
31 | return;
32 | }
33 | TexturePixel* sourceImage = sourceimages.value(0).data()->getData();
34 | if (settings->value("numneighbours").toInt() == 0) {
35 | memcpy(destimage, sourceImage, size.width() * size.height() * sizeof(TexturePixel));
36 | return;
37 | }
38 | int numNeightboursX = settings->value("numneighbours").toDouble() * qMax(size.width() / 250, 1);
39 | int numNeightboursY = settings->value("numneighbours").toDouble() * qMax(size.height() / 250, 1);
40 | for (int j = 0; j < size.height(); j++) {
41 | for (int i = 0; i < size.width(); i++) {
42 | int startX = i - numNeightboursX;
43 | int endX = i + numNeightboursX;
44 | int startY = j - numNeightboursY;
45 | int endY = j + numNeightboursY;
46 | int totalPixels = 0;
47 | quint64 red = 0;
48 | quint64 green = 0;
49 | quint64 blue = 0;
50 | quint64 alpha = 0;
51 | for (int ypos = startY; ypos < endY; ypos++) {
52 | int currY = ypos;
53 | if (currY < 0) {
54 | currY += size.height() * 5;
55 | }
56 | currY %= size.height();
57 | currY *= size.width();
58 | for (int xpos = startX; xpos < endX; xpos++) {
59 | int currX = xpos;
60 | if (currX < 0) {
61 | currX += size.width() * 5;
62 | }
63 | currX %= size.width();
64 | totalPixels++;
65 | TexturePixel sourcePixel = sourceImage[currY + currX];
66 | red += sourcePixel.r;
67 | green += sourcePixel.g;
68 | blue += sourcePixel.b;
69 | alpha += sourcePixel.a;
70 | }
71 | }
72 | int pixelpos = j * size.width() + i;
73 | destimage[pixelpos].r = static_cast(red / totalPixels);
74 | destimage[pixelpos].g = static_cast(green / totalPixels);
75 | destimage[pixelpos].b = static_cast(blue / totalPixels);
76 | destimage[pixelpos].a = static_cast(alpha / totalPixels);
77 | }
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/generators/boxblur.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Part of the ProceduralTextureMaker project.
3 | * http://github.com/johanokl/ProceduralTextureMaker
4 | * Released under GPLv3.
5 | * Johan Lindqvist (johan.lindqvist@gmail.com)
6 | */
7 |
8 | #ifndef BOXBLURTEXTUREGENERATOR_H
9 | #define BOXBLURTEXTUREGENERATOR_H
10 |
11 | #include "texturegenerator.h"
12 |
13 | /**
14 | * @brief The BoxBlurTextureGenerator class
15 | */
16 | class BoxBlurTextureGenerator : public TextureGenerator
17 | {
18 | public:
19 | BoxBlurTextureGenerator();
20 | ~BoxBlurTextureGenerator() override = default;
21 | void generate(QSize size,
22 | TexturePixel* destimage,
23 | QMap sourceimages,
24 | TextureNodeSettings* settings) const override;
25 | int getNumSourceSlots() const override { return 1; }
26 | QString getName() const override { return QString("Box blur"); }
27 | const TextureGeneratorSettings& getSettings() const override { return configurables; }
28 | QString getDescription() const override { return QString("Blurs the source image."); }
29 | TextureGenerator::Type getType() const override { return TextureGenerator::Type::Filter; }
30 |
31 | private:
32 | TextureGeneratorSettings configurables;
33 | };
34 |
35 | #endif // BOXBLURTEXTUREGENERATOR_H
36 |
--------------------------------------------------------------------------------
/generators/bricks.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Part of the ProceduralTextureMaker project.
3 | * http://github.com/johanokl/ProceduralTextureMaker
4 | * Released under GPLv3.
5 | * Johan Lindqvist (johan.lindqvist@gmail.com)
6 | */
7 |
8 | #include "bricks.h"
9 | #include
10 | #include
11 |
12 | BricksTextureGenerator::BricksTextureGenerator()
13 | {
14 | TextureGeneratorSetting color;
15 | color.name = "Color";
16 | color.defaultvalue = QVariant(QColor(200, 200, 200, 255));
17 | color.order = 1;
18 | configurables.insert("color", color);
19 |
20 | TextureGeneratorSetting linewidth;
21 | linewidth.name = "Line width";
22 | linewidth.defaultvalue = QVariant((int) 10);
23 | linewidth.min = QVariant(0);
24 | linewidth.max = QVariant(100);
25 | linewidth.order = 2;
26 | configurables.insert("linewidth", linewidth);
27 |
28 | TextureGeneratorSetting brickwidth;
29 | brickwidth.name = "Brick width";
30 | brickwidth.defaultvalue = QVariant((int) 120);
31 | brickwidth.min = QVariant(0);
32 | brickwidth.max = QVariant(300);
33 | brickwidth.group = "size";
34 | brickwidth.order = 3;
35 | configurables.insert("brickwidth", brickwidth);
36 |
37 | TextureGeneratorSetting brickheight;
38 | brickheight.name = "Brick height";
39 | brickheight.defaultvalue = QVariant((int) 45);
40 | brickheight.min = QVariant(0);
41 | brickheight.max = QVariant(300);
42 | brickheight.group = "size";
43 | brickheight.order = 4;
44 | configurables.insert("brickheight", brickheight);
45 |
46 | TextureGeneratorSetting offsetx;
47 | offsetx.name = "Offset left";
48 | offsetx.defaultvalue = QVariant((int) 0);
49 | offsetx.min = QVariant(-100);
50 | offsetx.max = QVariant(100);
51 | offsetx.order = 5;
52 | configurables.insert("offsetx", offsetx);
53 |
54 | TextureGeneratorSetting offsety;
55 | offsety.name = "Offset top";
56 | offsety.defaultvalue = QVariant((int) 0);
57 | offsety.min = QVariant(-100);
58 | offsety.max = QVariant(100);
59 | offsety.order = 6;
60 | configurables.insert("offsety", offsety);
61 | }
62 |
63 |
64 | void BricksTextureGenerator::generate(QSize size,
65 | TexturePixel* destimage,
66 | QMap sourceimages,
67 | TextureNodeSettings* settings) const
68 | {
69 | if (!settings || !destimage || !size.isValid()) {
70 | return;
71 | }
72 | QColor color = settings->value("color").value();
73 | int linewidth = settings->value("linewidth").toDouble() * size.height() / 300;
74 | int brickheight = settings->value("brickheight").toDouble() * size.height() / 300;
75 | int brickwidth = settings->value("brickwidth").toDouble() * size.width() / 300;
76 | int offsetx = settings->value("offsetx").toDouble() * size.width() / 100;
77 | int offsety = settings->value("offsety").toDouble() * size.height() / 100;
78 |
79 | if (sourceimages.contains(0)) {
80 | memcpy(destimage, sourceimages.value(0)->getData(), size.width() * size.height() * sizeof(TexturePixel));
81 | } else {
82 | memset(destimage, 0, size.width() * size.height() * sizeof(TexturePixel));
83 | }
84 |
85 | bool invert = false;
86 | QVector lines;
87 |
88 | int currY = offsety - size.height() - brickheight / 2;
89 | while (currY < (size.height() + linewidth / 2)) {
90 | if (currY > (-linewidth / 2) && currY < (size.height() + linewidth)) {
91 | lines.append(QLine(0, currY, size.width(), currY));
92 | }
93 | invert = !invert;
94 | int currX = offsetx - size.width() - brickwidth / 2;
95 | if (invert) {
96 | currX += brickwidth / 2;
97 | }
98 | while (currX < (size.width() + linewidth / 2)) {
99 | if (currX > (-linewidth / 2) && currX < (size.width() + linewidth)) {
100 | lines.append(QLine(currX, currY, currX, currY + brickheight + linewidth));
101 | }
102 | currX += brickwidth + linewidth;
103 | }
104 | currY += brickheight + linewidth;
105 | }
106 | QImage tempimage = QImage(size.width(), size.height(), QImage::Format_RGB32);
107 | memcpy(tempimage.bits(), destimage, size.width() * size.height() * sizeof(TexturePixel));
108 | QPainter painter(&tempimage);
109 | painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
110 | painter.setBrush(QBrush(color, Qt::BrushStyle::SolidPattern));
111 | painter.setPen(QPen(color, linewidth, Qt::SolidLine, Qt::FlatCap, Qt::BevelJoin));
112 | painter.drawLines(lines);
113 | memcpy(destimage, tempimage.bits(), size.width() * size.height() * sizeof(TexturePixel));
114 | }
115 |
--------------------------------------------------------------------------------
/generators/bricks.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Part of the ProceduralTextureMaker project.
3 | * http://github.com/johanokl/ProceduralTextureMaker
4 | * Released under GPLv3.
5 | * Johan Lindqvist (johan.lindqvist@gmail.com)
6 | */
7 |
8 | #ifndef BRICKSTEXTUREGENERATOR_H
9 | #define BRICKSTEXTUREGENERATOR_H
10 |
11 | #include "texturegenerator.h"
12 |
13 | /**
14 | * @brief The BricksTextureGenerator class
15 | */
16 | class BricksTextureGenerator : public TextureGenerator
17 | {
18 | public:
19 | BricksTextureGenerator();
20 | ~BricksTextureGenerator() override = default;
21 | void generate(QSize size,
22 | TexturePixel* destimage,
23 | QMap sourceimages,
24 | TextureNodeSettings* settings) const override;
25 | int getNumSourceSlots() const override { return 1; }
26 | QString getName() const override { return QString("Bricks"); }
27 | const TextureGeneratorSettings& getSettings() const override { return configurables; }
28 | QString getDescription() const override { return QString("Draws rectangle bricks"); }
29 | TextureGenerator::Type getType() const override { return TextureGenerator::Type::Generator; }
30 |
31 | private:
32 | TextureGeneratorSettings configurables;
33 | };
34 |
35 | #endif // BRICKSTEXTUREGENERATOR_H
36 |
--------------------------------------------------------------------------------
/generators/checkboard.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Part of the ProceduralTextureMaker project.
3 | * http://github.com/johanokl/ProceduralTextureMaker
4 | * Released under GPLv3.
5 | * Johan Lindqvist (johan.lindqvist@gmail.com)
6 | */
7 |
8 | #include "checkboard.h"
9 | #include
10 | #include
11 |
12 | CheckboardTextureGenerator::CheckboardTextureGenerator()
13 | {
14 | TextureGeneratorSetting color;
15 | color.name = "Color";
16 | color.defaultvalue = QVariant(QColor(0, 0, 0, 255));
17 | color.order = 1;
18 | configurables.insert("color", color);
19 |
20 | TextureGeneratorSetting brickwidth;
21 | brickwidth.name = "Brick width";
22 | brickwidth.defaultvalue = QVariant((int) 10);
23 | brickwidth.min = QVariant(1);
24 | brickwidth.max = QVariant(300);
25 | brickwidth.order = 2;
26 | configurables.insert("brickwidth", brickwidth);
27 |
28 | TextureGeneratorSetting brickheight;
29 | brickheight.name = "Brick height";
30 | brickheight.defaultvalue = QVariant((int) 10);
31 | brickheight.min = QVariant(1);
32 | brickheight.max = QVariant(300);
33 | brickheight.order = 3;
34 | configurables.insert("brickheight", brickheight);
35 |
36 | TextureGeneratorSetting offsetx;
37 | offsetx.name = "Offset left";
38 | offsetx.defaultvalue = QVariant((int) 0);
39 | offsetx.min = QVariant(-100);
40 | offsetx.max = QVariant(100);
41 | offsetx.order = 4;
42 | configurables.insert("offsetx", offsetx);
43 |
44 | TextureGeneratorSetting offsety;
45 | offsety.name = "Offset top";
46 | offsety.defaultvalue = QVariant((int) 0);
47 | offsety.min = QVariant(-100);
48 | offsety.max = QVariant(100);
49 | offsety.order = 5;
50 | configurables.insert("offsety", offsety);
51 | }
52 |
53 |
54 | void CheckboardTextureGenerator::generate(QSize size,
55 | TexturePixel* destimage,
56 | QMap sourceimages,
57 | TextureNodeSettings* settings) const
58 | {
59 | if (!settings || !destimage || !size.isValid()) {
60 | return;
61 | }
62 | QColor color = settings->value("color").value();
63 | int brickheight = settings->value("brickheight").toDouble() * size.height() / 300;
64 | int brickwidth = settings->value("brickwidth").toDouble() * size.width() / 300;
65 | int offsetx = settings->value("offsetx").toDouble() * size.width() / 100;
66 | int offsety = settings->value("offsety").toDouble() * size.height() / 100;
67 |
68 | if (sourceimages.contains(0)) {
69 | memcpy(destimage, sourceimages.value(0)->getData(), size.width() * size.height() * sizeof(TexturePixel));
70 | } else {
71 | memset(destimage, 0, size.width() * size.height() * sizeof(TexturePixel));
72 | }
73 | QImage tempimage = QImage(size.width(), size.height(), QImage::Format_RGB32);
74 | memcpy(tempimage.bits(), destimage, size.width() * size.height() * sizeof(TexturePixel));
75 | QPainter painter(&tempimage);
76 | painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
77 | painter.setBrush(QBrush(color, Qt::BrushStyle::SolidPattern));
78 | painter.setPen(Qt::NoPen);
79 |
80 | bool invert = false;
81 | int currY = offsety - size.height() - brickheight;
82 | while (currY < size.height()) {
83 | invert = !invert;
84 | int currX = offsetx - size.width() - brickwidth;
85 | if (invert) {
86 | currX += brickwidth;
87 | }
88 | while (currX < size.width()) {
89 | painter.drawRect(currX, currY, brickwidth, brickheight);
90 | currX += brickwidth * 2;
91 | }
92 | currY += brickheight;
93 | }
94 | memcpy(destimage, tempimage.bits(), size.width() * size.height() * sizeof(TexturePixel));
95 | }
96 |
--------------------------------------------------------------------------------
/generators/checkboard.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Part of the ProceduralTextureMaker project.
3 | * http://github.com/johanokl/ProceduralTextureMaker
4 | * Released under GPLv3.
5 | * Johan Lindqvist (johan.lindqvist@gmail.com)
6 | */
7 |
8 | #ifndef CHECKBOARDTEXTUREGENERATOR_H
9 | #define CHECKBOARDTEXTUREGENERATOR_H
10 |
11 | #include "texturegenerator.h"
12 |
13 | /**
14 | * @brief The CheckboardTextureGenerator class
15 | */
16 | class CheckboardTextureGenerator : public TextureGenerator
17 | {
18 | public:
19 | CheckboardTextureGenerator();
20 | ~CheckboardTextureGenerator() override = default;
21 | void generate(QSize size,
22 | TexturePixel* destimage,
23 | QMap sourceimages,
24 | TextureNodeSettings* settings) const override;
25 | int getNumSourceSlots() const override { return 1; }
26 | QString getName() const override { return QString("Checkboard"); }
27 | const TextureGeneratorSettings& getSettings() const override { return configurables; }
28 | QString getDescription() const override { return QString("Draws a checkboard."); }
29 | TextureGenerator::Type getType() const override { return TextureGenerator::Type::Generator; }
30 |
31 | private:
32 | TextureGeneratorSettings configurables;
33 | };
34 |
35 | #endif // CHECKBOARDTEXTUREGENERATOR_H
36 |
--------------------------------------------------------------------------------
/generators/circle.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Part of the ProceduralTextureMaker project.
3 | * http://github.com/johanokl/ProceduralTextureMaker
4 | * Released under GPLv3.
5 | * Johan Lindqvist (johan.lindqvist@gmail.com)
6 | */
7 |
8 | #include "circle.h"
9 | #include
10 | #include
11 |
12 | CircleTextureGenerator::CircleTextureGenerator()
13 | {
14 | TextureGeneratorSetting colorsetting;
15 | colorsetting.name = "Color";
16 | colorsetting.description = "Color of the circle";
17 | colorsetting.defaultvalue = QVariant(QColor(200, 100, 0, 200));
18 | colorsetting.order = 1;
19 | configurables.insert("color", colorsetting);
20 |
21 | TextureGeneratorSetting innerRadius;
22 | innerRadius.name = "Inner radius";
23 | innerRadius.description = "Inner radius of the circle in percent of width";
24 | innerRadius.defaultvalue = QVariant((double) 0);
25 | innerRadius.min = QVariant(0);
26 | innerRadius.max = QVariant(200);
27 | innerRadius.order = 2;
28 | configurables.insert("innerradius", innerRadius);
29 |
30 | TextureGeneratorSetting outerRadius;
31 | outerRadius.name = "Outer radius";
32 | outerRadius.description = "Outer radius of the circle in percent of width";
33 | outerRadius.defaultvalue = QVariant((double) 100);
34 | outerRadius.min = QVariant(0);
35 | outerRadius.max = QVariant(200);
36 | outerRadius.order = 3;
37 | configurables.insert("outerradius", outerRadius);
38 |
39 | TextureGeneratorSetting offsetLeft;
40 | offsetLeft.name = "Offset left";
41 | offsetLeft.description = "Inner radius of the circle in percent of width";
42 | offsetLeft.defaultvalue = QVariant((double) 0);
43 | offsetLeft.min = QVariant(-100);
44 | offsetLeft.max = QVariant(100);
45 | offsetLeft.order = 4;
46 | configurables.insert("offsetleft", offsetLeft);
47 |
48 | TextureGeneratorSetting offsetTop;
49 | offsetTop.name = "Offset top";
50 | offsetTop.description = "Outer radius of the circle in percent of width";
51 | offsetTop.defaultvalue = QVariant((double) 0);
52 | offsetTop.min = QVariant(-100);
53 | offsetTop.max = QVariant(100);
54 | offsetTop.order = 5;
55 | configurables.insert("offsettop", offsetTop);
56 | }
57 |
58 |
59 | void CircleTextureGenerator::generate(QSize size,
60 | TexturePixel* destimage,
61 | QMap sourceimages,
62 | TextureNodeSettings* settings) const
63 | {
64 | if (!settings || !destimage || !size.isValid()) {
65 | return;
66 | }
67 | QColor color = settings->value("color").value();
68 | double innerRadius = settings->value("innerradius").toDouble() * size.height() / 200.0;
69 | double outerRadius = settings->value("outerradius").toDouble() * size.height() / 200.0;
70 | int offsetLeft = settings->value("offsetleft").toDouble() * size.width() / 100;
71 | int offsetTop = settings->value("offsettop").toDouble() * size.height() / 100;
72 |
73 | bool blend = false;
74 | if (sourceimages.contains(0)) {
75 | memcpy(destimage, sourceimages.value(0)->getData(), size.width() * size.height() * sizeof(TexturePixel));
76 | blend = true;
77 | } else {
78 | memset(destimage, 0, size.width() * size.height() * sizeof(TexturePixel));
79 | }
80 | if (color.alpha() == 255) {
81 | blend = false;
82 | }
83 | double alpha = color.alphaF();
84 | double srcAlpha = 1 - alpha;
85 | for (int y = 0; y < size.height(); y++) {
86 | for (int x = 0; x < size.width(); x++) {
87 | if (((pow(abs(size.width() / 2 - x + offsetLeft), 2)
88 | + pow(abs(size.height() / 2 - y + offsetTop), 2))
89 | >= (pow(innerRadius, 2))) &&
90 | ((pow(abs(size.width() / 2 - x + offsetLeft), 2)
91 | + pow(abs(size.height() / 2 - y + offsetTop), 2))
92 | <= (pow(outerRadius, 2)))) {
93 | int thisPos = y * size.width() + x;
94 | destimage[thisPos].r = static_cast(alpha * color.red() + (blend ? (srcAlpha * destimage[thisPos].r) : 0));
95 | destimage[thisPos].g = static_cast(alpha * color.green() + (blend ? (srcAlpha * destimage[thisPos].g) : 0));
96 | destimage[thisPos].b = static_cast(alpha * color.blue() + (blend ? (srcAlpha * destimage[thisPos].b) : 0));
97 | destimage[thisPos].a = static_cast(color.alpha() + (blend ? (srcAlpha * destimage[thisPos].a) : 0));
98 | }
99 | }
100 | }
101 | }
102 |
--------------------------------------------------------------------------------
/generators/circle.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Part of the ProceduralTextureMaker project.
3 | * http://github.com/johanokl/ProceduralTextureMaker
4 | * Released under GPLv3.
5 | * Johan Lindqvist (johan.lindqvist@gmail.com)
6 | */
7 |
8 | #ifndef CIRCLETEXTUREGENERATOR_H
9 | #define CIRCLETEXTUREGENERATOR_H
10 |
11 | #include "texturegenerator.h"
12 |
13 | /**
14 | * @brief The CircleTextureGenerator class
15 | */
16 | class CircleTextureGenerator : public TextureGenerator
17 | {
18 | public:
19 | CircleTextureGenerator();
20 | ~CircleTextureGenerator() override = default;
21 | void generate(QSize size,
22 | TexturePixel* destimage,
23 | QMap sourceimages,
24 | TextureNodeSettings* settings) const override;
25 | int getNumSourceSlots() const override { return 1; }
26 | QString getName() const override { return QString("Circle"); }
27 | const TextureGeneratorSettings& getSettings() const override { return configurables; }
28 | QString getDescription() const override { return QString("Draws a filled circle."); }
29 | TextureGenerator::Type getType() const override { return TextureGenerator::Type::Generator; }
30 |
31 | private:
32 | TextureGeneratorSettings configurables;
33 | };
34 |
35 | #endif // CIRCLETEXTUREGENERATOR_H
36 |
--------------------------------------------------------------------------------
/generators/cutout.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Part of the ProceduralTextureMaker project.
3 | * http://github.com/johanokl/ProceduralTextureMaker
4 | * Released under GPLv3.
5 | * Johan Lindqvist (johan.lindqvist@gmail.com)
6 | */
7 |
8 | #include "cutout.h"
9 |
10 | CutoutTextureGenerator::CutoutTextureGenerator()
11 | {
12 | QStringList ordering;
13 | ordering.append("Slot 2 cut out from Slot 1");
14 | ordering.append("Slot 1 cut out from Slot 2");
15 | TextureGeneratorSetting order;
16 | order.name = "Order";
17 | order.defaultvalue = QVariant(ordering);
18 | order.defaultindex = 0;
19 | order.order = 1;
20 | configurables.insert("order", order);
21 |
22 | TextureGeneratorSetting factor;
23 | factor.name = "Factor";
24 | factor.defaultvalue = QVariant((int) 1);
25 | factor.min = 1;
26 | factor.max = 255;
27 | factor.defaultindex = 0;
28 | factor.order = 2;
29 | configurables.insert("factor", factor);
30 | }
31 |
32 |
33 | void CutoutTextureGenerator::generate(QSize size, TexturePixel* destimage,
34 | QMap sourceimages,
35 | TextureNodeSettings* settings) const
36 | {
37 | if (!settings || !destimage || !size.isValid()) {
38 | return;
39 | }
40 | QString order = settings->value("order").toString();
41 | int factor = settings->value("factor").toInt();
42 |
43 | int first = 0;
44 | int second = 1;
45 | if (order == "Slot 1 cut out from Slot 2") {
46 | first = 1;
47 | second = 0;
48 | }
49 | TexturePixel* originSource = nullptr;
50 | TexturePixel* subtractSource = nullptr;
51 | if (sourceimages.contains(first)) {
52 | originSource = sourceimages.value(first).data()->getData();
53 | }
54 | if (sourceimages.contains(second)) {
55 | subtractSource = sourceimages.value(second).data()->getData();
56 | }
57 | int numPixels = size.width() * size.height();
58 | if (originSource && subtractSource) {
59 | memcpy(destimage, originSource, numPixels * sizeof(TexturePixel));
60 | for (int i = 0; i < numPixels; i++) {
61 | if (destimage[i].a > (factor * subtractSource[i].a)) {
62 | destimage[i].a -= subtractSource[i].a;
63 | } else {
64 | destimage[i].a = 0;
65 | }
66 | }
67 | } else if (originSource) {
68 | memcpy(destimage, originSource, numPixels * sizeof(TexturePixel));
69 | } else if (subtractSource) {
70 | memcpy(destimage, subtractSource, numPixels * sizeof(TexturePixel));
71 | } else {
72 | memset(destimage, 0, numPixels * sizeof(TexturePixel));
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/generators/cutout.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Part of the ProceduralTextureMaker project.
3 | * http://github.com/johanokl/ProceduralTextureMaker
4 | * Released under GPLv3.
5 | * Johan Lindqvist (johan.lindqvist@gmail.com)
6 | */
7 |
8 | #ifndef CUTOUTTEXTUREGENERATOR_H
9 | #define CUTOUTTEXTUREGENERATOR_H
10 |
11 | #include "texturegenerator.h"
12 |
13 | /**
14 | * @brief The CutoutTextureGenerator class
15 | */
16 | class CutoutTextureGenerator : public TextureGenerator
17 | {
18 | public:
19 | CutoutTextureGenerator();
20 | ~CutoutTextureGenerator() override = default;
21 | void generate(QSize size,
22 | TexturePixel* destimage,
23 | QMap sourceimages,
24 | TextureNodeSettings* settings) const override;
25 | int getNumSourceSlots() const override { return 2; }
26 | QString getName() const override { return QString("Cutout"); }
27 | const TextureGeneratorSettings& getSettings() const override { return configurables; }
28 | QString getDescription() const override { return QString("Cut alpha from one image using another."); }
29 | TextureGenerator::Type getType() const override { return TextureGenerator::Type::Combiner; }
30 |
31 | private:
32 | TextureGeneratorSettings configurables;
33 | };
34 |
35 | #endif // CUTOUTTEXTUREGENERATOR_H
36 |
37 |
38 |
--------------------------------------------------------------------------------
/generators/displacementmap.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Part of the ProceduralTextureMaker project.
3 | * http://github.com/johanokl/ProceduralTextureMaker
4 | * Released under GPLv3.
5 | * Johan Lindqvist (johan.lindqvist@gmail.com)
6 | */
7 |
8 | #include
9 | #include
10 | #include "displacementmap.h"
11 |
12 | using namespace std;
13 |
14 | DisplacementMapTextureGenerator::DisplacementMapTextureGenerator()
15 | {
16 | TextureGeneratorSetting angle;
17 | angle.name = "Angle";
18 | angle.defaultvalue = QVariant((double) 45);
19 | angle.min = QVariant(-360);
20 | angle.max = QVariant(360);
21 | angle.order = 1;
22 | configurables.insert("angle", angle);
23 |
24 | TextureGeneratorSetting strength;
25 | strength.name = "Strength";
26 | strength.defaultvalue = QVariant((double) 0.5);
27 | strength.min = QVariant(0);
28 | strength.max = QVariant(3);
29 | strength.order = 3;
30 | configurables.insert("strength", strength);
31 |
32 | TextureGeneratorSetting offset;
33 | offset.name = "Offset";
34 | offset.defaultvalue = QVariant((double) 0);
35 | offset.min = QVariant(-360);
36 | offset.max = QVariant(360);
37 | offset.order = 4;
38 | configurables.insert("offset", offset);
39 |
40 | }
41 |
42 |
43 | void DisplacementMapTextureGenerator::generate(QSize size,
44 | TexturePixel* destimage,
45 | QMap sourceimages,
46 | TextureNodeSettings* settings) const
47 | {
48 | if (!settings || !destimage || !size.isValid()) {
49 | return;
50 | }
51 | if (!sourceimages.contains(0)) {
52 | memset(destimage, 0, size.width() * size.height() * sizeof(TexturePixel));
53 | return;
54 | }
55 | TexturePixel* sourceImage = sourceimages.value(0)->getData();
56 | if (!sourceimages.contains(1)) {
57 | memcpy(destimage, sourceImage, size.width() * size.height() * sizeof(TexturePixel));
58 | return;
59 | }
60 | TexturePixel* sourceMap = sourceimages.value(1)->getData();
61 |
62 | double strength = settings->value("strength").toDouble() * size.width() / 500;
63 | double offset = settings->value("offset").toDouble() * size.width() / 100;
64 | double angle = settings->value("angle").toDouble();
65 | angle = (angle / 180.0) * ((double) M_PI);
66 |
67 | for (int y = 0; y < size.height(); y++) {
68 | for (int x = 0; x < size.width(); x++) {
69 | double srcDistance = sourceMap[y * size.width() + x].intensityWithAlpha();
70 | srcDistance *= strength;
71 | srcDistance -= offset;
72 | int xpos = x + srcDistance * sin(angle);
73 | int ypos = y - srcDistance * cos(angle);
74 | xpos = xpos > size.height() ? xpos % size.height() :
75 | (xpos < 0 ? xpos + size.width() : xpos);
76 | ypos = ypos > size.height() ? ypos % size.height() :
77 | (ypos < 0 ? ypos + size.height() : ypos);
78 | xpos = qMax(qMin(xpos, size.width() - 1), 0);
79 | ypos = qMax(qMin(ypos, size.height() - 1), 0);
80 | destimage[y * size.width() + x] = sourceImage[ypos * size.width() + xpos];
81 | }
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/generators/displacementmap.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Part of the ProceduralTextureMaker project.
3 | * http://github.com/johanokl/ProceduralTextureMaker
4 | * Released under GPLv3.
5 | * Johan Lindqvist (johan.lindqvist@gmail.com)
6 | */
7 |
8 | #ifndef DISPLACEMENTMAPTEXTUREGENERATOR_H
9 | #define DISPLACEMENTMAPTEXTUREGENERATOR_H
10 |
11 | #include "texturegenerator.h"
12 |
13 | /**
14 | * @brief The DisplacementMapTextureGenerator class
15 | */
16 | class DisplacementMapTextureGenerator : public TextureGenerator
17 | {
18 | public:
19 | DisplacementMapTextureGenerator();
20 | ~DisplacementMapTextureGenerator() override = default;
21 | void generate(QSize size,
22 | TexturePixel* destimage,
23 | QMap sourceimages,
24 | TextureNodeSettings* settings) const override;
25 | int getNumSourceSlots() const override { return 2; }
26 | QString getSlotName(int num) override {
27 | if (num == 1) return QString("Map");
28 | return QString("Source image");
29 | }
30 | QString getName() const override { return QString("Displacement"); }
31 | const TextureGeneratorSettings& getSettings() const override { return configurables; }
32 | QString getDescription() const override {
33 | return QString("Transforms the image based on a gray-scale transform map.");
34 | }
35 | TextureGenerator::Type getType() const override { return TextureGenerator::Type::Filter; }
36 |
37 | private:
38 | TextureGeneratorSettings configurables;
39 | };
40 |
41 | #endif // DISPLACEMENTMAPTEXTUREGENERATOR_H
42 |
--------------------------------------------------------------------------------
/generators/empty.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Part of the ProceduralTextureMaker project.
3 | * http://github.com/johanokl/ProceduralTextureMaker
4 | * Released under GPLv3.
5 | * Johan Lindqvist (johan.lindqvist@gmail.com)
6 | */
7 |
8 | #include "empty.h"
9 |
10 | void EmptyGenerator::generate(QSize size, TexturePixel* destimage,
11 | QMap sourceimages,
12 | TextureNodeSettings* settings) const
13 | {
14 | Q_UNUSED(settings);
15 | Q_UNUSED(sourceimages);
16 | if (destimage && size.isValid()) {
17 | memset(destimage, 0, size.width() * size.height() * sizeof(TexturePixel));
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/generators/empty.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Part of the ProceduralTextureMaker project.
3 | * http://github.com/johanokl/ProceduralTextureMaker
4 | * Released under GPLv3.
5 | * Johan Lindqvist (johan.lindqvist@gmail.com)
6 | */
7 |
8 | #ifndef EMPTYGENERATOR_H
9 | #define EMPTYGENERATOR_H
10 |
11 | #include "texturegenerator.h"
12 |
13 | /**
14 | * @brief The EmptyGenerator class
15 | */
16 | class EmptyGenerator : public TextureGenerator
17 | {
18 | public:
19 | EmptyGenerator() = default;
20 | ~EmptyGenerator() override = default;
21 | void generate(QSize size,
22 | TexturePixel* destimage,
23 | QMap sourceimages,
24 | TextureNodeSettings* settings) const override;
25 | int getNumSourceSlots() const override { return 3; }
26 | QString getName() const override { return QString("Empty"); }
27 | const TextureGeneratorSettings& getSettings() const override { return _settings; }
28 | QString getDescription() const override { return QString("Empty generator."); }
29 | TextureGenerator::Type getType() const override { return TextureGenerator::Type::Generator; }
30 |
31 | private:
32 | TextureGeneratorSettings _settings;
33 | };
34 |
35 | #endif // EMPTYGENERATOR_H
36 |
--------------------------------------------------------------------------------
/generators/fill.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Part of the ProceduralTextureMaker project.
3 | * http://github.com/johanokl/ProceduralTextureMaker
4 | * Released under GPLv3.
5 | * Johan Lindqvist (johan.lindqvist@gmail.com)
6 | */
7 |
8 | #include "fill.h"
9 | #include
10 |
11 | FillTextureGenerator::FillTextureGenerator()
12 | {
13 | TextureGeneratorSetting colorsetting;
14 | colorsetting.defaultvalue = QVariant(QColor(255, 255, 255, 255));
15 | colorsetting.name = "Color";
16 | colorsetting.description = "Color to fill the texture with.";
17 | configurables.insert("color", colorsetting);
18 | }
19 |
20 |
21 | void FillTextureGenerator::generate(QSize size, TexturePixel* destimage,
22 | QMap sourceimages,
23 | TextureNodeSettings* settings) const
24 | {
25 | Q_UNUSED(sourceimages);
26 |
27 | if (!settings || !destimage || !size.isValid()) {
28 | return;
29 | }
30 | QColor color = settings->value("color").value();
31 | const int numpixels = size.width() * size.height();
32 | TexturePixel filler(static_cast(color.red()), static_cast(color.green()),
33 | static_cast(color.blue()), static_cast(color.alpha()));
34 | for (int i = 0; i < numpixels; i++) {
35 | destimage[i] = filler;
36 | }
37 | }
38 |
39 |
40 |
--------------------------------------------------------------------------------
/generators/fill.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Part of the ProceduralTextureMaker project.
3 | * http://github.com/johanokl/ProceduralTextureMaker
4 | * Released under GPLv3.
5 | * Johan Lindqvist (johan.lindqvist@gmail.com)
6 | */
7 |
8 | #ifndef FILLTEXTUREGENERATOR_H
9 | #define FILLTEXTUREGENERATOR_H
10 |
11 | #include "texturegenerator.h"
12 |
13 | /**
14 | * @brief The FillTextureGenerator class
15 | */
16 | class FillTextureGenerator : public TextureGenerator
17 | {
18 | public:
19 | FillTextureGenerator();
20 | ~FillTextureGenerator() override = default;
21 | void generate(QSize size,
22 | TexturePixel* destimage,
23 | QMap sourceimages,
24 | TextureNodeSettings* settings) const override;
25 | int getNumSourceSlots() const override { return 0; }
26 | QString getName() const override { return QString("Fill"); }
27 | const TextureGeneratorSettings& getSettings() const override { return configurables; }
28 | QString getDescription() const override { return QString("Fills the whole texture with the specified color."); }
29 | TextureGenerator::Type getType() const override { return TextureGenerator::Type::Generator; }
30 |
31 | private:
32 | TextureGeneratorSettings configurables;
33 | };
34 |
35 | #endif // FILLTEXTUREGENERATOR_H
36 |
--------------------------------------------------------------------------------
/generators/fire.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Part of the ProceduralTextureMaker project.
3 | * http://github.com/johanokl/ProceduralTextureMaker
4 | * Released under GPLv3.
5 | * Johan Lindqvist (johan.lindqvist@gmail.com)
6 | */
7 |
8 | #include "fire.h"
9 | #include
10 | #include
11 | #if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
12 | #include
13 | #endif
14 |
15 | /**
16 | * @brief FireTextureGenerator::FireTextureGenerator
17 | *
18 | * The algorithm is taken from Lode's Computer Graphics Tutorial
19 | * http://lodev.org/cgtutor/fire.html
20 | */
21 | FireTextureGenerator::FireTextureGenerator()
22 | {
23 | TextureGeneratorSetting falloff;
24 | falloff.defaultvalue = QVariant((double) 0.10);
25 | falloff.min = QVariant(0);
26 | falloff.max = QVariant(0.5);
27 | falloff.name = "Falloff";
28 | falloff.order = 1;
29 | configurables.insert("falloff", falloff);
30 |
31 | TextureGeneratorSetting iterations;
32 | iterations.defaultvalue = QVariant((int) 150);
33 | iterations.min = QVariant(1);
34 | iterations.max = QVariant(400);
35 | iterations.name = "Iterations";
36 | iterations.order = 2;
37 | configurables.insert("iterations", iterations);
38 |
39 | TextureGeneratorSetting randomize;
40 | randomize.defaultvalue = QVariant((int) 5);
41 | randomize.min = QVariant(1);
42 | randomize.max = QVariant(500);
43 | randomize.name = "Random seed";
44 | randomize.order = 3;
45 | configurables.insert("randomize", randomize);
46 | }
47 |
48 |
49 | void FireTextureGenerator::generate(QSize size, TexturePixel* destimage,
50 | QMap sourceimages,
51 | TextureNodeSettings* settings) const
52 | {
53 | if (!settings || !destimage || !size.isValid()) {
54 | return;
55 | }
56 | double falloff = 0.245 + settings->value("falloff").toDouble() / 100;
57 | int iterations = settings->value("iterations").toInt();
58 | uint randomize = settings->value("randomize").toUInt();
59 | #if QT_VERSION < QT_VERSION_CHECK(5, 10, 0)
60 | qsrand(randomize);
61 | #else
62 | QRandomGenerator random(randomize);
63 | #endif
64 | // Speed things up by having a smaller rendering surface.
65 | int screenWidth = 150;
66 | int screenHeight = 150;
67 | auto* renderSurface = new TexturePixel[screenWidth * screenHeight];
68 | auto* fire = new int[screenHeight * screenWidth]; //this buffer will contain the fire
69 | QColor palette[256]; //this will contain the color palette
70 | memset(fire, 0, screenWidth * screenWidth * sizeof(int));
71 |
72 | for (int x = 0; x < 256; x++) {
73 | // generate the palette
74 | // Hue goes from 0 to 85: red to yellow
75 | // Saturation is always the maximum: 255
76 | // Lightness is 0..255 for x=0..128, and 255 for x=128..255
77 | palette[x] = QColor::fromHsl(x / 3, 255, std::min(255, x * 2));
78 | }
79 | for (int i = 0; i < iterations; i++) {
80 | // randomize the bottom row of the fire buffer
81 | for (int x = 0; x < screenWidth; x++) {
82 | fire[(screenHeight - 1) * screenWidth + x] =
83 | #if QT_VERSION < QT_VERSION_CHECK(5, 10, 0)
84 | abs(32768 + qrand()) % 256;
85 | #else
86 | abs(32768 + random.bounded(RAND_MAX)) % 256;
87 | #endif
88 |
89 | }
90 | // do the fire calculations for every pixel
91 | for (int y = 0; y < screenHeight - 1; y++) {
92 | for (int x = 0; x < screenWidth; x++) {
93 | fire[y * screenWidth + x] = (int)
94 | ((fire[screenWidth * ((y + 1) % screenHeight) + ((x - 1 + screenWidth) % screenWidth)]
95 | + fire[screenWidth * ((y + 2) % screenHeight) + ((x) % screenWidth)]
96 | + fire[screenWidth * ((y + 1) % screenHeight) + ((x + 1) % screenWidth)]
97 | + fire[screenWidth * ((y + 3) % screenHeight) + ((x) % screenWidth)])
98 | * falloff) % 255;
99 | }
100 | }
101 | for (int y = 0; y < screenHeight; y++) {
102 | for (int x = 0; x < screenWidth; x++) {
103 | int thisPos = y * screenWidth + x;
104 | renderSurface[thisPos].r = palette[fire[y * screenWidth + x]].red();
105 | renderSurface[thisPos].g = palette[fire[y * screenWidth + x]].green();
106 | renderSurface[thisPos].b = palette[fire[y * screenWidth + x]].blue();
107 | renderSurface[thisPos].a = renderSurface[thisPos].r;
108 | }
109 | }
110 | }
111 | delete[] fire;
112 | QImage tempimage = QImage(screenWidth, screenHeight, QImage::Format_ARGB32);
113 | memcpy(tempimage.bits(), renderSurface, screenWidth * screenHeight * sizeof(TexturePixel));
114 | tempimage = tempimage.scaled(size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
115 |
116 | QImage destobject(size.width(), size.height(), QImage::Format_ARGB32);
117 | if (sourceimages.contains(0)) {
118 | memcpy(destobject.bits(), sourceimages.value(0)->getData(), size.width() * size.height() * sizeof(TexturePixel));
119 | } else {
120 | memset(destobject.bits(), 0, size.width() * size.height() * sizeof(TexturePixel));
121 | }
122 | QPainter painter(&destobject);
123 | painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
124 | painter.drawImage(QPoint(0, 0), tempimage);
125 | memcpy(destimage, destobject.bits(), size.width() * size.height() * sizeof(TexturePixel));
126 | }
127 |
--------------------------------------------------------------------------------
/generators/fire.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Part of the ProceduralTextureMaker project.
3 | * http://github.com/johanokl/ProceduralTextureMaker
4 | * Released under GPLv3.
5 | * Johan Lindqvist (johan.lindqvist@gmail.com)
6 | */
7 |
8 | #ifndef FIRETEXTUREGENERATOR_H
9 | #define FIRETEXTUREGENERATOR_H
10 |
11 | #include "texturegenerator.h"
12 |
13 | /**
14 | * @brief The FireTextureGenerator class
15 | *
16 | * The algorithm is taken from Lode's Computer Graphics Tutorial
17 | * http://lodev.org/cgtutor/fire.html
18 | */
19 | class FireTextureGenerator : public TextureGenerator
20 | {
21 | public:
22 | FireTextureGenerator();
23 | ~FireTextureGenerator() override = default;
24 | void generate(QSize size,
25 | TexturePixel* destimage,
26 | QMap sourceimages,
27 | TextureNodeSettings* settings) const override;
28 | const TextureGeneratorSettings& getSettings() const override { return configurables; }
29 | int getNumSourceSlots() const override { return 1; }
30 | QString getName() const override { return "Fire"; }
31 | QString getDescription() const override { return QString("Early 90's fire effect"); }
32 | TextureGenerator::Type getType() const override { return TextureGenerator::Type::Generator; }
33 |
34 | private:
35 | double noise(double x, double y) const;
36 | double findnoise2(double x,double y) const;
37 | double interpolate(double a, double b, double x) const;
38 |
39 | TextureGeneratorSettings configurables;
40 | };
41 |
42 | #endif // FIRETEXTUREGENERATOR_H
43 |
--------------------------------------------------------------------------------
/generators/gaussianblur.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Part of the ProceduralTextureMaker project.
3 | * http://github.com/johanokl/ProceduralTextureMaker
4 | * Released under GPLv3.
5 | * Johan Lindqvist (johan.lindqvist@gmail.com)
6 | */
7 |
8 | #include "gaussianblur.h"
9 | #include
10 | #include
11 |
12 | GaussianBlurTextureGenerator::GaussianBlurTextureGenerator()
13 | {
14 | TextureGeneratorSetting neighbourssetting;
15 | neighbourssetting.defaultvalue = QVariant((int) 1);
16 | neighbourssetting.name = "Neighbours";
17 | neighbourssetting.description = "Number of neighbours";
18 | neighbourssetting.min = QVariant(1);
19 | neighbourssetting.max = QVariant(30);
20 | neighbourssetting.order = 1;
21 | configurables.insert("numneighbours", neighbourssetting);
22 |
23 | TextureGeneratorSetting weightsetting;
24 | weightsetting.defaultvalue = QVariant((double) 1);
25 | weightsetting.name = "Weight";
26 | weightsetting.description = "";
27 | weightsetting.min = QVariant(0);
28 | weightsetting.max = QVariant(4);
29 | weightsetting.order = 2;
30 | configurables.insert("weight", weightsetting);
31 | }
32 |
33 |
34 | float* GaussianBlurTextureGenerator::ComputeGaussianKernel(const int inRadius, const float radiusModifier) const
35 | {
36 | int mem_amount = (inRadius * 2) + 1;
37 | auto* gaussian_kernel = new float[mem_amount];
38 |
39 | float twoRadiusSquaredRecip = 0.5 / (inRadius * inRadius);
40 | float sqrtTwoPiTimesRadiusRecip = 1.0 / (sqrt(M_PI * 2) * inRadius);
41 |
42 | // Create Gaussian Kernel
43 | int r = -inRadius;
44 | float sum = 0;
45 | for (int i = 0; i < mem_amount; i++) {
46 | float x = r * radiusModifier;
47 | x = x * x;
48 | float v = sqrtTwoPiTimesRadiusRecip * exp(-x * twoRadiusSquaredRecip);
49 | gaussian_kernel[i] = v;
50 | sum += v;
51 | r++;
52 | }
53 | // Normalize distribution
54 | float div = sum;
55 | for (int i = 0; i < mem_amount; i++) {
56 | gaussian_kernel[i] /= div;
57 | }
58 | return gaussian_kernel;
59 | }
60 |
61 |
62 | // Calculates the Gaussian Blur and stores the result on the height map given
63 | void GaussianBlurTextureGenerator::generate(QSize size,
64 | TexturePixel* destimage,
65 | QMap sourceimages,
66 | TextureNodeSettings* settings) const
67 | {
68 | if (!settings || !destimage || !size.isValid()) {
69 | return;
70 | }
71 | int numNeightbours = settings->value("numneighbours").toInt();
72 | float inWeight = settings->value("weight").toFloat();
73 |
74 | memset(destimage, 0, size.width() * size.height() * sizeof(TexturePixel));
75 |
76 | if (!sourceimages.contains(0)) {
77 | return;
78 | }
79 | TexturePixel* sourceImage = sourceimages.value(0).data()->getData();
80 |
81 | int pixels_on_row = 1 + (numNeightbours * 2);
82 |
83 | float* gaussian_kernel = ComputeGaussianKernel(numNeightbours, inWeight);
84 |
85 | for (int y = 0; y < size.height(); y++) {
86 | int row = y * size.width();
87 | for (int x = 0; x < size.width(); x++) {
88 | TexturePixel blurred_value(0, 0, 0, 0);
89 | for (int xoffset = 0; xoffset < pixels_on_row; xoffset++) {
90 | int sx = x - numNeightbours + xoffset;
91 | if (sx < 0) {
92 | sx = 0;
93 | } else if (sx > size.width() - 1){
94 | sx = size.width() - 1;
95 | }
96 | // Calculate newly blurred value
97 | int pixelPos = row + sx;
98 | blurred_value.r += gaussian_kernel[xoffset] * sourceImage[pixelPos].r;
99 | blurred_value.g += gaussian_kernel[xoffset] * sourceImage[pixelPos].g;
100 | blurred_value.b += gaussian_kernel[xoffset] * sourceImage[pixelPos].b;
101 | blurred_value.a += gaussian_kernel[xoffset] * sourceImage[pixelPos].a;
102 | }
103 | // Set our calculated value to our temp map
104 | destimage[y * size.width() + x] = blurred_value;
105 | }
106 | }
107 | for(int y = 0; y < size.height(); y++) {
108 | for(int x = 0; x < size.width(); x++) {
109 | TexturePixel blurred_value(0, 0, 0, 0);
110 | for (int yoffset = 0; yoffset < pixels_on_row; yoffset++) {
111 | int sy = y - numNeightbours + yoffset;
112 | if (sy < 0) {
113 | sy = 0;
114 | } else if (sy > size.height() - 1){
115 | sy = size.height() - 1;
116 | }
117 | int pixelPos = sy * size.width() + x;
118 | // Calculate blurred value
119 | blurred_value.r += gaussian_kernel[yoffset] * destimage[pixelPos].r;
120 | blurred_value.g += gaussian_kernel[yoffset] * destimage[pixelPos].g;
121 | blurred_value.b += gaussian_kernel[yoffset] * destimage[pixelPos].b;
122 | blurred_value.a += gaussian_kernel[yoffset] * destimage[pixelPos].a;
123 | }
124 |
125 | // Set the original height map value to our computed value
126 | // This is the actual blurred value (previously scaled)
127 | destimage[y * size.width() + x] = blurred_value;
128 | }
129 | }
130 | delete[] gaussian_kernel;
131 | }
132 |
--------------------------------------------------------------------------------
/generators/gaussianblur.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Part of the ProceduralTextureMaker project.
3 | * http://github.com/johanokl/ProceduralTextureMaker
4 | * Released under GPLv3.
5 | * Johan Lindqvist (johan.lindqvist@gmail.com)
6 | */
7 |
8 | #ifndef GAUSSIANBLURTEXTUREGENERATOR_H
9 | #define GAUSSIANBLURTEXTUREGENERATOR_H
10 |
11 | #include "texturegenerator.h"
12 |
13 | /**
14 | * @brief The GaussianBlurTextureGenerator class
15 | */
16 | class GaussianBlurTextureGenerator : public TextureGenerator
17 | {
18 | public:
19 | GaussianBlurTextureGenerator();
20 | ~GaussianBlurTextureGenerator() override = default;
21 | void generate(QSize size,
22 | TexturePixel* destimage,
23 | QMap sourceimages,
24 | TextureNodeSettings* settings) const override;
25 | int getNumSourceSlots() const override { return 1; }
26 | QString getName() const override { return QString("Gaussian blur"); }
27 | const TextureGeneratorSettings& getSettings() const override { return configurables; }
28 | QString getDescription() const override { return QString("Blurs the source image."); }
29 | TextureGenerator::Type getType() const override { return TextureGenerator::Type::Filter; }
30 |
31 | private:
32 | TextureGeneratorSettings configurables;
33 | float* ComputeGaussianKernel(const int inRadius, const float inWeight) const;
34 | };
35 |
36 | #endif // GAUSSIANBLURTEXTUREGENERATOR_H
37 |
--------------------------------------------------------------------------------
/generators/glow.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Part of the ProceduralTextureMaker project.
3 | * http://github.com/johanokl/ProceduralTextureMaker
4 | * Released under GPLv3.
5 | * Johan Lindqvist (johan.lindqvist@gmail.com)
6 | */
7 |
8 | #ifndef GLOWTEXTUREGENERATOR_H
9 | #define GLOWTEXTUREGENERATOR_H
10 |
11 | #include "texturegenerator.h"
12 |
13 | /**
14 | * @brief The GlowTextureGenerator class
15 | */
16 | class GlowTextureGenerator : public TextureGenerator
17 | {
18 | public:
19 | GlowTextureGenerator();
20 | ~GlowTextureGenerator() override = default;
21 | void generate(QSize size,
22 | TexturePixel* destimage,
23 | QMap sourceimages,
24 | TextureNodeSettings* settings) const override;
25 | int getNumSourceSlots() const override { return 1; }
26 | QString getName() const override { return QString("Glow"); }
27 | const TextureGeneratorSettings& getSettings() const override { return configurables; }
28 | QString getDescription() const override { return QString("Adds a glow around the object."); }
29 | TextureGenerator::Type getType() const override { return TextureGenerator::Type::Filter; }
30 |
31 | private:
32 | TextureGeneratorSettings configurables;
33 | };
34 |
35 | #endif // GLOWTEXTUREGENERATOR_H
36 |
--------------------------------------------------------------------------------
/generators/gradient.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Part of the ProceduralTextureMaker project.
3 | * http://github.com/johanokl/ProceduralTextureMaker
4 | * Released under GPLv3.
5 | * Johan Lindqvist (johan.lindqvist@gmail.com)
6 | */
7 |
8 | #ifndef GRADIENTTEXTUREGENERATOR_H
9 | #define GRADIENTTEXTUREGENERATOR_H
10 |
11 | #include "texturegenerator.h"
12 |
13 | /**
14 | * @brief The GradientTextureGenerator class
15 | */
16 | class GradientTextureGenerator : public TextureGenerator
17 | {
18 | public:
19 | GradientTextureGenerator();
20 | ~GradientTextureGenerator() override = default;
21 | void generate(QSize size,
22 | TexturePixel* destimage,
23 | QMap sourceimages,
24 | TextureNodeSettings* settings) const override;
25 | int getNumSourceSlots() const override { return 1; }
26 | QString getName() const override { return QString("Gradient"); }
27 | const TextureGeneratorSettings& getSettings() const override { return configurables; }
28 | QString getDescription() const override { return QString("Draws a filled Gradient."); }
29 | TextureGenerator::Type getType() const override { return TextureGenerator::Type::Generator; }
30 |
31 | private:
32 | TextureGeneratorSettings configurables;
33 | };
34 |
35 | #endif // GRADIENTTEXTUREGENERATOR_H
36 |
--------------------------------------------------------------------------------
/generators/greyscale.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Part of the ProceduralTextureMaker project.
3 | * http://github.com/johanokl/ProceduralTextureMaker
4 | * Released under GPLv3.
5 | * Johan Lindqvist (johan.lindqvist@gmail.com)
6 | */
7 |
8 | #include "greyscale.h"
9 |
10 | void GreyscaleTextureGenerator::generate(QSize size,
11 | TexturePixel* destimage,
12 | QMap sourceimages,
13 | TextureNodeSettings* settings) const
14 | {
15 | Q_UNUSED(settings);
16 |
17 | if (!destimage || !size.isValid()) {
18 | return;
19 | }
20 | if (!sourceimages.contains(0)) {
21 | memset(destimage, 0, size.width() * size.height() * sizeof(TexturePixel));
22 | return;
23 | }
24 | TexturePixel* sourceImage = sourceimages.value(0).data()->getData();
25 |
26 | for (int j = 0; j < size.height(); j++) {
27 | for (int i = 0; i < size.width(); i++) {
28 | int pixelpos = j * size.width() + i;
29 | TexturePixel sourcePixel = sourceImage[pixelpos];
30 | auto color = static_cast(sourcePixel.intensity() * 255);
31 | destimage[pixelpos].r = color;
32 | destimage[pixelpos].g = color;
33 | destimage[pixelpos].b = color;
34 | destimage[pixelpos].a = sourcePixel.a;
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/generators/greyscale.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Part of the ProceduralTextureMaker project.
3 | * http://github.com/johanokl/ProceduralTextureMaker
4 | * Released under GPLv3.
5 | * Johan Lindqvist (johan.lindqvist@gmail.com)
6 | */
7 |
8 | #ifndef GREYSCALETEXTUREGENERATOR_H
9 | #define GREYSCALETEXTUREGENERATOR_H
10 |
11 | #include "texturegenerator.h"
12 |
13 | /**
14 | * @brief The GreyscaleTextureGenerator class
15 | */
16 | class GreyscaleTextureGenerator : public TextureGenerator
17 | {
18 | public:
19 | GreyscaleTextureGenerator() = default;
20 | ~GreyscaleTextureGenerator() override = default;
21 | void generate(QSize size,
22 | TexturePixel* destimage,
23 | QMap sourceimages,
24 | TextureNodeSettings* settings) const override;
25 | int getNumSourceSlots() const override { return 1; }
26 | QString getName() const override { return QString("Greyscale"); }
27 | const TextureGeneratorSettings& getSettings() const override { return configurables; }
28 | QString getDescription() const override { return QString("Blurs the source image."); }
29 | TextureGenerator::Type getType() const override { return TextureGenerator::Type::Filter; }
30 |
31 | private:
32 | TextureGeneratorSettings configurables;
33 | };
34 |
35 | #endif // GREYSCALETEXTUREGENERATOR_H
36 |
--------------------------------------------------------------------------------
/generators/invert.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Part of the ProceduralTextureMaker project.
3 | * http://github.com/johanokl/ProceduralTextureMaker
4 | * Released under GPLv3.
5 | * Johan Lindqvist (johan.lindqvist@gmail.com)
6 | */
7 |
8 | #include "invert.h"
9 |
10 | InvertTextureGenerator::InvertTextureGenerator()
11 | {
12 | QStringList options;
13 | options.append("Yes");
14 | options.append("No");
15 |
16 | TextureGeneratorSetting channelRed;
17 | channelRed.name = "Invert red";
18 | channelRed.order = 0;
19 | channelRed.defaultindex = 0;
20 | channelRed.defaultvalue = QVariant(options);
21 | configurables.insert("channelRed", channelRed);
22 |
23 | TextureGeneratorSetting channelGreen;
24 | channelGreen.name = "Invert green";
25 | channelGreen.order = 1;
26 | channelGreen.defaultindex = 0;
27 | channelGreen.defaultvalue = QVariant(options);
28 | configurables.insert("channelGreen", channelGreen);
29 |
30 | TextureGeneratorSetting channelBlue;
31 | channelBlue.name = "Invert blue";
32 | channelBlue.order = 2;
33 | channelBlue.defaultindex = 0;
34 | channelBlue.defaultvalue = QVariant(options);
35 | configurables.insert("channelBlue", channelBlue);
36 |
37 | TextureGeneratorSetting channelAlpha;
38 | channelAlpha.name = "Invert alpha";
39 | channelAlpha.order = 3;
40 | channelAlpha.defaultindex = 1;
41 | channelAlpha.defaultvalue = QVariant(options);
42 | configurables.insert("channelAlpha", channelAlpha);
43 | }
44 |
45 | void InvertTextureGenerator::generate(QSize size, TexturePixel* destimage,
46 | QMap sourceimages,
47 | TextureNodeSettings* settings) const
48 | {
49 | if (!settings || !destimage || !size.isValid()) {
50 | return;
51 | }
52 | auto channelRedStr = settings->value("channelRed").toString();
53 | auto channelGreenStr = settings->value("channelGreen").toString();
54 | auto channelBlueStr = settings->value("channelBlue").toString();
55 | auto channelAlphaStr = settings->value("channelAlpha").toString();
56 | int numPixels = size.width() * size.height();
57 | TexturePixel* source = nullptr;
58 | if (sourceimages.contains(0)) {
59 | source = sourceimages.value(0).data()->getData();
60 | }
61 | if (!source) {
62 | memset(destimage, 0, numPixels * sizeof(TexturePixel));
63 | return;
64 | }
65 | memcpy(destimage, source, numPixels * sizeof(TexturePixel));
66 |
67 | bool channelRedInvert = false;
68 | bool channelGreenInvert = false;
69 | bool channelBlueInvert = false;
70 | bool channelAlphaInvert = false;
71 | if (channelRedStr == "Yes") {
72 | channelRedInvert = true;
73 | }
74 | if (channelGreenStr == "Yes") {
75 | channelGreenInvert = true;
76 | }
77 | if (channelBlueStr == "Yes") {
78 | channelBlueInvert = true;
79 | }
80 | if (channelAlphaStr == "Yes") {
81 | channelAlphaInvert = true;
82 | }
83 | for (int thisPos = 0; thisPos < numPixels; thisPos++) {
84 | if (channelRedInvert) {
85 | destimage[thisPos].r = 255 - destimage[thisPos].r;
86 | }
87 | if (channelGreenInvert) {
88 | destimage[thisPos].g = 255 - destimage[thisPos].g;
89 | }
90 | if (channelBlueInvert) {
91 | destimage[thisPos].b = 255 - destimage[thisPos].b;
92 | }
93 | if (channelAlphaInvert) {
94 | destimage[thisPos].a = 255 - destimage[thisPos].a;
95 | }
96 | }
97 | }
98 |
--------------------------------------------------------------------------------
/generators/invert.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Part of the ProceduralTextureMaker project.
3 | * http://github.com/johanokl/ProceduralTextureMaker
4 | * Released under GPLv3.
5 | * Johan Lindqvist (johan.lindqvist@gmail.com)
6 | */
7 |
8 | #ifndef INVERTTEXTUREGENERATOR_H
9 | #define INVERTTEXTUREGENERATOR_H
10 |
11 | #include "texturegenerator.h"
12 |
13 | /**
14 | * @brief The InvertTextureGenerator class
15 | */
16 | class InvertTextureGenerator : public TextureGenerator
17 | {
18 | public:
19 | InvertTextureGenerator();
20 | ~InvertTextureGenerator() override = default;
21 | void generate(QSize size,
22 | TexturePixel* destimage,
23 | QMap sourceimages,
24 | TextureNodeSettings* settings) const override;
25 | int getNumSourceSlots() const override { return 1; }
26 | QString getName() const override { return QString("Invert"); }
27 | const TextureGeneratorSettings& getSettings() const override { return configurables; }
28 | QString getDescription() const override { return QString("Inverts the colors."); }
29 | TextureGenerator::Type getType() const override { return TextureGenerator::Type::Filter; }
30 |
31 | private:
32 | TextureGeneratorSettings configurables;
33 | };
34 |
35 | #endif // INVERTTEXTUREGENERATOR_H
36 |
--------------------------------------------------------------------------------
/generators/javascript.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Part of the ProceduralTextureMaker project.
3 | * http://github.com/johanokl/ProceduralTextureMaker
4 | * Released under GPLv3.
5 | * Johan Lindqvist (johan.lindqvist@gmail.com)
6 | */
7 |
8 | #ifndef JSTEXGENMANAGER_H
9 | #define JSTEXGENMANAGER_H
10 |
11 | #include "texturegenerator.h"
12 | #include
13 | #include
14 |
15 | class GeneratorFileFinder;
16 | class JsTexGen;
17 | class TextureProject;
18 |
19 | /**
20 | * @brief The JSTexGenManager class
21 | */
22 | class JSTexGenManager : public QObject
23 | {
24 | Q_OBJECT
25 |
26 | public:
27 | explicit JSTexGenManager(TextureProject* project);
28 | ~JSTexGenManager() override;
29 |
30 | public slots:
31 | void setDirectory(const QString& path, bool forceScan=false);
32 | void addGenerator(JsTexGen* generator);
33 | void setEnabled(bool);
34 | void settingsUpdated();
35 |
36 | signals:
37 | void generatorAdded(TextureGeneratorPtr);
38 | void generatorRemoved(TextureGeneratorPtr);
39 | void scanDirectory(QString);
40 |
41 | private:
42 | QString directoryPath;
43 | GeneratorFileFinder* filefinder;
44 | QThread* filefinderthread;
45 | TextureProject* project;
46 | bool enabled;
47 | bool hasScannedDirectory;
48 | };
49 |
50 | /**
51 | * @brief The JsTexGen class
52 | */
53 | class JsTexGen : public TextureGenerator
54 | {
55 | public:
56 | explicit JsTexGen(const QString& jsContent);
57 | ~JsTexGen() override = default;
58 | void generate(QSize size, TexturePixel* destimage,
59 | QMap sourceimages,
60 | TextureNodeSettings* settings) const override;
61 |
62 | int getNumSourceSlots() const override { return numSlots; }
63 | QString getName() const override { return name; }
64 | const TextureGeneratorSettings& getSettings() const override { return configurables; }
65 | QString getDescription() const override { return description; }
66 | TextureGenerator::Type getType() const override { return TextureGenerator::Type::Generator; }
67 | bool isValid();
68 |
69 | private:
70 | TextureGeneratorSettings configurables;
71 | QString name;
72 | QString description;
73 | QString scriptContent;
74 | mutable QReadWriteLock mutex;
75 | int numSlots;
76 | bool valid;
77 | bool separateColorChannels;
78 | };
79 |
80 | /**
81 | * @brief The GeneratorFileFinder class
82 | */
83 | class GeneratorFileFinder : public QObject
84 | {
85 | Q_OBJECT
86 | public slots:
87 | void abort();
88 | void scanDirectory(QString basepath);
89 | signals:
90 | void scanFinished();
91 | void generatorFound(JsTexGen* filename);
92 | private:
93 | bool aborted;
94 | };
95 |
96 | #endif // JSTEXGENMANAGER_H
97 |
--------------------------------------------------------------------------------
/generators/lens.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Part of the ProceduralTextureMaker project.
3 | * http://github.com/johanokl/ProceduralTextureMaker
4 | * Released under GPLv3.
5 | * Johan Lindqvist (johan.lindqvist@gmail.com)
6 | */
7 |
8 | #include "lens.h"
9 | #include
10 | #include
11 |
12 | LensTextureGenerator::LensTextureGenerator()
13 | {
14 | TextureGeneratorSetting offsetleft;
15 | offsetleft.defaultvalue = QVariant((int) 0);
16 | offsetleft.name = "Offset left";
17 | offsetleft.min = QVariant(-100);
18 | offsetleft.max = QVariant(100);
19 | offsetleft.order = 0;
20 | configurables.insert("offsetleft", offsetleft);
21 |
22 | TextureGeneratorSetting offsettop;
23 | offsettop.defaultvalue = QVariant((int) 0);
24 | offsettop.name = "Offset top";
25 | offsettop.min = QVariant(-100);
26 | offsettop.max = QVariant(100);
27 | offsettop.order = 1;
28 | configurables.insert("offsettop", offsettop);
29 |
30 | TextureGeneratorSetting size;
31 | size.defaultvalue = QVariant((double) 50);
32 | size.name = "Size";
33 | size.min = QVariant(0);
34 | size.max = QVariant(300);
35 | size.order = 2;
36 | configurables.insert("size", size);
37 |
38 | TextureGeneratorSetting strength;
39 | strength.defaultvalue = QVariant((double) 200);
40 | strength.name = "Strength";
41 | strength.min = QVariant(0);
42 | strength.max = QVariant(300);
43 | strength.order = 3;
44 | configurables.insert("strength", strength);
45 | }
46 |
47 |
48 | void LensTextureGenerator::generate(QSize size,
49 | TexturePixel* destimage,
50 | QMap sourceimages,
51 | TextureNodeSettings* settings) const
52 | {
53 | if (!settings || !destimage || !size.isValid()) {
54 | return;
55 | }
56 | int offsetleft = settings->value("offsetleft").toDouble() * size.width() / 100;
57 | int offsettop = settings->value("offsettop").toDouble() * size.height() / 100;
58 | int lenssize = settings->value("size").toDouble() * size.height() / 100;
59 | double strength = (300 - settings->value("strength").toDouble()) * size.width() / 100;
60 | if (!sourceimages.contains(0)) {
61 | memset(destimage, 0, size.width() * size.height() * sizeof(TexturePixel));
62 | return;
63 | }
64 | TexturePixel* sourceimage = sourceimages.value(0).data()->getData();
65 |
66 | memcpy(destimage, sourceimage, size.width() * size.height() * sizeof(TexturePixel));
67 |
68 | if (lenssize % 2) {
69 | lenssize += 1;
70 | }
71 | QPoint* lens = new QPoint[lenssize * lenssize];
72 | int r = lenssize / 2;
73 |
74 | for (int y = 0; y < (lenssize >> 1); y++) {
75 | for (int x = 0; x < (lenssize >> 1); x++) {
76 | int ix = 0;
77 | int iy = 0;
78 | if ((x * x + y * y) < (r * r)) {
79 | double shift = (double) strength /
80 | sqrt(strength * strength - (x * x + y * y - r * r));
81 | ix = x * shift - x;
82 | iy = y * shift - y;
83 | }
84 | lens[lenssize * (lenssize / 2 - y) + lenssize / 2 - x] = QPoint(-ix, -iy);
85 | lens[lenssize * (lenssize / 2 + y) + lenssize / 2 + x] = QPoint(ix, iy);
86 | lens[lenssize * (lenssize / 2 + y) + lenssize / 2 - x] = QPoint(-ix, iy);
87 | lens[lenssize * (lenssize / 2 - y) + lenssize / 2 + x] = QPoint(ix, -iy);
88 | }
89 | }
90 | for (int y = 0; y < lenssize; y++) {
91 | int ypos = y + size.height() / 2 + offsettop - lenssize / 2;
92 | for (int x = 0; x < lenssize; x++) {
93 | int xpos = x + size.width() / 2 + offsetleft - lenssize / 2;
94 | int destpos = ypos * size.width() + xpos;
95 | if (xpos >= 0 && xpos < size.width() && ypos >= 0 && ypos < size.height()) {
96 | int sourcex = xpos + lens[y * lenssize + x].x();
97 | if (sourcex < 0) {
98 | sourcex += size.width();
99 | } else {
100 | sourcex = sourcex % size.width();
101 | }
102 | int sourcey = ypos + lens[y * lenssize + x].y();
103 | if (sourcey < 0) {
104 | sourcey += size.height();
105 | } else {
106 | sourcey = sourcey % size.height();
107 | }
108 | destimage[destpos] = sourceimage[sourcey * size.width() + sourcex];
109 | }
110 | }
111 | }
112 | delete[] lens;
113 | }
114 |
--------------------------------------------------------------------------------
/generators/lens.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Part of the ProceduralTextureMaker project.
3 | * http://github.com/johanokl/ProceduralTextureMaker
4 | * Released under GPLv3.
5 | * Johan Lindqvist (johan.lindqvist@gmail.com)
6 | */
7 |
8 | #ifndef LENSTEXTUREGENERATOR_H
9 | #define LENSTEXTUREGENERATOR_H
10 |
11 | #include "texturegenerator.h"
12 |
13 | /**
14 | * @brief The LensTextureGenerator class
15 | */
16 | class LensTextureGenerator : public TextureGenerator
17 | {
18 | public:
19 | LensTextureGenerator();
20 | ~LensTextureGenerator() override = default;
21 | void generate(QSize size,
22 | TexturePixel* destimage,
23 | QMap sourceimages,
24 | TextureNodeSettings* settings) const override;
25 | int getNumSourceSlots() const override { return 1; }
26 | QString getName() const override { return QString("Lens"); }
27 | const TextureGeneratorSettings& getSettings() const override { return configurables; }
28 | QString getDescription() const override { return QString("Applies a lens effect."); }
29 | TextureGenerator::Type getType() const override { return TextureGenerator::Type::Filter; }
30 |
31 | private:
32 | TextureGeneratorSettings configurables;
33 | };
34 |
35 | #endif // LENSTEXTUREGENERATOR_H
36 |
--------------------------------------------------------------------------------
/generators/lines.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Part of the ProceduralTextureMaker project.
3 | * http://github.com/johanokl/ProceduralTextureMaker
4 | * Released under GPLv3.
5 | * Johan Lindqvist (johan.lindqvist@gmail.com)
6 | */
7 |
8 | #include "lines.h"
9 | #include
10 | #include
11 | #include
12 |
13 |
14 | LinesTextureGenerator::LinesTextureGenerator()
15 | {
16 | TextureGeneratorSetting color;
17 | color.name = "Line color";
18 | color.defaultvalue = QVariant(QColor(255, 100, 50, 255));
19 | color.order = 1;
20 | configurables.insert("color", color);
21 |
22 | TextureGeneratorSetting lineheight;
23 | lineheight.name = "Line width";
24 | lineheight.defaultvalue = QVariant((int) 10);
25 | lineheight.min = QVariant(0);
26 | lineheight.max = QVariant(100);
27 | lineheight.order = 2;
28 | configurables.insert("lineheight", lineheight);
29 |
30 | TextureGeneratorSetting spacing;
31 | spacing.name = "Spacing";
32 | spacing.defaultvalue = QVariant((int) 10);
33 | spacing.min = QVariant(0);
34 | spacing.max = QVariant(100);
35 | spacing.order = 3;
36 | configurables.insert("spacing", spacing);
37 |
38 | TextureGeneratorSetting offset;
39 | offset.name = "Offset";
40 | offset.defaultvalue = QVariant((int) 0);
41 | offset.min = QVariant(-100);
42 | offset.max = QVariant(0);
43 | offset.order = 4;
44 | configurables.insert("offset", offset);
45 |
46 | TextureGeneratorSetting angle;
47 | angle.name = "Angle";
48 | angle.defaultvalue = QVariant((double) 0);
49 | angle.min = QVariant(0);
50 | angle.max = QVariant(180);
51 | angle.order = 5;
52 | configurables.insert("angle", angle);
53 | }
54 |
55 |
56 | void LinesTextureGenerator::generate(QSize size,
57 | TexturePixel* destimage,
58 | QMap sourceimages,
59 | TextureNodeSettings* settings) const
60 | {
61 | if (!settings || !destimage || !size.isValid()) {
62 | return;
63 | }
64 | QColor color = settings->value("color").value();
65 | int spacing = settings->value("spacing").toDouble() * size.height() / 100;
66 | int lineheight = settings->value("lineheight").toDouble() * size.height() / 100;
67 | int offset = settings->value("offset").toDouble() * size.height() / 100;
68 | double angle = settings->value("angle").toDouble();
69 |
70 | if (sourceimages.contains(0)) {
71 | memcpy(destimage, sourceimages.value(0)->getData(), size.width() * size.height() * sizeof(TexturePixel));
72 | } else {
73 | memset(destimage, 0, size.width() * size.height() * sizeof(TexturePixel));
74 | }
75 |
76 | TexturePixel filler(color.red(), color.green(), color.blue(), 255);
77 | bool invert = false;
78 | if (angle > 90) {
79 | invert = true;
80 | angle = 180 - angle;
81 | }
82 | angle = (angle / 180.0) * ((double) M_PI);
83 | double x1 = 0;
84 | double y1 = -10000;
85 | double x1rot = (x1 * cos(angle)) - (y1 * sin(angle));
86 | double y1rot = (y1 * cos(angle)) + (x1 * sin(angle));
87 | x1 = x1rot;
88 | y1 = y1rot;
89 | double x2 = -x1;
90 | double y2 = -y1;
91 | for (int y = 0; y < size.height(); y++) {
92 | for (int x = 0; x < size.width(); x++) {
93 | double x3 = x;
94 | double y3 = y;
95 | double x4 = -10000;
96 | double y4 = y;
97 | double x4rot = ((x4 - x3) * cos(angle)) - ((y4 - y3) * sin(angle)) + x3;
98 | double y4rot = ((y4 - y3) * cos(angle)) + ((x4 - x3) * sin(angle)) + y3;
99 | x4 = x4rot;
100 | y4 = y4rot;
101 | double intersection_x = ((x2 * y1 - x1 * y2) * (x4 - x) - (x4 * y - x * y4) * (x2 - x1)) /
102 | ((x2 - x1) * (y4 - y) - (x4 - x) * (y2 - y1));
103 | double intersection_y = ((x2 * y1 - x1 * y2) * (y4 - y) - (x4 * y - x * y4) * (y2 - y1)) /
104 | ((x2 - x1) * (y4 - y) - (x4 - x) * (y2 - y1));
105 | int distance = sqrt((x - intersection_x) * (x - intersection_x) + (y - intersection_y) * (y - intersection_y));
106 | if (((distance - offset) % (lineheight + spacing)) > spacing) {
107 | if (invert) {
108 | destimage[y * size.width() + size.width() - x - 1] = filler;
109 | } else {
110 | destimage[y * size.width() + x] = filler;
111 | }
112 | }
113 | }
114 | }
115 | }
116 |
--------------------------------------------------------------------------------
/generators/lines.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Part of the ProceduralTextureMaker project.
3 | * http://github.com/johanokl/ProceduralTextureMaker
4 | * Released under GPLv3.
5 | * Johan Lindqvist (johan.lindqvist@gmail.com)
6 | */
7 |
8 | #ifndef LINESTEXTUREGENERATOR_H
9 | #define LINESTEXTUREGENERATOR_H
10 |
11 | #include "texturegenerator.h"
12 |
13 | /**
14 | * @brief The LinesTextureGenerator class
15 | */
16 | class LinesTextureGenerator : public TextureGenerator
17 | {
18 | public:
19 | LinesTextureGenerator();
20 | ~LinesTextureGenerator() override = default;
21 | void generate(QSize size,
22 | TexturePixel* destimage,
23 | QMap sourceimages,
24 | TextureNodeSettings* settings) const override;
25 | int getNumSourceSlots() const override { return 1; }
26 | QString getName() const override { return QString("Lines"); }
27 | const TextureGeneratorSettings& getSettings() const override { return configurables; }
28 | QString getDescription() const override { return QString("Draws filled lines."); }
29 | TextureGenerator::Type getType() const override { return TextureGenerator::Type::Generator; }
30 |
31 | private:
32 | TextureGeneratorSettings configurables;
33 | };
34 |
35 | #endif // LINESTEXTUREGENERATOR_H
36 |
--------------------------------------------------------------------------------
/generators/merge.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Part of the ProceduralTextureMaker project.
3 | * http://github.com/johanokl/ProceduralTextureMaker
4 | * Released under GPLv3.
5 | * Johan Lindqvist (johan.lindqvist@gmail.com)
6 | */
7 |
8 | #include "merge.h"
9 |
10 | void MergeTextureGenerator::generate(QSize size, TexturePixel* destimage,
11 | QMap sourceimages,
12 | TextureNodeSettings* settings) const
13 | {
14 | Q_UNUSED(settings);
15 | if (!destimage || !size.isValid()) {
16 | return;
17 | }
18 | int numPixels = size.width() * size.height();
19 | memset(destimage, 0, numPixels * sizeof(TexturePixel));
20 | QMapIterator sourceIterator(sourceimages);
21 | while (sourceIterator.hasNext()) {
22 | sourceIterator.next();
23 | TexturePixel* newSource = sourceIterator.value().data()->getData();
24 | for (int i = 0; i < numPixels; i++) {
25 | destimage[i] += newSource[i];
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/generators/merge.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Part of the ProceduralTextureMaker project.
3 | * http://github.com/johanokl/ProceduralTextureMaker
4 | * Released under GPLv3.
5 | * Johan Lindqvist (johan.lindqvist@gmail.com)
6 | */
7 |
8 | #ifndef MERGETEXTUREGENERATOR_H
9 | #define MERGETEXTUREGENERATOR_H
10 |
11 | #include "texturegenerator.h"
12 |
13 | /**
14 | * @brief The MergeTextureGenerator class
15 | */
16 | class MergeTextureGenerator : public TextureGenerator
17 | {
18 | public:
19 | MergeTextureGenerator() = default;
20 | ~MergeTextureGenerator() override = default;
21 | void generate(QSize size,
22 | TexturePixel* destimage,
23 | QMap sourceimages,
24 | TextureNodeSettings* settings) const override;
25 | int getNumSourceSlots() const override { return 10; }
26 | QString getName() const override { return QString("Merge"); }
27 | const TextureGeneratorSettings& getSettings() const override { return configurables; }
28 | QString getDescription() const override { return QString("Merge multiple textures."); }
29 | TextureGenerator::Type getType() const override { return TextureGenerator::Type::Combiner; }
30 |
31 | private:
32 | TextureGeneratorSettings configurables;
33 | };
34 |
35 | #endif // MERGETEXTUREGENERATOR_H
36 |
37 |
38 |
--------------------------------------------------------------------------------
/generators/mirror.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Part of the ProceduralTextureMaker project.
3 | * http://github.com/johanokl/ProceduralTextureMaker
4 | * Released under GPLv3.
5 | * Johan Lindqvist (johan.lindqvist@gmail.com)
6 | */
7 |
8 | #include "mirror.h"
9 |
10 | MirrorTextureGenerator::MirrorTextureGenerator()
11 | {
12 | QStringList directions;
13 | directions.append("Flip horizentally");
14 | directions.append("Flip vertically");
15 | directions.append("Mirror horizentally");
16 | directions.append("Mirror vertically");
17 | TextureGeneratorSetting direction;
18 | direction.name = "Direction";
19 | direction.description = "Which way?";
20 | direction.defaultvalue = QVariant(directions);
21 | configurables.insert("direction", direction);
22 | }
23 |
24 |
25 | void MirrorTextureGenerator::generate(QSize size,
26 | TexturePixel* destimage,
27 | QMap sourceimages,
28 | TextureNodeSettings* settings) const
29 | {
30 | if (!settings || !destimage || !size.isValid()) {
31 | return;
32 | }
33 | QString direction = settings->value("direction").toString();
34 |
35 | if (!sourceimages.contains(0)) {
36 | memset(destimage, 255, size.width() * size.height() * sizeof(TexturePixel));
37 | return;
38 | }
39 | TexturePixel* sourceImage = sourceimages.value(0)->getData();
40 |
41 | if (direction == "Flip horizentally" || direction == "Flip vertically") {
42 | for (int y = 0; y < size.height(); y++) {
43 | bool horizontal = (direction == "Flip horizentally") ? true : false;
44 | int destrowstart = y * size.width();
45 | if (horizontal) {
46 | for (int x = 0; x < size.width(); x++) {
47 | int sourcepos = destrowstart + size.width() - x;
48 | destimage[destrowstart + x] = sourceImage[sourcepos];
49 | }
50 | } else {
51 | int sourcerowstart = (size.height() - y - 1) * size.width();
52 | for (int x = 0; x < size.width(); x++) {
53 | destimage[destrowstart + x] = sourceImage[sourcerowstart + x];
54 | }
55 | }
56 | }
57 | } else if (size.width() % 2 == 0) {
58 | if (direction == "Mirror horizentally") {
59 | for (int y = 0; y < size.height(); y++) {
60 | int destrowstart = y * size.width();
61 | for (int x = 0; x < size.width(); x+=2) {
62 | TexturePixel color;
63 | color.r = (int) (sourceImage[destrowstart + x].r + sourceImage[destrowstart + x + 1].r) / 2;
64 | color.g = (int) (sourceImage[destrowstart + x].g + sourceImage[destrowstart + x + 1].g) / 2;
65 | color.b = (int) (sourceImage[destrowstart + x].b + sourceImage[destrowstart + x + 1].b) / 2;
66 | color.a = (int) (sourceImage[destrowstart + x].a + sourceImage[destrowstart + x + 1].a) / 2;
67 | destimage[destrowstart + x / 2] = color;
68 | destimage[destrowstart + size.width() - 1 - x / 2] = color;
69 | }
70 | }
71 | } else if (direction == "Mirror vertically") {
72 | int height = size.height();
73 | int width = size.width();
74 | for (int x = 0; x < size.width(); x++) {
75 | for (int y = 0; y < size.height(); y+=2) {
76 | TexturePixel color;
77 | color.r = (int) (sourceImage[y * width + x].r + sourceImage[(y + 1) * width + x].r) / 2;
78 | color.g = (int) (sourceImage[y * width + x].g + sourceImage[(y + 1) * width + x].g) / 2;
79 | color.b = (int) (sourceImage[y * width + x].b + sourceImage[(y + 1) * width + x].b) / 2;
80 | color.a = (int) (sourceImage[y * width + x].a + sourceImage[(y + 1) * width + x].a) / 2;
81 | destimage[y * width / 2 + x] = color;
82 | destimage[(height - 1 - y / 2) * width + x] = color;
83 | }
84 | }
85 | }
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/generators/mirror.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Part of the ProceduralTextureMaker project.
3 | * http://github.com/johanokl/ProceduralTextureMaker
4 | * Released under GPLv3.
5 | * Johan Lindqvist (johan.lindqvist@gmail.com)
6 | */
7 |
8 | #ifndef MIRRORTEXTUREGENERATOR_H
9 | #define MIRRORTEXTUREGENERATOR_H
10 |
11 | #include "texturegenerator.h"
12 |
13 | /**
14 | * @brief The MirrorTextureGenerator class
15 | */
16 | class MirrorTextureGenerator : public TextureGenerator
17 | {
18 | public:
19 | MirrorTextureGenerator();
20 | ~MirrorTextureGenerator() override = default;
21 | void generate(QSize size,
22 | TexturePixel* destimage,
23 | QMap sourceimages,
24 | TextureNodeSettings* settings) const override;
25 | int getNumSourceSlots() const override { return 1; }
26 | QString getName() const override { return QString("Mirror"); }
27 | const TextureGeneratorSettings& getSettings() const override { return configurables; }
28 | QString getDescription() const override { return QString("Blurs the source image."); }
29 | TextureGenerator::Type getType() const override { return TextureGenerator::Type::Filter; }
30 |
31 | private:
32 | TextureGeneratorSettings configurables;
33 | };
34 |
35 |
36 | #endif // MIRRORTEXTUREGENERATOR_H
37 |
--------------------------------------------------------------------------------
/generators/modifylevels.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Part of the ProceduralTextureMaker project.
3 | * http://github.com/johanokl/ProceduralTextureMaker
4 | * Released under GPLv3.
5 | * Johan Lindqvist (johan.lindqvist@gmail.com)
6 | */
7 |
8 | #include "modifylevels.h"
9 |
10 | ModifyLevelsTextureGenerator::ModifyLevelsTextureGenerator()
11 | {
12 | TextureGeneratorSetting channel;
13 | channel.name = "Channels";
14 | QStringList channels;
15 | channels.append("All channels");
16 | channels.append("All colors, not alpha");
17 | channels.append("Only red");
18 | channels.append("Only green");
19 | channels.append("Only blue");
20 | channels.append("Only alpha");
21 | channel.description = "";
22 | channel.order = 0;
23 | channel.defaultindex = 1;
24 | channel.defaultvalue = QVariant(channels);
25 | configurables.insert("channel", channel);
26 |
27 | TextureGeneratorSetting mode;
28 | mode.name = "Mode";
29 | QStringList modes;
30 | modes.append("Multiply");
31 | modes.append("Add");
32 | mode.defaultvalue = QVariant(modes);
33 | mode.order = 1;
34 | configurables.insert("mode", mode);
35 |
36 | TextureGeneratorSetting blendingAlpha;
37 | blendingAlpha.name = "Amount";
38 | blendingAlpha.defaultvalue = QVariant((double) 100);
39 | blendingAlpha.min = -500;
40 | blendingAlpha.max = 500;
41 | blendingAlpha.order = 2;
42 | configurables.insert("level", blendingAlpha);
43 | }
44 |
45 |
46 | void ModifyLevelsTextureGenerator::generate(QSize size, TexturePixel* destimage,
47 | QMap sourceimages,
48 | TextureNodeSettings* settings) const
49 | {
50 | if (!settings || !destimage || !size.isValid()) {
51 | return;
52 | }
53 | int numpixels = size.width() * size.height();
54 | if (!sourceimages.contains(0)) {
55 | memset(destimage, 0, numpixels * sizeof(TexturePixel));
56 | return;
57 | }
58 | memcpy(destimage, sourceimages.value(0)->getData(), numpixels * sizeof(TexturePixel));
59 |
60 | QString mode = settings->value("mode").toString();
61 | QString channel = settings->value("channel").toString();
62 | double levelFactor = settings->value("level").toDouble() / 100;
63 | int levelAbsolute = qMin(settings->value("level").toInt(), 255);
64 |
65 | bool r = false, g = false, b = false, a = false;
66 | if (channel == "All channels") {
67 | r = g = b = a = true;
68 | } else if (channel == "All colors, not alpha") {
69 | r = g = b = true;
70 | } else if (channel == "Only red") {
71 | r = true;
72 | } else if (channel == "Only green") {
73 | g = true;
74 | } else if (channel == "Only blue") {
75 | b = true;
76 | } else if (channel == "Only alpha") {
77 | a = true;
78 | }
79 |
80 | if (mode == "Add") {
81 | for (int i = 0; i < numpixels; i++) {
82 | if (r) {
83 | destimage[i].r = qMax(qMin(levelAbsolute + destimage[i].r, 255), 0);
84 | }
85 | if (g) {
86 | destimage[i].g = qMax(qMin(levelAbsolute + destimage[i].g, 255), 0);
87 | }
88 | if (b) {
89 | destimage[i].b = qMax(qMin(levelAbsolute + destimage[i].b, 255), 0);
90 | }
91 | if (a) {
92 | destimage[i].a = qMax(qMin(levelAbsolute + destimage[i].a, 255), 0);
93 | }
94 | }
95 | } else if (mode == "Multiply") {
96 | for (int i = 0; i < numpixels; i++) {
97 | if (r) {
98 | destimage[i].r = qMax(qMin((int) (levelFactor * destimage[i].r), 255), 0);
99 | }
100 | if (g) {
101 | destimage[i].g = qMax(qMin((int) (levelFactor * destimage[i].g), 255), 0);
102 | }
103 | if (b) {
104 | destimage[i].b = qMax(qMin((int) (levelFactor * destimage[i].b), 255), 0);
105 | }
106 | if (a) {
107 | destimage[i].a = qMax(qMin((int) (levelFactor * destimage[i].a), 255), 0);
108 | }
109 | }
110 | }
111 | }
112 |
113 |
114 |
--------------------------------------------------------------------------------
/generators/modifylevels.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Part of the ProceduralTextureMaker project.
3 | * http://github.com/johanokl/ProceduralTextureMaker
4 | * Released under GPLv3.
5 | * Johan Lindqvist (johan.lindqvist@gmail.com)
6 | */
7 |
8 | #ifndef MODIFYLEVELSTEXTUREGENERATOR_H
9 | #define MODIFYLEVELSTEXTUREGENERATOR_H
10 |
11 | #include "texturegenerator.h"
12 |
13 | /**
14 | * @brief The ModifyLevelsTextureGenerator class
15 | */
16 | class ModifyLevelsTextureGenerator : public TextureGenerator
17 | {
18 | public:
19 | ModifyLevelsTextureGenerator();
20 | ~ModifyLevelsTextureGenerator() override = default;
21 | void generate(QSize size,
22 | TexturePixel* destimage,
23 | QMap sourceimages,
24 | TextureNodeSettings* settings) const override;
25 | int getNumSourceSlots() const override { return 1; }
26 | QString getName() const override { return QString("Modify levels"); }
27 | const TextureGeneratorSettings& getSettings() const override { return configurables; }
28 | QString getDescription() const override { return QString("Modifies the different."); }
29 | TextureGenerator::Type getType() const override { return TextureGenerator::Type::Filter; }
30 |
31 | private:
32 | TextureGeneratorSettings configurables;
33 | };
34 |
35 | #endif // MODIFYLEVELSTEXTUREGENERATOR_H
36 |
--------------------------------------------------------------------------------
/generators/noise.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Part of the ProceduralTextureMaker project.
3 | * http://github.com/johanokl/ProceduralTextureMaker
4 | * Released under GPLv3.
5 | * Johan Lindqvist (johan.lindqvist@gmail.com)
6 | */
7 |
8 | #ifndef NOISETEXTUREGENERATOR_H
9 | #define NOISETEXTUREGENERATOR_H
10 |
11 | #include "texturegenerator.h"
12 |
13 | /**
14 | * @brief The NoiseTextureGenerator class
15 | */
16 | class NoiseTextureGenerator : public TextureGenerator
17 | {
18 | public:
19 | NoiseTextureGenerator();
20 | ~NoiseTextureGenerator() override = default;
21 | void generate(QSize size,
22 | TexturePixel* destimage,
23 | QMap sourceimages,
24 | TextureNodeSettings* settings) const override;
25 | int getNumSourceSlots() const override { return 1; }
26 | QString getName() const override { return QString("Noise"); }
27 | const TextureGeneratorSettings& getSettings() const override { return configurables; }
28 | QString getDescription() const override { return QString("Pure noise."); }
29 | TextureGenerator::Type getType() const override { return TextureGenerator::Type::Generator; }
30 |
31 | private:
32 | TextureGeneratorSettings configurables;
33 | };
34 |
35 | #endif // NOISETEXTUREGENERATOR_H
36 |
--------------------------------------------------------------------------------
/generators/normalmap.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Part of the ProceduralTextureMaker project.
3 | * http://github.com/johanokl/ProceduralTextureMaker
4 | * Released under GPLv3.
5 | * Johan Lindqvist (johan.lindqvist@gmail.com)
6 | */
7 |
8 | #include "normalmap.h"
9 | #include
10 |
11 | void NormalMapTextureGenerator::generate(QSize size,
12 | TexturePixel* destimage,
13 | QMap sourceimages,
14 | TextureNodeSettings* settings) const
15 | {
16 | if (!settings || !destimage || !size.isValid()) {
17 | return;
18 | }
19 |
20 | memset(destimage, 0, size.width() * size.height() * sizeof(TexturePixel));
21 |
22 | if (!sourceimages.contains(0)) {
23 | return;
24 | }
25 | TexturePixel* sourceImage = sourceimages.value(0)->getData();
26 |
27 | for (int y = 1; y < size.height() - 1; y++) {
28 | for (int x = 1; x < size.width() - 1; x++) {
29 | int pixelpos = y * size.width() + x;
30 | double topleft = sourceImage[(y - 1) * size.width() + x - 1].intensity();
31 | double topmiddle = sourceImage[(y - 1) * size.width() + x].intensity();
32 | double topright = sourceImage[(y - 1) * size.width() + x + 1].intensity();
33 | double middleleft = sourceImage[y * size.width() + x - 1].intensity();
34 | double middleright = sourceImage[y * size.width() + x + 1].intensity();
35 | double lowerleft = sourceImage[(y + 1) * size.width() + x - 1].intensity();
36 | double lowermiddle = sourceImage[(y + 1) * size.width() + x].intensity();
37 | double lowerright = sourceImage[(y + 1) * size.width() + x + 1].intensity();
38 |
39 | double pStrength = 2;
40 |
41 | const double dX = (topright + 2.0 * middleright + lowerright) - (topleft + 2.0 * middleleft + lowerleft);
42 | const double dY = (lowerleft + 2.0 * lowermiddle + lowerright) - (topleft + 2.0 * topmiddle + topright);
43 | const double dZ = 1.0 / pStrength;
44 |
45 | QVector3D vect(dX, dY, dZ);
46 | vect.normalize();
47 |
48 | destimage[pixelpos].r = (vect.x() + 1.0) * 127.5;
49 | destimage[pixelpos].g = (vect.y() + 1.0) * 127.5;
50 | destimage[pixelpos].b = (vect.z() + 1.0) * 127.5;
51 | }
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/generators/normalmap.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Part of the ProceduralTextureMaker project.
3 | * http://github.com/johanokl/ProceduralTextureMaker
4 | * Released under GPLv3.
5 | * Johan Lindqvist (johan.lindqvist@gmail.com)
6 | */
7 |
8 | #ifndef NORMALMAPTEXTUREGENERATOR_H
9 | #define NORMALMAPTEXTUREGENERATOR_H
10 |
11 | #include "texturegenerator.h"
12 |
13 | /**
14 | * @brief The NormalMapTextureGenerator class
15 | */
16 | class NormalMapTextureGenerator : public TextureGenerator
17 | {
18 | public:
19 | NormalMapTextureGenerator() = default;
20 | ~NormalMapTextureGenerator() override = default;
21 | void generate(QSize size,
22 | TexturePixel* destimage,
23 | QMap sourceimages,
24 | TextureNodeSettings* settings) const override;
25 | int getNumSourceSlots() const override { return 1; }
26 | QString getName() const override { return QString("Normal-map"); }
27 | const TextureGeneratorSettings& getSettings() const override { return configurables; }
28 | QString getDescription() const override { return QString("Blurs the source image."); }
29 | TextureGenerator::Type getType() const override { return TextureGenerator::Type::Filter; }
30 |
31 | private:
32 | TextureGeneratorSettings configurables;
33 | };
34 |
35 |
36 | #endif // NORMALMAPTEXTUREGENERATOR_H
37 |
--------------------------------------------------------------------------------
/generators/perlinnoise.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Part of the ProceduralTextureMaker project.
3 | * http://github.com/johanokl/ProceduralTextureMaker
4 | * Released under GPLv3.
5 | * Johan Lindqvist (johan.lindqvist@gmail.com)
6 | */
7 |
8 | #include "perlinnoise.h"
9 | #include
10 | #include
11 | #include
12 |
13 | PerlinNoiseTextureGenerator::PerlinNoiseTextureGenerator()
14 | {
15 | TextureGeneratorSetting colorsetting;
16 | colorsetting.defaultvalue = QVariant(QColor(255, 255, 255));
17 | colorsetting.name = "Color";
18 | colorsetting.description = "Color of the circle";
19 | colorsetting.order = 1;
20 | configurables.insert("color", colorsetting);
21 |
22 | TextureGeneratorSetting numOctaves;
23 | numOctaves.defaultvalue = QVariant((int) 5);
24 | numOctaves.name = "Octaves";
25 | numOctaves.description = "Number of octaves";
26 | numOctaves.order = 2;
27 | configurables.insert("numoctaves", numOctaves);
28 |
29 | TextureGeneratorSetting persistence;
30 | persistence.defaultvalue = QVariant((double) 0.5);
31 | persistence.name = "Persistence";
32 | persistence.description = "This controls the roughness of the picture,";
33 | persistence.order = 3;
34 | configurables.insert("persistence", persistence);
35 |
36 | TextureGeneratorSetting zoom;
37 | zoom.defaultvalue = QVariant((double) 75);
38 | zoom.min = QVariant(10);
39 | zoom.max = QVariant(200);
40 | zoom.name = "Zoom";
41 | zoom.order = 4;
42 | configurables.insert("zoom", zoom);
43 |
44 | TextureGeneratorSetting randomizer;
45 | randomizer.defaultvalue = QVariant((double) 500);
46 | randomizer.min = QVariant(0);
47 | randomizer.max = QVariant(1000);
48 | randomizer.name = "Random seed";
49 | randomizer.order = 5;
50 | configurables.insert("randomizer", randomizer);
51 | }
52 |
53 |
54 | double PerlinNoiseTextureGenerator::findnoise2(double x, double y) const
55 | {
56 | int n = (int) x + (int) y * 57;
57 | n = (n << 13) ^ n;
58 | int nn = (n * (n * n * 60493 + 19990303) + 1376312589)& 0x7fffffff;
59 | return 1.0 - ((double) nn / 1073741824.0);
60 | }
61 |
62 |
63 | double PerlinNoiseTextureGenerator::noise(double x, double y) const
64 | {
65 | double s = findnoise2((int) x, (int) y);
66 | double t = findnoise2((int) x + 1, (int) y);
67 | double u = findnoise2((int) x, (int) y + 1);
68 | double v = findnoise2((int) x + 1, (int) y + 1);
69 | double int1 = interpolate(s, t, x - (int) x);
70 | double int2 = interpolate(u, v, x - (int) x);
71 | return interpolate(int1, int2, y - (int) y);
72 | }
73 |
74 |
75 | double PerlinNoiseTextureGenerator::interpolate(double a, double b, double x) const
76 | {
77 | double f = (1.0 - cos(x * 3.1415927)) * 0.5;
78 | return a * (1.0 - f) + b * f;
79 | }
80 |
81 |
82 | void PerlinNoiseTextureGenerator::generate(QSize size, TexturePixel* destimage,
83 | QMap sourceimages,
84 | TextureNodeSettings* settings) const
85 | {
86 | if (!settings || !destimage || !size.isValid()) {
87 | return;
88 | }
89 |
90 |
91 | QColor color = settings->value("color").value();
92 | int numOctaves = settings->value("numoctaves").toInt();
93 | double persistence = settings->value("persistence").toDouble();
94 | double zoom = settings->value("zoom").toDouble();
95 | double randomizer = settings->value("randomizer").toDouble() * 1000;
96 | double xFactor = (double) 500 / size.width();
97 | double yFactor = (double) 500 / size.height();
98 | bool blend = false;
99 | TexturePixel* sourceImg = nullptr;
100 | if (sourceimages.contains(0)) {
101 | sourceImg = sourceimages.value(0)->getData();
102 | blend = true;
103 | }
104 | for (int y = 0; y < size.height(); y++) {
105 | for (int x = 0; x < size.width(); x++) {
106 | double getnoise = 0;
107 | int thisPos = y * size.width() + x;
108 |
109 | for (int currOctave = 0; currOctave < numOctaves - 1; currOctave++) {
110 | double frequency = pow(2, currOctave); //This increases the frequency with every loop of the octave.
111 | double amplitude = pow(persistence, currOctave);//This decreases the amplitude with every loop of the octave.
112 | getnoise += noise(randomizer + static_cast(x) * xFactor * frequency / zoom,
113 | randomizer + static_cast(y) * yFactor / zoom * frequency) * amplitude;
114 | }
115 | auto pixelColor = static_cast((getnoise * 128.0) + 128.0);
116 | if (pixelColor > 255) {
117 | pixelColor = 255;
118 | }
119 | if (pixelColor < 0) {
120 | pixelColor = 0;
121 | }
122 | double fraction = (static_cast(pixelColor) / 255.0);
123 | double negVal = 1 - (static_cast(pixelColor) / 255.0);
124 |
125 | destimage[thisPos].r = qMin(qMax((int) (fraction * (float) color.red() + (blend ? (negVal * (float) sourceImg[thisPos].r) : 0)), 0), 255);
126 | destimage[thisPos].g = qMin(qMax((int) (fraction * (float) color.green() + (blend ? (negVal * (float) sourceImg[thisPos].g) : 0)), 0), 255);
127 | destimage[thisPos].b = qMin(qMax((int) (fraction * (float) color.blue() + (blend ? (negVal * (float) sourceImg[thisPos].b) : 0)), 0), 255);
128 | destimage[thisPos].a = 255;
129 | }
130 | }
131 | }
132 |
--------------------------------------------------------------------------------
/generators/perlinnoise.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Part of the ProceduralTextureMaker project.
3 | * http://github.com/johanokl/ProceduralTextureMaker
4 | * Released under GPLv3.
5 | * Johan Lindqvist (johan.lindqvist@gmail.com)
6 | */
7 |
8 | #ifndef PERLINNOISETEXTUREGENERATOR_H
9 | #define PERLINNOISETEXTUREGENERATOR_H
10 |
11 | #include "texturegenerator.h"
12 |
13 | /**
14 | * @brief The PerlinNoiseTextureGenerator class
15 | */
16 | class PerlinNoiseTextureGenerator : public TextureGenerator
17 | {
18 | public:
19 | PerlinNoiseTextureGenerator();
20 | ~PerlinNoiseTextureGenerator() override = default;
21 | void generate(QSize size,
22 | TexturePixel* destimage,
23 | QMap sourceimages,
24 | TextureNodeSettings* settings) const override;
25 | const TextureGeneratorSettings& getSettings() const override { return configurables; }
26 | int getNumSourceSlots() const override { return 1; }
27 | QString getName() const override { return "Perlin noise"; }
28 | QString getDescription() const override { return QString("Basic Perlin Noise"); }
29 | TextureGenerator::Type getType() const override { return TextureGenerator::Type::Generator; }
30 |
31 | private:
32 | double noise(double x, double y) const;
33 | double findnoise2(double x,double y) const;
34 | double interpolate(double a, double b, double x) const;
35 |
36 | TextureGeneratorSettings configurables;
37 | };
38 |
39 | #endif // PERLINNOISETEXTUREGENERATOR_H
40 |
--------------------------------------------------------------------------------
/generators/pixelate.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Part of the ProceduralTextureMaker project.
3 | * http://github.com/johanokl/ProceduralTextureMaker
4 | * Released under GPLv3.
5 | * Johan Lindqvist (johan.lindqvist@gmail.com)
6 | */
7 |
8 | #include "pixelate.h"
9 |
10 | PixelateTextureGenerator::PixelateTextureGenerator()
11 | {
12 | TextureGeneratorSetting width;
13 | width.defaultvalue = QVariant((double) 5);
14 | width.name = "Width";
15 | width.min = QVariant(0);
16 | width.max = QVariant(50);
17 | width.group = "size";
18 | width.order = 1;
19 | configurables.insert("width", width);
20 |
21 | TextureGeneratorSetting height;
22 | height.defaultvalue = QVariant((double) 5);
23 | height.name = "Height";
24 | height.min = QVariant(0);
25 | height.max = QVariant(50);
26 | height.group = "size";
27 | height.order = 2;
28 | configurables.insert("height", height);
29 |
30 | TextureGeneratorSetting offsetx;
31 | offsetx.defaultvalue = QVariant((double) 0);
32 | offsetx.name = "Offset left";
33 | offsetx.min = QVariant(-50);
34 | offsetx.max = QVariant(50);
35 | offsetx.order = 3;
36 | configurables.insert("offsetx", offsetx);
37 |
38 | TextureGeneratorSetting offsety;
39 | offsety.defaultvalue = QVariant((double) 0);
40 | offsety.name = "Offset top";
41 | offsety.min = QVariant(-50);
42 | offsety.max = QVariant(50);
43 | offsety.order = 4;
44 | configurables.insert("offsety", offsety);
45 | }
46 |
47 |
48 | void PixelateTextureGenerator::generate(QSize size,
49 | TexturePixel* destimage,
50 | QMap sourceimages,
51 | TextureNodeSettings* settings) const
52 | {
53 | if (!settings || !destimage || !size.isValid()) {
54 | return;
55 | }
56 | int width = qMax(settings->value("width").toDouble() / 100 * size.width(), (double) 1);
57 | int height = qMax(settings->value("height").toDouble() / 100 * size.height(), (double) 1);
58 | int offsetx = settings->value("offsetx").toDouble() / 100 * size.width();
59 | int offsety = settings->value("offsety").toDouble() / 100 * size.height();
60 | if (!sourceimages.contains(0)) {
61 | memset(destimage, 0, size.width() * size.height() * sizeof(TexturePixel));
62 | return;
63 | }
64 | TexturePixel* sourceImage = sourceimages.value(0).data()->getData();
65 | int y = offsety - size.height();
66 | while (y < size.height()) {
67 | if (y + height > 0) {
68 | int x = offsetx - size.width();
69 | while (x < size.width()) {
70 | if (x + width > 0) {
71 | int totalPixels = 0;
72 | quint64 red = 0;
73 | quint64 green = 0;
74 | quint64 blue = 0;
75 | quint64 alpha = 0;
76 | for (int ypos = y; ypos < y + height; ypos++) {
77 | int currY = ypos;
78 | if (currY < 0) {
79 | currY += size.height() * 5;
80 | }
81 | currY %= size.height();
82 | currY *= size.width();
83 | for (int xpos = x; xpos < x + width; xpos++) {
84 | int currX = xpos;
85 | if (currX < 0) {
86 | currX += size.width() * 5;
87 | }
88 | currX %= size.width();
89 | TexturePixel sourcePixel = sourceImage[currY + currX];
90 | totalPixels++;
91 | red += sourcePixel.r;
92 | green += sourcePixel.g;
93 | blue += sourcePixel.b;
94 | alpha += sourcePixel.a;
95 | }
96 | }
97 | if (totalPixels > 0) {
98 | TexturePixel color(red / totalPixels, green / totalPixels,
99 | blue / totalPixels, alpha / totalPixels);
100 | int stopY = qMin(y + height, size.height());
101 | for (int ypos = qMax(y, 0); ypos < stopY; ypos++) {
102 | int linestart = ypos * size.width();
103 | int stopX = qMin(x + width, size.width());
104 | for (int xpos = qMax(x, 0); xpos < stopX; xpos++) {
105 | destimage[linestart + xpos] = color;
106 | }
107 | }
108 | }
109 | }
110 | x += width;
111 | }
112 | }
113 | y += height;
114 | }
115 | }
116 |
--------------------------------------------------------------------------------
/generators/pixelate.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Part of the ProceduralTextureMaker project.
3 | * http://github.com/johanokl/ProceduralTextureMaker
4 | * Released under GPLv3.
5 | * Johan Lindqvist (johan.lindqvist@gmail.com)
6 | */
7 |
8 | #ifndef PIXELATETEXTUREGENERATOR_H
9 | #define PIXELATETEXTUREGENERATOR_H
10 |
11 | #include "texturegenerator.h"
12 |
13 | /**
14 | * @brief The PixelateTextureGenerator class
15 | */
16 | class PixelateTextureGenerator : public TextureGenerator
17 | {
18 | public:
19 | PixelateTextureGenerator();
20 | ~PixelateTextureGenerator() override = default;
21 | void generate(QSize size,
22 | TexturePixel* destimage,
23 | QMap sourceimages,
24 | TextureNodeSettings* settings) const override;
25 | int getNumSourceSlots() const override { return 1; }
26 | QString getName() const override { return QString("Pixelate"); }
27 | const TextureGeneratorSettings& getSettings() const override { return configurables; }
28 | QString getDescription() const override { return QString("Pixelates the source image."); }
29 | TextureGenerator::Type getType() const override { return TextureGenerator::Type::Filter; }
30 |
31 | private:
32 | TextureGeneratorSettings configurables;
33 | };
34 |
35 | #endif // PIXELATETEXTUREGENERATOR_H
36 |
--------------------------------------------------------------------------------
/generators/pointillism.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Part of the ProceduralTextureMaker project.
3 | * http://github.com/johanokl/ProceduralTextureMaker
4 | * Released under GPLv3.
5 | * Johan Lindqvist (johan.lindqvist@gmail.com)
6 | */
7 |
8 |
9 | #include "pointillism.h"
10 | #include
11 | #include
12 | #if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
13 | #include
14 | #endif
15 | #include
16 |
17 | PointillismTextureGenerator::PointillismTextureGenerator()
18 | {
19 | TextureGeneratorSetting points;
20 | points.defaultvalue = QVariant((int) 10000);
21 | points.name = "Points";
22 | points.min = QVariant(0);
23 | points.max = QVariant(250 * 1000);
24 | points.order = 1;
25 | configurables.insert("points", points);
26 |
27 | TextureGeneratorSetting width;
28 | width.defaultvalue = QVariant((double) 1);
29 | width.name = "Width";
30 | width.min = QVariant(0.2);
31 | width.max = QVariant(50);
32 | width.order = 2;
33 | width.group = "size";
34 | configurables.insert("width", width);
35 |
36 | TextureGeneratorSetting height;
37 | height.defaultvalue = QVariant((double) 1);
38 | height.name = "Height";
39 | height.min = QVariant(0.2);
40 | height.max = QVariant(50);
41 | height.order = 3;
42 | height.group = "size";
43 | configurables.insert("height", height);
44 |
45 | TextureGeneratorSetting includesource;
46 | includesource.defaultvalue = QVariant((bool) true);
47 | includesource.name = "Include source";
48 | includesource.order = 4;
49 | configurables.insert("includesource", includesource);
50 |
51 | TextureGeneratorSetting antialiasing;
52 | antialiasing.defaultvalue = QVariant((bool) true);
53 | antialiasing.name = "Antialiasing";
54 | antialiasing.order = 5;
55 | configurables.insert("antialiasing", antialiasing);
56 |
57 | TextureGeneratorSetting randseed;
58 | randseed.defaultvalue = QVariant((int) 500);
59 | randseed.name = "Random seed";
60 | randseed.min = QVariant(0);
61 | randseed.max = QVariant(1000);
62 | randseed.order = 6;
63 | configurables.insert("randseed", randseed);
64 | }
65 |
66 |
67 | void PointillismTextureGenerator::generate(QSize size,
68 | TexturePixel* destimage,
69 | QMap sourceimages,
70 | TextureNodeSettings* settings) const
71 | {
72 | if (!settings || !destimage || !size.isValid()) {
73 | return;
74 | }
75 | double shapeWidth = settings->value("width").toDouble() * size.width() / 100;
76 | double shapeHeight = settings->value("height").toDouble() * size.height() / 100;
77 | int randseed = settings->value("randseed").toInt();
78 | int points = settings->value("points").toInt();
79 | bool includesource = settings->value("includesource").toBool();
80 | bool antialiasing = settings->value("antialiasing").toBool();
81 |
82 | if (!sourceimages.contains(0)) {
83 | memset(destimage, 0, size.width() * size.height() * sizeof(TexturePixel));
84 | return;
85 | }
86 |
87 | #if QT_VERSION < QT_VERSION_CHECK(5, 10, 0)
88 | srand(randseed);
89 | #else
90 | QRandomGenerator random(randseed);
91 | #endif
92 |
93 | TexturePixel* sourceImage = sourceimages.value(0)->getData();
94 | if (includesource) {
95 | memcpy(destimage, sourceimages.value(0)->getData(), size.width() * size.height() * sizeof(TexturePixel));
96 | } else {
97 | memset(destimage, 0, size.width() * size.height() * sizeof(TexturePixel));
98 | }
99 |
100 | QImage tempimage = QImage(size.width(), size.height(), QImage::Format_RGB32);
101 | memcpy(tempimage.bits(), destimage, size.width() * size.height() * sizeof(TexturePixel));
102 |
103 | QPainter painter(&tempimage);
104 | painter.setPen(Qt::NoPen);
105 | painter.setRenderHint(QPainter::Antialiasing, antialiasing);
106 | painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
107 |
108 | for (int i = 0; i < points; i++) {
109 | #if QT_VERSION < QT_VERSION_CHECK(5, 10, 0)
110 | int x = qrand() % size.width();
111 | int y = qrand() % size.height();
112 | #else
113 | int x = random.bounded(0, size.width());
114 | int y = random.bounded(0, size.height());
115 | #endif
116 | TexturePixel sourcePixel = sourceImage[y * size.width() + x];
117 | QColor sourceColor(sourcePixel.r, sourcePixel.g, sourcePixel.b, sourcePixel.a);
118 | painter.setBrush(QBrush(sourceColor, Qt::BrushStyle::SolidPattern));
119 | painter.drawEllipse(QPointF(x, y), shapeWidth, shapeHeight);
120 | }
121 | memcpy(destimage, tempimage.bits(), size.width() * size.height() * sizeof(TexturePixel));
122 | }
123 |
--------------------------------------------------------------------------------
/generators/pointillism.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Part of the ProceduralTextureMaker project.
3 | * http://github.com/johanokl/ProceduralTextureMaker
4 | * Released under GPLv3.
5 | * Johan Lindqvist (johan.lindqvist@gmail.com)
6 | */
7 |
8 | #ifndef POINTILLISMTEXTUREGENERATOR_H
9 | #define POINTILLISMTEXTUREGENERATOR_H
10 |
11 | #include "texturegenerator.h"
12 |
13 | /**
14 | * @brief The PointillismTextureGenerator class
15 | */
16 | class PointillismTextureGenerator : public TextureGenerator
17 | {
18 | public:
19 | PointillismTextureGenerator();
20 | ~PointillismTextureGenerator() override = default;
21 | void generate(QSize size,
22 | TexturePixel* destimage,
23 | QMap sourceimages,
24 | TextureNodeSettings* settings) const override;
25 | int getNumSourceSlots() const override { return 1; }
26 | QString getName() const override { return QString("Pointillism"); }
27 | const TextureGeneratorSettings& getSettings() const override { return configurables; }
28 | QString getDescription() const override { return QString(""); }
29 | TextureGenerator::Type getType() const override { return TextureGenerator::Type::Filter; }
30 |
31 | private:
32 | TextureGeneratorSettings configurables;
33 | };
34 |
35 | #endif // POINTILLISMTEXTUREGENERATOR_H
36 |
--------------------------------------------------------------------------------
/generators/setchannels.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Part of the ProceduralTextureMaker project.
3 | * http://github.com/johanokl/ProceduralTextureMaker
4 | * Released under GPLv3.
5 | * Johan Lindqvist (johan.lindqvist@gmail.com)
6 | */
7 |
8 | #ifndef SETCHANNELSTEXTUREGENERATOR_H
9 | #define SETCHANNELSTEXTUREGENERATOR_H
10 |
11 | #include "texturegenerator.h"
12 |
13 | /**
14 | * @brief The SetChannelsTextureGenerator class
15 | */
16 | class SetChannelsTextureGenerator : public TextureGenerator
17 | {
18 | public:
19 | enum Channels {
20 | none = 1,
21 | fill = 2,
22 | node1red = 3,
23 | node1green = 4,
24 | node1blue = 5,
25 | node1alpha = 6,
26 | node2red = 7,
27 | node2green = 8,
28 | node2blue = 9,
29 | node2alpha = 10
30 | };
31 |
32 | SetChannelsTextureGenerator();
33 | ~SetChannelsTextureGenerator() override = default;
34 | void generate(QSize size,
35 | TexturePixel* destimage,
36 | QMap sourceimages,
37 | TextureNodeSettings* settings) const override;
38 | int getNumSourceSlots() const override { return 2; }
39 | QString getName() const override { return QString("Set channels"); }
40 | const TextureGeneratorSettings& getSettings() const override { return configurables; }
41 | QString getDescription() const override { return QString(""); }
42 | TextureGenerator::Type getType() const override { return TextureGenerator::Type::Combiner; }
43 |
44 | private:
45 | TextureGeneratorSettings configurables;
46 | Channels getChannelFromName(const QString& name) const;
47 | quint8 getColorFromChannel(const TexturePixel& firstColor, const TexturePixel& secondColor,
48 | Channels channel) const;
49 | };
50 |
51 | #endif // SETCHANNELSTEXTUREGENERATOR_H
52 |
53 |
54 |
--------------------------------------------------------------------------------
/generators/shadow.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Part of the ProceduralTextureMaker project.
3 | * http://github.com/johanokl/ProceduralTextureMaker
4 | * Released under GPLv3.
5 | * Johan Lindqvist (johan.lindqvist@gmail.com)
6 | */
7 |
8 | #ifndef SHADOWTEXTUREGENERATOR_H
9 | #define SHADOWTEXTUREGENERATOR_H
10 |
11 | #include "texturegenerator.h"
12 |
13 | /**
14 | * @brief The ShadowTextureGenerator class
15 | */
16 | class ShadowTextureGenerator : public TextureGenerator
17 | {
18 | public:
19 | ShadowTextureGenerator();
20 | ~ShadowTextureGenerator() override = default;
21 | void generate(QSize size,
22 | TexturePixel* destimage,
23 | QMap sourceimages,
24 | TextureNodeSettings* settings) const override;
25 | int getNumSourceSlots() const override { return 1; }
26 | QString getName() const override { return QString("Shadow"); }
27 | const TextureGeneratorSettings& getSettings() const override { return configurables; }
28 | QString getDescription() const override { return QString("Adds a shadow under the object."); }
29 | TextureGenerator::Type getType() const override { return TextureGenerator::Type::Filter; }
30 |
31 | private:
32 | TextureGeneratorSettings configurables;
33 | };
34 |
35 | #endif // SHADOWTEXTUREGENERATOR_H
36 |
--------------------------------------------------------------------------------
/generators/sineplasma.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Part of the ProceduralTextureMaker project.
3 | * http://github.com/johanokl/ProceduralTextureMaker
4 | * Released under GPLv3.
5 | * Johan Lindqvist (johan.lindqvist@gmail.com)
6 | */
7 |
8 | #include "sineplasma.h"
9 | #include
10 | #include
11 | #include
12 |
13 | SinePlasmaTextureGenerator::SinePlasmaTextureGenerator()
14 | {
15 | TextureGeneratorSetting colorsetting;
16 | colorsetting.defaultvalue = QVariant(QColor(255, 0, 0));
17 | colorsetting.name = "Color";
18 | colorsetting.description = "Color of the circle";
19 | colorsetting.order = 1;
20 | configurables.insert("color", colorsetting);
21 |
22 | TextureGeneratorSetting xoffset;
23 | xoffset.defaultvalue = QVariant((double) 10);
24 | xoffset.name = "Offset left";
25 | xoffset.description = "Offset along the x axis";
26 | xoffset.min = QVariant(-100);
27 | xoffset.max = QVariant(100);
28 | xoffset.order = 2;
29 | configurables.insert("xoffset", xoffset);
30 |
31 | TextureGeneratorSetting yoffset;
32 | yoffset.defaultvalue = QVariant((double) 10);
33 | yoffset.name = "Offset top";
34 | yoffset.description = "Offset along the y axis";
35 | yoffset.min = QVariant(-100);
36 | yoffset.max = QVariant(100);
37 | yoffset.order = 3;
38 | configurables.insert("yoffset", yoffset);
39 |
40 | TextureGeneratorSetting xfrequency;
41 | xfrequency.defaultvalue = QVariant((double) 10);
42 | xfrequency.name = "Frequency X axis";
43 | xfrequency.description = "How often it repeats along the y axis";
44 | xfrequency.min = QVariant(0);
45 | xfrequency.max = QVariant(100);
46 | xfrequency.group = "frequencies";
47 | xfrequency.order = 4;
48 | configurables.insert("xfrequency", xfrequency);
49 |
50 | TextureGeneratorSetting yfrequency;
51 | yfrequency.defaultvalue = QVariant((double) 10);
52 | yfrequency.name = "Frequency Y axis";
53 | yfrequency.description = "How often it repeats along the y axis";
54 | yfrequency.min = QVariant(0);
55 | yfrequency.max = QVariant(100);
56 | yfrequency.group = "frequencies";
57 | yfrequency.order = 5;
58 | configurables.insert("yfrequency", yfrequency);
59 | }
60 |
61 |
62 | void SinePlasmaTextureGenerator::generate(QSize size,
63 | TexturePixel* destimage,
64 | QMap sourceimages,
65 | TextureNodeSettings* settings) const
66 | {
67 | if (!settings || !destimage || !size.isValid()) {
68 | return;
69 | }
70 | QColor color = settings->value("color").value();
71 | double xoffset = settings->value("xoffset").toInt() * size.width() / 100;
72 | double yoffset = settings->value("yoffset").toInt() * size.height() / 100;
73 | double xfrequency = settings->value("xfrequency").toDouble() * 5 / size.width();
74 | double yfrequency = settings->value("yfrequency").toDouble() * 5 / size.height();
75 |
76 | if (sourceimages.contains(0)) {
77 | memcpy(destimage, sourceimages.value(0)->getData(), size.width() * size.height() * sizeof(TexturePixel));
78 | } else {
79 | memset(destimage, 0, size.width() * size.height() * sizeof(TexturePixel));
80 | }
81 |
82 | for (int y = 0; y < size.height(); y++) {
83 | for (int x = 0; x < size.width(); x++) {
84 | double value = 0.5 + 0.25 * qSin((x - xoffset) * xfrequency) + 0.25 * qSin((y - yoffset) * yfrequency);
85 | double negVal = 1 - value;
86 | int pixelPos = y * size.width() + x;
87 | destimage[pixelPos].r = qMin(qMax((int) (value * (double) color.red() +
88 | negVal * (double) destimage[pixelPos].r), 0), 255);
89 | destimage[pixelPos].g = qMin(qMax((int) (value * (double) color.green() +
90 | negVal * (double) destimage[pixelPos].g), 0), 255);
91 | destimage[pixelPos].b = qMin(qMax((int) (value * (double) color.blue() +
92 | negVal * (double) destimage[pixelPos].b), 0), 255);
93 | destimage[pixelPos].a = qMin(qMax((int) (value * (double) color.alpha() +
94 | negVal * (double) destimage[pixelPos].a), (int) destimage[pixelPos].a), 255);
95 | }
96 | }
97 | }
98 |
--------------------------------------------------------------------------------
/generators/sineplasma.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Part of the ProceduralTextureMaker project.
3 | * http://github.com/johanokl/ProceduralTextureMaker
4 | * Released under GPLv3.
5 | * Johan Lindqvist (johan.lindqvist@gmail.com)
6 | */
7 |
8 | #ifndef SINEPLASMATEXTUREGENERATOR_H
9 | #define SINEPLASMATEXTUREGENERATOR_H
10 |
11 | #include "texturegenerator.h"
12 |
13 | /**
14 | * @brief The SinePlasmaTextureGenerator class
15 | */
16 | class SinePlasmaTextureGenerator : public TextureGenerator
17 | {
18 | public:
19 | SinePlasmaTextureGenerator();
20 | ~SinePlasmaTextureGenerator() override = default;
21 | void generate(QSize size,
22 | TexturePixel* destimage,
23 | QMap sourceimages,
24 | TextureNodeSettings* settings) const override;
25 | int getNumSourceSlots() const override { return 1; }
26 | QString getName() const override { return QString("Sine plasma"); }
27 | const TextureGeneratorSettings& getSettings() const override { return configurables; }
28 | QString getDescription() const override { return QString("Repeating sine plasma."); }
29 | TextureGenerator::Type getType() const override { return TextureGenerator::Type::Generator; }
30 |
31 | private:
32 | TextureGeneratorSettings configurables;
33 | };
34 |
35 | #endif // SINEPLASMATEXTUREGENERATOR_H
36 |
--------------------------------------------------------------------------------
/generators/sinetransform.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Part of the ProceduralTextureMaker project.
3 | * http://github.com/johanokl/ProceduralTextureMaker
4 | * Released under GPLv3.
5 | * Johan Lindqvist (johan.lindqvist@gmail.com)
6 | */
7 |
8 | #ifndef SINETRANSFORMTEXTUREGENERATOR_H
9 | #define SINETRANSFORMTEXTUREGENERATOR_H
10 |
11 | #include "texturegenerator.h"
12 |
13 | /**
14 | * @brief The SineTransformTextureGenerator class
15 | */
16 | class SineTransformTextureGenerator : public TextureGenerator
17 | {
18 | public:
19 | SineTransformTextureGenerator();
20 | ~SineTransformTextureGenerator() override = default;
21 | void generate(QSize size,
22 | TexturePixel* destimage,
23 | QMap sourceimages,
24 | TextureNodeSettings* settings) const override;
25 | int getNumSourceSlots() const override { return 1; }
26 | QString getName() const override { return QString("Sine transform"); }
27 | const TextureGeneratorSettings& getSettings() const override { return configurables; }
28 | QString getDescription() const override { return QString("Stretches the texture along a sinus wave."); }
29 | TextureGenerator::Type getType() const override { return TextureGenerator::Type::Filter; }
30 |
31 | private:
32 | TextureGeneratorSettings configurables;
33 | };
34 |
35 | #endif // SINETRANSFORMTEXTUREGENERATOR_H
36 |
--------------------------------------------------------------------------------
/generators/square.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Part of the ProceduralTextureMaker project.
3 | * http://github.com/johanokl/ProceduralTextureMaker
4 | * Released under GPLv3.
5 | * Johan Lindqvist (johan.lindqvist@gmail.com)
6 | */
7 |
8 | #ifndef SQUARETEXTUREGENERATOR_H
9 | #define SQUARETEXTUREGENERATOR_H
10 |
11 | #include "texturegenerator.h"
12 |
13 | /**
14 | * @brief The SquareTextureGenerator class
15 | */
16 | class SquareTextureGenerator : public TextureGenerator
17 | {
18 | public:
19 | SquareTextureGenerator();
20 | ~SquareTextureGenerator() override = default;
21 | void generate(QSize size,
22 | TexturePixel* destimage,
23 | QMap sourceimages,
24 | TextureNodeSettings* settings) const override;
25 | int getNumSourceSlots() const override { return 1; }
26 | QString getName() const override { return QString("Square"); }
27 | const TextureGeneratorSettings& getSettings() const override { return configurables; }
28 | QString getDescription() const override { return QString("Draws a square."); }
29 | TextureGenerator::Type getType() const override { return TextureGenerator::Type::Generator; }
30 |
31 | private:
32 | TextureGeneratorSettings configurables;
33 | };
34 |
35 | #endif // SQUARETEXTUREGENERATOR_H
36 |
--------------------------------------------------------------------------------
/generators/stackblur.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Part of the ProceduralTextureMaker project.
3 | * http://github.com/johanokl/ProceduralTextureMaker
4 | * Released under GPLv3.
5 | * Johan Lindqvist (johan.lindqvist@gmail.com)
6 | */
7 |
8 | #ifndef STACKBLURTEXTUREGENERATOR_H
9 | #define STACKBLURTEXTUREGENERATOR_H
10 |
11 | #include "texturegenerator.h"
12 |
13 | /**
14 | * @brief The StackBlurTextureGenerator class
15 | */
16 | class StackBlurTextureGenerator : public TextureGenerator
17 | {
18 | public:
19 | StackBlurTextureGenerator();
20 | ~StackBlurTextureGenerator() override = default;
21 | void generate(QSize size,
22 | TexturePixel* destimage,
23 | QMap sourceimages,
24 | TextureNodeSettings* settings) const override;
25 | int getNumSourceSlots() const override { return 1; }
26 | QString getName() const override { return QString("Stack Blur"); }
27 | const TextureGeneratorSettings& getSettings() const override { return configurables; }
28 | QString getDescription() const override { return QString("Blurs the source image."); }
29 | TextureGenerator::Type getType() const override { return TextureGenerator::Type::Filter; }
30 |
31 | private:
32 | TextureGeneratorSettings configurables;
33 | };
34 |
35 | #endif // STACKBLURTEXTUREGENERATOR_H
36 |
--------------------------------------------------------------------------------
/generators/star.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Part of the ProceduralTextureMaker project.
3 | * http://github.com/johanokl/ProceduralTextureMaker
4 | * Released under GPLv3.
5 | * Johan Lindqvist (johan.lindqvist@gmail.com)
6 | */
7 | #ifndef STARTEXTUREGENERATOR_H
8 | #define STARTEXTUREGENERATOR_H
9 |
10 | #include "texturegenerator.h"
11 |
12 | /**
13 | * @brief The StarTextureGenerator class
14 | */
15 | class StarTextureGenerator : public TextureGenerator
16 | {
17 | public:
18 | StarTextureGenerator();
19 | ~StarTextureGenerator() override = default;
20 | void generate(QSize size,
21 | TexturePixel* destimage,
22 | QMap sourceimages,
23 | TextureNodeSettings* settings) const override;
24 | int getNumSourceSlots() const override { return 1; }
25 | QString getName() const override { return QString("Star"); }
26 | const TextureGeneratorSettings& getSettings() const override { return configurables; }
27 | QString getDescription() const override { return QString("Draws a star."); }
28 | TextureGenerator::Type getType() const override { return TextureGenerator::Type::Generator; }
29 |
30 | private:
31 | TextureGeneratorSettings configurables;
32 | };
33 |
34 | #endif // STARTEXTUREGENERATOR_H
35 |
--------------------------------------------------------------------------------
/generators/text.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Part of the ProceduralTextureMaker project.
3 | * http://github.com/johanokl/ProceduralTextureMaker
4 | * Released under GPLv3.
5 | * Johan Lindqvist (johan.lindqvist@gmail.com)
6 | */
7 |
8 | #ifndef TEXTTEXTUREGENERATOR_H
9 | #define TEXTTEXTUREGENERATOR_H
10 |
11 | #include "texturegenerator.h"
12 |
13 | /**
14 | * @brief The TextTextureGenerator class
15 | */
16 | class TextTextureGenerator : public TextureGenerator
17 | {
18 | public:
19 | TextTextureGenerator();
20 | ~TextTextureGenerator() override = default;
21 | void generate(QSize size,
22 | TexturePixel* destimage,
23 | QMap sourceimages,
24 | TextureNodeSettings* settings) const override;
25 | int getNumSourceSlots() const override { return 1; }
26 | QString getName() const override { return QString("Text"); }
27 | const TextureGeneratorSettings& getSettings() const override { return configurables; }
28 | QString getDescription() const override { return QString("Draws a Text."); }
29 | TextureGenerator::Type getType() const override { return TextureGenerator::Type::Generator; }
30 |
31 | private:
32 | TextureGeneratorSettings configurables;
33 | };
34 |
35 | #endif // TEXTTEXTUREGENERATOR_H
36 |
--------------------------------------------------------------------------------
/generators/texturegenerator.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Part of the ProceduralTextureMaker project.
3 | * http://github.com/johanokl/ProceduralTextureMaker
4 | * Released under GPLv3.
5 | * Johan Lindqvist (johan.lindqvist@gmail.com)
6 | */
7 |
8 | #include "texturegenerator.h"
9 | #include
10 |
11 | /**
12 | * @brief TextureGenerator::getSlotName
13 | * @param id Slot id
14 | * @return The name
15 | * Default name for slots.
16 | */
17 | QString TextureGenerator::getSlotName(int id)
18 | {
19 | return QString("Slot %1").arg(id + 1);
20 | }
21 |
--------------------------------------------------------------------------------
/generators/texturegenerator.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Part of the ProceduralTextureMaker project.
3 | * http://github.com/johanokl/ProceduralTextureMaker
4 | * Released under GPLv3.
5 | * Johan Lindqvist (johan.lindqvist@gmail.com)
6 | */
7 |
8 | #ifndef TEXTUREGENERATOR_H
9 | #define TEXTUREGENERATOR_H
10 |
11 | #include "base/textureimage.h"
12 | #include "global.h"
13 | #include
14 |
15 | class TextureImage;
16 |
17 | /**
18 | * @brief The TextureGenerator class
19 | *
20 | * Pure abstract class for TextureGenerator.
21 | */
22 | class TextureGenerator
23 | {
24 | public:
25 | enum class Type { Filter, Combiner, Generator };
26 |
27 | virtual ~TextureGenerator() = default;
28 | virtual void generate(QSize size,
29 | TexturePixel* destimage,
30 | QMap sourceimages,
31 | TextureNodeSettings* settings) const = 0;
32 | virtual const TextureGeneratorSettings& getSettings() const = 0;
33 | virtual Type getType() const = 0;
34 | virtual int getNumSourceSlots() const = 0;
35 | virtual QString getName() const = 0;
36 | virtual QString getSlotName(int id);
37 | virtual QString getDescription() const = 0;
38 | };
39 |
40 | /**
41 | * @brief TextureGeneratorPtr
42 | *
43 | * Thread-safe smart pointer for TextureGenerator
44 | */
45 | typedef QSharedPointer TextureGeneratorPtr;
46 |
47 | #endif // TEXTUREGENERATOR_H
48 |
--------------------------------------------------------------------------------
/generators/transform.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Part of the ProceduralTextureMaker project.
3 | * http://github.com/johanokl/ProceduralTextureMaker
4 | * Released under GPLv3.
5 | * Johan Lindqvist (johan.lindqvist@gmail.com)
6 | */
7 |
8 | #ifndef TRANSFORMTEXTUREGENERATOR_H
9 | #define TRANSFORMTEXTUREGENERATOR_H
10 |
11 | #include "texturegenerator.h"
12 |
13 | /**
14 | * @brief The TransformTextureGenerator class
15 | */
16 | class TransformTextureGenerator : public TextureGenerator
17 | {
18 | public:
19 | TransformTextureGenerator();
20 | ~TransformTextureGenerator() override = default;
21 | void generate(QSize size,
22 | TexturePixel* destimage,
23 | QMap sourceimages,
24 | TextureNodeSettings* settings) const override;
25 | int getNumSourceSlots() const override { return 1; }
26 | QString getName() const override { return QString("Transform"); }
27 | const TextureGeneratorSettings& getSettings() const override { return configurables; }
28 | QString getDescription() const override { return QString("Resizes/translates/rotates."); }
29 | TextureGenerator::Type getType() const override { return TextureGenerator::Type::Filter; }
30 |
31 | private:
32 | TextureGeneratorSettings configurables;
33 | };
34 |
35 |
36 | #endif // TRANSFORMTEXTUREGENERATOR_H
37 |
--------------------------------------------------------------------------------
/generators/whirl.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Part of the ProceduralTextureMaker project.
3 | * http://github.com/johanokl/ProceduralTextureMaker
4 | * Released under GPLv3.
5 | * Johan Lindqvist (johan.lindqvist@gmail.com)
6 | */
7 |
8 | #include "whirl.h"
9 | #include
10 | #include
11 |
12 | WhirlTextureGenerator::WhirlTextureGenerator()
13 | {
14 | TextureGeneratorSetting radius;
15 | radius.name = "Radius";
16 | radius.defaultvalue = QVariant((double) 50);
17 | radius.min = QVariant(0);
18 | radius.max = QVariant(200);
19 | radius.order = 1;
20 | configurables.insert("radius", radius);
21 |
22 | TextureGeneratorSetting strength;
23 | strength.name = "Strength";
24 | strength.defaultvalue = QVariant((double) 40);
25 | strength.min = QVariant(-500);
26 | strength.max = QVariant(500);
27 | strength.order = 2;
28 | configurables.insert("strength", strength);
29 |
30 | TextureGeneratorSetting offsetleft;
31 | offsetleft.name = "Offset left";
32 | offsetleft.defaultvalue = QVariant((double) 0);
33 | offsetleft.min = QVariant(-100);
34 | offsetleft.max = QVariant(100);
35 | offsetleft.order = 3;
36 | configurables.insert("offsetleft", offsetleft);
37 |
38 | TextureGeneratorSetting offsettop;
39 | offsettop.name = "Offset top";
40 | offsettop.defaultvalue = QVariant((double) 0);
41 | offsettop.min = QVariant(-100);
42 | offsettop.max = QVariant(100);
43 | offsettop.order = 4;
44 | configurables.insert("offsettop", offsettop);
45 | }
46 |
47 |
48 | void WhirlTextureGenerator::generate(QSize size,
49 | TexturePixel* destimage,
50 | QMap sourceimages,
51 | TextureNodeSettings* settings) const
52 | {
53 | if (!settings || !destimage || !size.isValid()) {
54 | return;
55 | }
56 | if (!sourceimages.contains(0)) {
57 | memset(destimage, 0, size.width() * size.height() * sizeof(TexturePixel));
58 | return;
59 | }
60 |
61 | double radius = settings->value("radius").toDouble() * size.width() / 100;
62 | double strength = settings->value("strength").toDouble() / 80;
63 | double offsetleft = settings->value("offsetleft").toDouble() * size.width() / 100;
64 | double offsettop = settings->value("offsettop").toDouble() * size.height() / 100;
65 |
66 | TexturePixel* source = sourceimages.value(0)->getData();
67 | int centerx = size.width() / 2 + offsetleft;
68 | int centery = size.height() / 2 + offsettop;
69 |
70 | for (int y = 0; y < size.height(); y++) {
71 | for (int x = 0; x < size.width(); x++) {
72 | double distortion = sqrt((x - centerx) * (x - centerx) + (y - centery) * (y - centery));
73 | if (distortion > radius) {
74 | distortion = 0;
75 | } else {
76 | distortion = (radius - distortion) * (radius - distortion) / radius;
77 | }
78 | double angle = 2 * M_PI * distortion / (radius / strength);
79 | int xpos = ((x - centerx) * cos(angle)) - ((y - centery) * sin(angle)) + centerx;
80 | int ypos = ((y - centery) * cos(angle)) + ((x - centerx) * sin(angle)) + centery;
81 | xpos = xpos > size.height() ? xpos % size.height() :
82 | (xpos < 0 ? xpos + size.width() : xpos);
83 | ypos = ypos > size.height() ? ypos % size.height() :
84 | (ypos < 0 ? ypos + size.height() : ypos);
85 | xpos = qMax(qMin(xpos, size.width() - 1), 0);
86 | ypos = qMax(qMin(ypos, size.height() - 1), 0);
87 | destimage[y * size.width() + x] = source[ypos * size.width() + xpos];
88 | }
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/generators/whirl.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Part of the ProceduralTextureMaker project.
3 | * http://github.com/johanokl/ProceduralTextureMaker
4 | * Released under GPLv3.
5 | * Johan Lindqvist (johan.lindqvist@gmail.com)
6 | */
7 |
8 | #ifndef WHIRLTEXTUREGENERATOR_H
9 | #define WHIRLTEXTUREGENERATOR_H
10 |
11 | #include "texturegenerator.h"
12 |
13 | /**
14 | * @brief The WhirlTextureGenerator class
15 | */
16 | class WhirlTextureGenerator : public TextureGenerator
17 | {
18 | public:
19 | WhirlTextureGenerator();
20 | ~WhirlTextureGenerator() override = default;
21 | void generate(QSize size,
22 | TexturePixel* destimage,
23 | QMap sourceimages,
24 | TextureNodeSettings* settings) const override;
25 | int getNumSourceSlots() const override { return 1; }
26 | QString getName() const override { return QString("Whirl"); }
27 | const TextureGeneratorSettings& getSettings() const override { return configurables; }
28 | QString getDescription() const override { return QString("Twirls the image."); }
29 | TextureGenerator::Type getType() const override { return TextureGenerator::Type::Filter; }
30 |
31 | private:
32 | TextureGeneratorSettings configurables;
33 | };
34 |
35 | #endif // WHIRLTEXTUREGENERATOR_H
36 |
--------------------------------------------------------------------------------
/global.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Part of the ProceduralTextureMaker project.
3 | * http://github.com/johanokl/ProceduralTextureMaker
4 | * Released under GPLv3.
5 | * Johan Lindqvist (johan.lindqvist@gmail.com)
6 | */
7 |
8 | #ifndef TEXGENGLOBAL_H
9 | #define TEXGENGLOBAL_H
10 |
11 | #include
12 | #include
13 | #include
14 |
15 | /**
16 | * @brief The TexturePixel class
17 | *
18 | * 32 bit RGBA pixel, stored as BGRA.
19 | */
20 | class TexturePixel {
21 | public:
22 | unsigned char b;
23 | unsigned char g;
24 | unsigned char r;
25 | unsigned char a;
26 |
27 | TexturePixel() = default;
28 |
29 | explicit
30 | TexturePixel(unsigned char red, unsigned char green,
31 | unsigned char blue, unsigned char alpha)
32 | : b(blue), g(green), r(red), a(alpha) {}
33 |
34 | TexturePixel(const TexturePixel& rhs) = default;
35 |
36 | /**
37 | * @brief TexturePixel::toRGBA
38 | * @return the pixel as RGBA
39 | */
40 | quint32 toRGBA() const {
41 | quint32 ret = r;
42 | ret = ret << 8;
43 | ret += g;
44 | ret = ret << 8;
45 | ret += b;
46 | ret = ret << 8;
47 | ret += a;
48 | return ret;
49 | }
50 |
51 | TexturePixel& operator=(const TexturePixel& rhs) = default;
52 |
53 | TexturePixel& operator+=(const TexturePixel& rhs) {
54 | r = static_cast(qMin(static_cast(rhs.r) + static_cast(r), 255));
55 | g = static_cast(qMin(static_cast(rhs.g) + static_cast(g), 255));
56 | b = static_cast(qMin(static_cast(rhs.b) + static_cast(b), 255));
57 | a = static_cast(qMin(static_cast(rhs.a) + static_cast(a), 255));
58 | return *this;
59 | }
60 |
61 | TexturePixel operator+(const TexturePixel& rhs) const {
62 | TexturePixel ret(*this);
63 | ret += rhs;
64 | return ret;
65 | }
66 |
67 | /**
68 | * @brief TexturePixel::intensity
69 | * @return the intensity of pixel, from 0 - 1
70 | */
71 | double intensity() const {
72 | return ((static_cast(this->r) +
73 | static_cast(this->g) +
74 | static_cast(this->b))
75 | / 3.0) / 255.0;
76 | }
77 |
78 | /**
79 | * @brief TexturePixel::intensity
80 | * @return the intensity of pixel, from 0 - 1
81 | */
82 | double intensityWithAlpha() const {
83 | return ((static_cast(this->r) +
84 | static_cast(this->g) +
85 | static_cast(this->b))
86 | / 3.0) * this->a / 255.0;
87 | }
88 |
89 | };
90 |
91 |
92 | struct TextureGeneratorSetting {
93 | QVariant defaultvalue;
94 | QString name;
95 | QString description = "";
96 | int order = 0;
97 | int defaultindex = 0; // For QStringList
98 | QVariant min;
99 | QVariant max;
100 | QString group = "";
101 | QString enabler = "";
102 | };
103 |
104 | typedef QMap TextureGeneratorSettings;
105 |
106 | typedef QMap TextureNodeSettings;
107 |
108 | #define ERROR_MSG(X) printf("ERROR: %s:%i: %s\n", __FUNCTION__, __LINE__, qPrintable(QString(X)))
109 | #define INFO_MSG(X) printf("INFO: %s: %s\n", __FUNCTION__, qPrintable(QString(X)))
110 |
111 | #endif // TEXGENGLOBAL_H
112 |
--------------------------------------------------------------------------------
/gui/addnodepanel.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Part of the ProceduralTextureMaker project.
3 | * http://github.com/johanokl/ProceduralTextureMaker
4 | * Released under GPLv3.
5 | * Johan Lindqvist (johan.lindqvist@gmail.com)
6 | */
7 |
8 | #ifndef ADDNODEPANEL_H
9 | #define ADDNODEPANEL_H
10 |
11 | #include "generators/texturegenerator.h"
12 | #include
13 | #include
14 |
15 | class TextureProject;
16 | class QGridLayout;
17 | class QVBoxLayout;
18 | class QGroupBox;
19 | class QScrollArea;
20 |
21 | /**
22 | * @brief The AddNodePanel class
23 | *
24 | * Vertical panel that displays all available node types.
25 | * All generators are represented as buttons that can be dragged to
26 | * the scene to add a new node.
27 | * The button list is updated automatically when new generators are
28 | * added to the associated project.
29 | */
30 | class AddNodePanel : public QWidget
31 | {
32 | Q_OBJECT
33 |
34 | public:
35 | explicit AddNodePanel(TextureProject*);
36 | ~AddNodePanel() override = default;
37 |
38 | public slots:
39 | void addGenerator(const TextureGeneratorPtr& generator);
40 | void removeGenerator(const TextureGeneratorPtr& generator);
41 |
42 | private:
43 | QMap widgets;
44 | TextureProject* project;
45 | QGroupBox* combinersWidget;
46 | QGroupBox* filtersWidget;
47 | QGroupBox* generatorsWidget;
48 | QGridLayout* filtersLayout;
49 | QGridLayout* combinersLayout;
50 | QGridLayout* generatorsLayout;
51 | };
52 |
53 |
54 | #endif // ADDNODEPANEL_H
55 |
--------------------------------------------------------------------------------
/gui/connectionwidget.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Part of the ProceduralTextureMaker project.
3 | * http://github.com/johanokl/ProceduralTextureMaker
4 | * Released under GPLv3.
5 | * Johan Lindqvist (johan.lindqvist@gmail.com)
6 | */
7 |
8 | #include "base/textureproject.h"
9 | #include "gui/connectionwidget.h"
10 | #include "gui/iteminfopanel.h"
11 | #include
12 | #include
13 | #include
14 | #include
15 |
16 | /**
17 | * @brief ConnectionWidget::ConnectionWidget
18 | * @param widgetmanager Parent.
19 | */
20 | ConnectionWidget::ConnectionWidget(ItemInfoPanel* widgetmanager)
21 | {
22 | this->widgetmanager = widgetmanager;
23 |
24 | layout = new QVBoxLayout(this);
25 | this->setLayout(layout);
26 |
27 | nodeInfoWidget = new QGroupBox("Connection");
28 | nodeInfoLayout = new QGridLayout();
29 | nodeInfoWidget->setLayout(nodeInfoLayout);
30 | nodeSourceLabel = new QLabel();
31 | nodeReceiverLabel = new QLabel();
32 | nodeSlotLabel = new QLabel();
33 | nodeInfoLayout->addWidget(new QLabel("Source: "), 0, 0);
34 | nodeInfoLayout->addWidget(new QLabel("Receiver: "), 1, 0);
35 | nodeInfoLayout->addWidget(new QLabel("Slot: "), 2, 0);
36 | nodeInfoLayout->addWidget(nodeSourceLabel, 0, 1);
37 | nodeInfoLayout->addWidget(nodeReceiverLabel, 1, 1);
38 | nodeInfoLayout->addWidget(nodeSlotLabel, 2, 1);
39 | layout->addWidget(nodeInfoWidget);
40 |
41 | QPushButton* disconnectNodesButton = new QPushButton("Disconnect");
42 | layout->addWidget(disconnectNodesButton);
43 | QObject::connect(disconnectNodesButton, &QPushButton::clicked,
44 | this, &ConnectionWidget::disconnectNodes);
45 |
46 | auto* spaceritem = new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding);
47 | layout->addItem(spaceritem);
48 |
49 | sourceNodeId = -1;
50 | receiverNodeId = -1;
51 | slot = -1;
52 | }
53 |
54 | /**
55 | * @brief ConnectionWidget::disconnectNodes
56 | */
57 | void ConnectionWidget::disconnectNodes()
58 | {
59 | TextureProject* project = widgetmanager->getTextureProject();
60 | if (project == nullptr) {
61 | return;
62 | }
63 | TextureNodePtr node = project->getNode(receiverNodeId);
64 | if (node.isNull()) {
65 | return;
66 | }
67 | node.data()->setSourceSlot(slot, 0);
68 | this->hide();
69 | }
70 |
71 | /**
72 | * @brief ConnectionWidget::setNodes
73 | * @param sourceNodeId Source node id
74 | * @param receiverNodeId Receiver node id
75 | * @param slot Receiver's slot id
76 | *
77 | * Updates the widget to display a new connection. Called when the user selects
78 | * a different connection (so that we don't need to create a new widget for
79 | * every single connection).
80 | */
81 | void ConnectionWidget::setNodes(int sourceNodeId, int receiverNodeId, int slot)
82 | {
83 | this->sourceNodeId = sourceNodeId;
84 | this->receiverNodeId = receiverNodeId;
85 | this->slot = slot;
86 |
87 | nodeSourceLabel->setText(QString("%1").arg(sourceNodeId));
88 | nodeReceiverLabel->setText(QString("%1").arg(receiverNodeId));
89 | nodeSlotLabel->setText(QString("%1").arg(slot + 1));
90 |
91 | TextureProject* project = widgetmanager->getTextureProject();
92 | if (project != nullptr) {
93 | TextureNodePtr node;
94 | node = project->getNode(sourceNodeId);
95 | if (!node.isNull()) {
96 | nodeSourceLabel->setText(QString("%1\n(%2)")
97 | .arg(node->getName(), node->getGeneratorName()));
98 | }
99 | node = project->getNode(receiverNodeId);
100 | if (!node.isNull()) {
101 | nodeReceiverLabel->setText(QString("%1\n(%2)")
102 | .arg(node->getName(), node->getGeneratorName()));
103 | }
104 | }
105 | }
106 |
107 |
108 |
--------------------------------------------------------------------------------
/gui/connectionwidget.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Part of the ProceduralTextureMaker project.
3 | * http://github.com/johanokl/ProceduralTextureMaker
4 | * Released under GPLv3.
5 | * Johan Lindqvist (johan.lindqvist@gmail.com)
6 | */
7 |
8 | #ifndef CONNECTIONWIDGET_H
9 | #define CONNECTIONWIDGET_H
10 |
11 | #include
12 |
13 | class TextureProject;
14 | class ItemInfoPanel;
15 | class QLabel;
16 | class QVBoxLayout;
17 | class QGroupBox;
18 | class QGridLayout;
19 |
20 | /**
21 | * @brief The ConnectionWidget class
22 | *
23 | * Simple widget that displays a connections. Currently just lists
24 | * the names of the source and receiver nodes with a button for
25 | * disconnecting them.
26 | *
27 | * @todo Display the nodes' images similar to PreviewImagePanel
28 | */
29 | class ConnectionWidget : public QWidget
30 | {
31 | Q_OBJECT
32 |
33 | public:
34 | explicit ConnectionWidget(ItemInfoPanel* widgetmanager);
35 | ~ConnectionWidget() override = default;
36 | void setNodes(int sourceNodeId, int receiverNodeId, int slot);
37 |
38 | public slots:
39 | void disconnectNodes();
40 |
41 | private:
42 | ItemInfoPanel* widgetmanager;
43 | int sourceNodeId;
44 | int receiverNodeId;
45 | int slot;
46 |
47 | QGroupBox* nodeInfoWidget;
48 | QGridLayout* nodeInfoLayout;
49 | QLabel* nodeSourceLabel;
50 | QLabel* nodeReceiverLabel;
51 | QLabel* nodeSlotLabel;
52 | QVBoxLayout* layout;
53 | };
54 |
55 | #endif // CONNECTIONWIDGET_H
56 |
--------------------------------------------------------------------------------
/gui/cubewidget.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Part of the ProceduralTextureMaker project.
3 | * http://github.com/johanokl/ProceduralTextureMaker
4 | * Released under GPLv3.
5 | * Johan Lindqvist (johan.lindqvist@gmail.com)
6 | */
7 |
8 | #ifndef PREVIEW3DPANEL_H
9 | #define PREVIEW3DPANEL_H
10 |
11 | #include
12 | #include
13 | #include
14 | #include
15 | #include
16 | #include
17 | #include
18 | #include
19 |
20 | /**
21 | * @brief The CubeWidget class
22 | */
23 | class CubeWidget : public QOpenGLWidget, protected QOpenGLFunctions
24 | {
25 | Q_OBJECT
26 | struct VertexData {
27 | QVector3D position;
28 | QVector2D texCoord;
29 | };
30 |
31 | public:
32 | explicit CubeWidget(QWidget *parent = nullptr);
33 | ~CubeWidget() override;
34 | void setTexture(const QPixmap& pixmap);
35 |
36 | public slots:
37 | void imageUpdated();
38 | void setBackgroundColor(const QColor& color);
39 |
40 | protected:
41 | void mousePressEvent(QMouseEvent *e) override;
42 | void mouseReleaseEvent(QMouseEvent *e) override;
43 | void timerEvent(QTimerEvent *e) override;
44 | void initializeGL() override;
45 | void resizeGL(int width, int height) override;
46 | void paintGL() override;
47 | void initShaders();
48 |
49 | private:
50 | QBasicTimer timer;
51 | QOpenGLShaderProgram program;
52 | QOpenGLTexture* texture;
53 | bool textureUpdated;
54 | QMatrix4x4 projection;
55 | QVector2D mousePressPosition;
56 | QVector3D rotationAxis;
57 | double angularSpeed;
58 | QQuaternion rotation;
59 | bool textureAvailable;
60 | QOpenGLBuffer arrayBuf;
61 | QOpenGLBuffer indexBuf;
62 | QColor backgroundcolor;
63 | bool initialized;
64 | };
65 |
66 |
67 | #endif // PREVIEW3DPANEL_H
68 |
--------------------------------------------------------------------------------
/gui/iteminfopanel.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Part of the ProceduralTextureMaker project.
3 | * http://github.com/johanokl/ProceduralTextureMaker
4 | * Released under GPLv3.
5 | * Johan Lindqvist (johan.lindqvist@gmail.com)
6 | */
7 |
8 | #ifndef ITEMINFOPANEL_H
9 | #define ITEMINFOPANEL_H
10 |
11 | #include "base/texturenode.h"
12 | #include
13 | #include
14 | #include
15 |
16 | class TextureProject;
17 | class NodeSettingsWidget;
18 | class ConnectionWidget;
19 | class SceneInfoWidget;
20 |
21 | /**
22 | * @brief The ItemInfoPanel class
23 | *
24 | * Controls which info widget to display at a given moment. Either the scene node,
25 | * when no node is selected in the graph, the node settings widget or the line
26 | * node connection info widget.
27 | */
28 | class ItemInfoPanel : public QWidget
29 | {
30 | Q_OBJECT
31 |
32 | public:
33 | ItemInfoPanel(QWidget* parent, TextureProject* textureProject);
34 | ~ItemInfoPanel() override = default;
35 | TextureProject* getTextureProject() { return texproject; }
36 |
37 | public slots:
38 | void setActiveNode(int id);
39 | void setActiveLine(int sourceNodeId, int receiverNodeId, int slot);
40 | void removeNode(int id);
41 | void addNode(const TextureNodePtr&);
42 | void sourceUpdated(int id);
43 | void nodesDisconnected(int sourceNodeId, int receiverNodeId, int slot);
44 |
45 | private:
46 | TextureProject* texproject;
47 | QMap nodes;
48 |
49 | ConnectionWidget* lineWidget;
50 | NodeSettingsWidget* currWidget;
51 | SceneInfoWidget* sceneWidget;
52 | int currNodeId;
53 | std::tuple currLine;
54 | };
55 |
56 |
57 | #endif // ITEMINFOPANEL_H
58 |
--------------------------------------------------------------------------------
/gui/mainwindow.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Part of the ProceduralTextureMaker project.
3 | * http://github.com/johanokl/ProceduralTextureMaker
4 | * Released under GPLv3.
5 | * Johan Lindqvist (johan.lindqvist@gmail.com)
6 | */
7 |
8 | #ifndef MAINWINDOW_H
9 | #define MAINWINDOW_H
10 |
11 | #include "generators/texturegenerator.h"
12 | #include
13 |
14 | class TexGenApplication;
15 | class TextureProject;
16 | class ViewNodeScene;
17 | class ViewNodeView;
18 | class ItemInfoPanel;
19 | class AddNodePanel;
20 | class QCloseEvent;
21 | class MenuActions;
22 | class PreviewImagePanel;
23 | class Preview3dPanel;
24 | class SettingsPanel;
25 | class SettingsManager;
26 | class JSTexGenManager;
27 |
28 | /**
29 | * @brief The MainWindow class
30 | *
31 | * The application's main window, containing all the scenes and panels.
32 | *
33 | * It initializes and configures the TextureProject with its submodules,
34 | * including which texture generators should be loaded.
35 | */
36 | class MainWindow : public QMainWindow
37 | {
38 | Q_OBJECT
39 |
40 | public:
41 | explicit MainWindow(TexGenApplication* parent = nullptr);
42 | ~MainWindow() override;
43 | TextureProject* getTextureProject() { return project; }
44 | TexGenApplication* parent() { return parentapp; }
45 | MenuActions* getMenu() { return menuactions; }
46 |
47 | public slots:
48 | bool saveAs();
49 | bool saveFile(bool newFileName = false);
50 | void openFile(const QString&);
51 | void clearScene();
52 | void showAbout();
53 | void showHelp();
54 | void closeEvent(QCloseEvent*) override;
55 | void copyNode();
56 | void pasteNode();
57 | void cutNode();
58 | void saveImage(int id = 0);
59 | void reloadSceneView();
60 | void moveToFront();
61 | void resetViewZoom();
62 | void generatorNameCollision(const TextureGeneratorPtr&, const TextureGeneratorPtr&);
63 |
64 | private:
65 | void drawScene();
66 | void createActions();
67 | bool maybeSave();
68 | ViewNodeScene* createScene(ViewNodeScene* source = nullptr);
69 |
70 | TexGenApplication* parentapp;
71 | TextureProject* project;
72 | QString savedFileName;
73 | MenuActions* menuactions;
74 |
75 | ViewNodeScene* scene;
76 | ViewNodeView* view;
77 | SettingsManager* settingsManager;
78 | JSTexGenManager* jstexgenManager;
79 | ItemInfoPanel* iteminfopanel;
80 | SettingsPanel* settingspanel;
81 | AddNodePanel* addnodewidget;
82 | PreviewImagePanel* previewimagewidget;
83 | Preview3dPanel* preview3dwidget;
84 | };
85 |
86 | #endif // MAINWINDOW_H
87 |
--------------------------------------------------------------------------------
/gui/menuactions.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Part of the ProceduralTextureMaker project.
3 | * http://github.com/johanokl/ProceduralTextureMaker
4 | * Released under GPLv3.
5 | * Johan Lindqvist (johan.lindqvist@gmail.com)
6 | */
7 |
8 | #ifndef MENUACTIONS_H
9 | #define MENUACTIONS_H
10 |
11 | #include
12 | #include
13 |
14 | class QMainWindow;
15 | class TextureProject;
16 | class TextureGenerator;
17 | class QMenu;
18 | class QAction;
19 | class MainWindow;
20 | class AddNodePanel;
21 | class PreviewImagePanel;
22 | class Preview3dPanel;
23 | class ItemInfoPanel;
24 | class SettingsPanel;
25 | class QToolBar;
26 |
27 | /**
28 | * @brief The MenuActions class
29 | *
30 | * Sets up the MainWindow's menus and toolbars and
31 | * the respective actions.
32 | *
33 | * Upon destruction the panel and toolbar visiblity settings are written
34 | * to persistant storage and loaded the next time the application is started.
35 | */
36 | class MenuActions : public QObject
37 | {
38 | Q_OBJECT
39 |
40 | public:
41 | explicit MenuActions(MainWindow* parentwindow);
42 | MainWindow* parent() { return parentwindow; }
43 | ~MenuActions() override;
44 | void setAddNodePanel(AddNodePanel* addNodePanel);
45 | void setPreviewImagePanel(PreviewImagePanel* previewImagePanel);
46 | void setSettingsPanel(SettingsPanel* settingsPanel);
47 | void setItemInfoPanel(ItemInfoPanel* settingswidget);
48 |
49 | public slots:
50 | void toggleAddNodePanel();
51 | void togglePreviewImagePanel();
52 | void toggleItemInfoPanel();
53 | void toggleSettingsPanel();
54 | void toogleToolbars();
55 | void openFile();
56 | void windowsChanged();
57 |
58 | private:
59 | MainWindow* parentwindow;
60 | AddNodePanel* nodepanel;
61 | PreviewImagePanel* previewImagePanel;
62 | ItemInfoPanel* nodesettings;
63 | SettingsPanel* settingspanel;
64 |
65 | QToolBar* settingsToolBar;
66 | QToolBar* fileToolBar;
67 | QToolBar* editToolBar;
68 | QToolBar* insertToolBar;
69 | QToolBar* toggleAddNodeToolBar;
70 |
71 | QMenu* fileMenu;
72 | QMenu* viewMenu;
73 | QMenu* editMenu;
74 | QMenu* helpMenu;
75 |
76 | QAction* newAct;
77 | QAction* openAct;
78 | QAction* saveAct;
79 | QAction* saveAsAct;
80 | QAction* saveImageAct;
81 | QAction* closeAct;
82 | QAction* exitAct;
83 | QAction* clearAct;
84 | QAction* copyAct;
85 | QAction* cutAct;
86 | QAction* pasteAct;
87 | QAction* helpAct;
88 | QAction* aboutAct;
89 | QAction* resetZoomAct;
90 | QAction* resetSceneAct;
91 | QAction* displayAddNodePanelAct;
92 | QAction* displayPreviewImagePanelAct;
93 | QAction* displayPreview3dPanelAct;
94 | QAction* displayItemInfoPanelAct;
95 | QAction* displaySettingsPanelAct;
96 | QAction* displayToolbarsAct;
97 | QAction* toggleItemInfoPanelAct;
98 | QAction* togglePreviewImagePanelAct;
99 | QAction* togglePreview3dPanelAct;
100 | QAction* toggleAddNodePanelAct;
101 |
102 | QVector windowlistActions;
103 | QString lastOpenedDirectory;
104 | };
105 |
106 | #endif // MENUACTIONS_H
107 |
--------------------------------------------------------------------------------
/gui/nodesettingswidget.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Part of the ProceduralTextureMaker project.
3 | * http://github.com/johanokl/ProceduralTextureMaker
4 | * Released under GPLv3.
5 | * Johan Lindqvist (johan.lindqvist@gmail.com)
6 | */
7 |
8 | #ifndef NODESETTINGSWIDGET_H
9 | #define NODESETTINGSWIDGET_H
10 |
11 | #include "base/texturenode.h"
12 | #include
13 | #include
14 | #include
15 |
16 | class ItemInfoPanel;
17 | class QLabel;
18 | class QPushButton;
19 | class QSpacerItem;
20 | class QGroupBox;
21 | class QLineEdit;
22 | class QFormLayout;
23 | class QSlider;
24 | class QGridLayout;
25 | class QDoubleSlider;
26 | class QScrollArea;
27 | class QVBoxLayout;
28 |
29 | /**
30 | * @brief The NodeSettingsWidget class
31 | *
32 | * Vertical panel for changing the values sent to the node's generator.
33 | * Has widgets for displaying and setting integer, double, color and
34 | * string/enum values.
35 | */
36 | class NodeSettingsWidget : public QWidget
37 | {
38 | Q_OBJECT
39 |
40 | public:
41 | NodeSettingsWidget(ItemInfoPanel* widgetmanager, int id);
42 | ~NodeSettingsWidget() override = default;
43 |
44 | public slots:
45 | void settingsUpdated();
46 | void slotsUpdated();
47 | void generatorUpdated();
48 | void saveSettings();
49 | void colorDialog(const QString&);
50 | void swapSlots();
51 |
52 | private:
53 | QFormLayout* createGroupLayout();
54 | void styleButton(QPushButton* button, const QColor& color);
55 | void setGroupAlignment(const QString& group, bool aligned);
56 | ItemInfoPanel* widgetmanager;
57 | int id;
58 | TextureNodePtr texNode;
59 | bool saveDisabled;
60 |
61 | QMap settingLabels;
62 | QMap settingElements;
63 | QMap settingSliders;
64 | QMap settingValues;
65 |
66 | QScrollArea* scrollarea;
67 | QWidget* contents;
68 | QVBoxLayout* contentsLayout;
69 |
70 | QFormLayout* settingsLayout;
71 | QGroupBox* settingsWidget;
72 |
73 | QLabel* generatorNameLabel;
74 | QGroupBox* nodeInfoWidget;
75 | QFormLayout* nodeInfoLayout;
76 | QLineEdit* nodeNameLineEdit;
77 |
78 | QGroupBox* sourceButtonsWidget;
79 | QGridLayout* sourceButtonsLayout;
80 | QList sourceSlotLabels;
81 | QPushButton* swapSlotButton;
82 | QList sourceSlotButtons;
83 | QVBoxLayout* layout;
84 | };
85 |
86 | #endif // NODESETTINGSWIDGET_H
87 |
--------------------------------------------------------------------------------
/gui/previewimagepanel.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Part of the ProceduralTextureMaker project.
3 | * http://github.com/johanokl/ProceduralTextureMaker
4 | * Released under GPLv3.
5 | * Johan Lindqvist (johan.lindqvist@gmail.com)
6 | */
7 |
8 | #ifndef PREVIEWIMAGEPANEL_H
9 | #define PREVIEWIMAGEPANEL_H
10 |
11 | #include
12 |
13 | class TextureProject;
14 | class QGridLayout;
15 | class QVBoxLayout;
16 | class QGroupBox;
17 | class QPushButton;
18 | class ImageLabel;
19 | class QLabel;
20 | class QComboBox;
21 | class CubeWidget;
22 | class QResizeEvent;
23 | class QShowEvent;
24 |
25 | /**
26 | * @brief The PreviewImagePanel class
27 | *
28 | * Vertical panel that displays a node's generated image.
29 | * When an active node's image is updated this also propagates
30 | * to the panel, which then updates the displayed image.
31 | */
32 | class PreviewImagePanel : public QWidget
33 | {
34 | Q_OBJECT
35 |
36 | public:
37 | explicit PreviewImagePanel(TextureProject*);
38 | ~PreviewImagePanel() override = default;
39 | void showEvent(QShowEvent* event) override;
40 | bool loadNodeImage(int);
41 |
42 | public slots:
43 | void setActiveNode(int);
44 | void imageAvailable(int, QSize);
45 | void imageUpdated(int);
46 | void settingsUpdated();
47 | void nodeRemoved(int);
48 |
49 | private:
50 | QPixmap tilePixmap(const QPixmap& pixmap, int number);
51 | TextureProject* project;
52 | QVBoxLayout* layout;
53 | QComboBox* combobox;
54 | ImageLabel* imageLabel;
55 | CubeWidget* cubeWidget;
56 | QPushButton* lockNodeButton;
57 | int currId;
58 | int numTiles;
59 | QSize imageSize;
60 | };
61 |
62 | /**
63 | * @brief The ImageLabel class
64 | *
65 | * QLabel with added functions to handle automatic
66 | * scaling of QPixmap images to fit them in inside a QWidget.
67 | * Supports 2x2 tiled drawing.
68 | */
69 | class ImageLabel : public QWidget
70 | {
71 | Q_OBJECT
72 | public:
73 | explicit ImageLabel(QWidget* parent = nullptr);
74 | public slots:
75 | void setPixmap(const QPixmap&);
76 | protected:
77 | void resizeEvent(QResizeEvent*) override;
78 | private slots:
79 | void resizeImage();
80 | private:
81 | QLabel* label;
82 | };
83 |
84 | #endif // PREVIEWIMAGEPANEL_H
85 |
--------------------------------------------------------------------------------
/gui/qdoubleslider.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Part of the ProceduralTextureMaker project.
3 | * http://github.com/johanokl/ProceduralTextureMaker
4 | * Released under GPLv3.
5 | * Johan Lindqvist (johan.lindqvist@gmail.com)
6 | */
7 |
8 | #ifndef QDOUBLESLIDER_H
9 | #define QDOUBLESLIDER_H
10 |
11 | #include
12 |
13 | /**
14 | * @brief The QDoubleSlider class
15 | *
16 | * Class derived from QSlider to support floating point values.
17 | * QSlider only supports integers so this has been modified to refer to the values
18 | * in 0,01 increments (100 times the value).
19 | * All signals and slots upscales or downscales it so that it can be used
20 | * interchangeably as a replacement for QSlider.
21 | */
22 | class QDoubleSlider : public QSlider {
23 | Q_OBJECT
24 |
25 | public:
26 | explicit QDoubleSlider(Qt::Orientation orientation = Qt::Orientation::Horizontal, QWidget* parent = nullptr)
27 | : QSlider(orientation, parent) {
28 | QObject::connect(this, &QDoubleSlider::valueChanged,
29 | this, &QDoubleSlider::notifyValueChanged);
30 | }
31 |
32 | signals:
33 | void doubleValueChanged(double value);
34 |
35 | public slots:
36 | void setDoubleMinimum(double value) {
37 | setMinimum(value * 100);
38 | }
39 | void setDoubleMaximum(double value) {
40 | setMaximum(value * 100);
41 | }
42 | void notifyValueChanged(int value) {
43 | emit doubleValueChanged((double) value / 100.0);
44 | }
45 | void setDoubleValue(double value) {
46 | setValue(value * 100);
47 | }
48 | };
49 |
50 | #endif // QDOUBLESLIDER_H
51 |
--------------------------------------------------------------------------------
/gui/sceneinfowidget.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Part of the ProceduralTextureMaker project.
3 | * http://github.com/johanokl/ProceduralTextureMaker
4 | * Released under GPLv3.
5 | * Johan Lindqvist (johan.lindqvist@gmail.com)
6 | */
7 |
8 | #include "base/textureproject.h"
9 | #include "gui/iteminfopanel.h"
10 | #include "gui/sceneinfowidget.h"
11 | #include
12 | #include
13 |
14 | /**
15 | * @brief SceneInfoWidget::SceneInfoWidget
16 | * @param widgetmanager Parent
17 | */
18 | SceneInfoWidget::SceneInfoWidget(ItemInfoPanel* widgetmanager)
19 | {
20 | this->widgetmanager = widgetmanager;
21 |
22 | layout = new QVBoxLayout(this);
23 | this->setLayout(layout);
24 |
25 | nodeInfoWidget = new QGroupBox("Scene info");
26 | nodeInfoLayout = new QGridLayout();
27 | nodeInfoWidget->setLayout(nodeInfoLayout);
28 | nodeInfoLayout->addWidget(new QLabel("Number of nodes: "), 0, 0);
29 | numNodesLabel = new QLabel("0", this);
30 | nodeInfoLayout->addWidget(numNodesLabel, 0, 1);
31 | layout->addWidget(nodeInfoWidget);
32 |
33 | layout->addItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding));
34 | }
35 |
36 | /**
37 | * @brief SceneInfoWidget::updateNumNodes
38 | * Updates the text label with the number of nodes.
39 | */
40 | void SceneInfoWidget::updateNumNodes()
41 | {
42 | int num = widgetmanager->getTextureProject()->getNumNodes();
43 | numNodesLabel->setText(QString("%1").arg(num));
44 | }
45 |
--------------------------------------------------------------------------------
/gui/sceneinfowidget.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Part of the ProceduralTextureMaker project.
3 | * http://github.com/johanokl/ProceduralTextureMaker
4 | * Released under GPLv3.
5 | * Johan Lindqvist (johan.lindqvist@gmail.com)
6 | */
7 |
8 | #ifndef SCENEINFOWIDGET_H
9 | #define SCENEINFOWIDGET_H
10 |
11 | #include "base/texturenode.h"
12 | #include
13 | #include
14 |
15 | class ItemInfoPanel;
16 | class QLabel;
17 | class QGroupBox;
18 | class QVBoxLayout;
19 |
20 | /**
21 | * @brief The SceneInfoWidget class
22 | *
23 | * Simple widget which currently just displays the number of nodes
24 | * in the scene. For having something to display in the info panel
25 | * when the scene's empty.
26 | */
27 | class SceneInfoWidget : public QWidget
28 | {
29 | Q_OBJECT
30 |
31 | public:
32 | explicit SceneInfoWidget(ItemInfoPanel* widgetmanager);
33 | ~SceneInfoWidget() override = default;
34 | void updateNumNodes();
35 |
36 | private:
37 | ItemInfoPanel* widgetmanager;
38 |
39 | QGroupBox* nodeInfoWidget;
40 | QGridLayout* nodeInfoLayout;
41 | QLabel* numNodesLabel;
42 | QVBoxLayout* layout;
43 | };
44 |
45 | #endif // SCENEINFOWIDGET_H
46 |
--------------------------------------------------------------------------------
/gui/settingspanel.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Part of the ProceduralTextureMaker project.
3 | * http://github.com/johanokl/ProceduralTextureMaker
4 | * Released under GPLv3.
5 | * Johan Lindqvist (johan.lindqvist@gmail.com)
6 | */
7 |
8 | #ifndef SETTINGSPANEL_H
9 | #define SETTINGSPANEL_H
10 |
11 | #include
12 |
13 | class QVBoxLayout;
14 | class QScrollArea;
15 | class QSpinBox;
16 | class SettingsManager;
17 | class QLineEdit;
18 | class QCheckBox;
19 | class QPushButton;
20 | class MainWindow;
21 | class QComboBox;
22 |
23 | /**
24 | * @brief The SettingsPanel class
25 | *
26 | * Vertical panel with all the user controlled settings for a project
27 | * listed. Connected to a SettingsManager instance which loads and saved
28 | * to an persistant storage.
29 | */
30 | class SettingsPanel : public QWidget
31 | {
32 | Q_OBJECT
33 |
34 | public:
35 | SettingsPanel(MainWindow* parent, SettingsManager* settingsmanager);
36 | ~SettingsPanel() override = default;
37 | void showEvent(QShowEvent*) override;
38 |
39 | public slots:
40 | void settingsUpdated();
41 | void saveSettings();
42 | void selectDirectoryPath(QLineEdit*);
43 | void colorDialog(QPushButton*);
44 |
45 | private:
46 | void styleColorButton(QPushButton*, const QColor&);
47 |
48 | SettingsManager* settingsmanager;
49 |
50 | QVBoxLayout* contentsLayout;
51 | QVBoxLayout* layout;
52 | QScrollArea* area;
53 | QWidget* contents;
54 |
55 | QSpinBox* thumbnailWidthSpinbox;
56 | QSpinBox* thumbnailHeightSpinbox;
57 | QSpinBox* exportImageWidthSpinbox;
58 | QSpinBox* exportImageHeightSpinbox;
59 | QSpinBox* defaultZoomSpinbox;
60 | QLineEdit* jsGeneratorPathEdit;
61 | QCheckBox* jsGeneratorEnabledCheckbox;
62 | QPushButton* backgroundColorButton;
63 | QPushButton* previewBackgroundColorButton;
64 | QComboBox* backgroundBrushCombobox;
65 |
66 | bool blockSlot;
67 | };
68 |
69 | #endif // SETTINGSPANEL_H
70 |
--------------------------------------------------------------------------------
/images/copyicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johanokl/ProceduralTextureMaker/1d46e273b5e213ad15c635233b4e7763d5404be4/images/copyicon.png
--------------------------------------------------------------------------------
/images/cuticon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johanokl/ProceduralTextureMaker/1d46e273b5e213ad15c635233b4e7763d5404be4/images/cuticon.png
--------------------------------------------------------------------------------
/images/mainicon.icns:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johanokl/ProceduralTextureMaker/1d46e273b5e213ad15c635233b4e7763d5404be4/images/mainicon.icns
--------------------------------------------------------------------------------
/images/mainicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johanokl/ProceduralTextureMaker/1d46e273b5e213ad15c635233b4e7763d5404be4/images/mainicon.ico
--------------------------------------------------------------------------------
/images/mainicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johanokl/ProceduralTextureMaker/1d46e273b5e213ad15c635233b4e7763d5404be4/images/mainicon.png
--------------------------------------------------------------------------------
/images/new.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johanokl/ProceduralTextureMaker/1d46e273b5e213ad15c635233b4e7763d5404be4/images/new.png
--------------------------------------------------------------------------------
/images/open.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johanokl/ProceduralTextureMaker/1d46e273b5e213ad15c635233b4e7763d5404be4/images/open.png
--------------------------------------------------------------------------------
/images/pasteicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johanokl/ProceduralTextureMaker/1d46e273b5e213ad15c635233b4e7763d5404be4/images/pasteicon.png
--------------------------------------------------------------------------------
/images/save.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johanokl/ProceduralTextureMaker/1d46e273b5e213ad15c635233b4e7763d5404be4/images/save.png
--------------------------------------------------------------------------------
/main.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Part of the ProceduralTextureMaker project.
3 | * http://github.com/johanokl/ProceduralTextureMaker
4 | * Released under GPLv3.
5 | * Johan Lindqvist (johan.lindqvist@gmail.com)
6 | */
7 |
8 | #include "texgenapplication.h"
9 | #include
10 |
11 | int main(int argc, char**argv)
12 | {
13 | QCoreApplication::setOrganizationName("Johan Lindqvist");
14 | QCoreApplication::setOrganizationDomain("github.com/johanokl");
15 | QCoreApplication::setApplicationName("ProceduralTextureMaker");
16 |
17 | TexGenApplication app(argc, argv);
18 | return app.exec();
19 | }
20 |
--------------------------------------------------------------------------------
/sceneview/viewnodeitem.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Part of the ProceduralTextureMaker project.
3 | * http://github.com/johanokl/ProceduralTextureMaker
4 | * Released under GPLv3.
5 | * Johan Lindqvist (johan.lindqvist@gmail.com)
6 | */
7 |
8 | #ifndef VIEWNODEITEM_H
9 | #define VIEWNODEITEM_H
10 |
11 | #include "base/texturenode.h"
12 | #include
13 |
14 | class ViewNodeScene;
15 | class TextureNode;
16 | class ViewNodeLine;
17 |
18 | /**
19 | * @brief The ViewNodeItem class
20 | *
21 | * Renders the node as a widget in a ViewNodeView scene.
22 | * Contains functions that let the user interact with the node and
23 | * change connections, positions etc.
24 | */
25 | class ViewNodeItem : public QGraphicsItem
26 | {
27 | friend class ViewNodeLine;
28 | friend class ViewNodeScene;
29 |
30 | public:
31 | ViewNodeItem(ViewNodeScene* scene, const TextureNodePtr& newNode);
32 | ~ViewNodeItem() override = default;
33 | void paint (QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) override;
34 | int getId() const { return id; }
35 | TextureNodePtr getTextureNode() { return texNode; }
36 | bool posInImage(QPointF pos) const;
37 | QRectF boundingRect() const override;
38 | QPainterPath shape() const override;
39 | QVariant itemChange(GraphicsItemChange change, const QVariant& value) override;
40 | void showConnectable(bool showConnectable);
41 | void showUnconnectable(bool showUnconnectable);
42 | void clearOverlays();
43 | QSet getStartLines() const { return startLines; }
44 | QMap getEndLines() const { return endLines; }
45 | void addConnectionLine(ViewNodeLine* line);
46 | void removeConnectionLine(ViewNodeLine* line);
47 |
48 | public slots:
49 | void positionUpdated();
50 | void settingsUpdated();
51 | void imageUpdated();
52 | void imageAvailable(QSize size);
53 | void generatorUpdated();
54 | void setThumbnailSize(QSize);
55 |
56 | protected:
57 | void mousePressEvent(QGraphicsSceneMouseEvent* event) override;
58 | void mouseMoveEvent(QGraphicsSceneMouseEvent* mouseEvent) override;
59 | void mouseReleaseEvent(QGraphicsSceneMouseEvent* event) override;
60 | void hoverMoveEvent(QGraphicsSceneHoverEvent* event) override;
61 | void hoverEnterEvent(QGraphicsSceneHoverEvent* event) override;
62 | void hoverLeaveEvent(QGraphicsSceneHoverEvent* event) override;
63 | void contextMenuEvent(QGraphicsSceneContextMenuEvent* event) override;
64 |
65 | private:
66 | int id;
67 |
68 | ViewNodeScene* scene;
69 | QPixmap pixmap;
70 | TextureNodePtr texNode;
71 | QSize thumbnailSize;
72 | QString titleString;
73 |
74 | int highlightSlot;
75 | QPointF mousePressedPos;
76 | QPointF mousePressedItemPos;
77 | int highlighterWidth;
78 | int borderWidth;
79 |
80 | QSet startLines;
81 | QMap endLines;
82 |
83 | bool imageValid;
84 | bool isUnconnectable;
85 | bool isConnectable;
86 | bool mousePressed;
87 | };
88 |
89 | #endif // VIEWNODEITEM_H
90 |
--------------------------------------------------------------------------------
/sceneview/viewnodeline.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Part of the ProceduralTextureMaker project.
3 | * http://github.com/johanokl/ProceduralTextureMaker
4 | * Released under GPLv3.
5 | * Johan Lindqvist (johan.lindqvist@gmail.com)
6 | */
7 |
8 | #ifndef VIEWNODELINE_H
9 | #define VIEWNODELINE_H
10 |
11 | #include
12 |
13 | class ViewNodeItem;
14 | class ViewNodeScene;
15 | class QPen;
16 |
17 | /**
18 | * @brief The ViewNodeLine class
19 | *
20 | * Draws a styled line in a ViewNodeScene.
21 | */
22 | class ViewNodeLine : public QGraphicsLineItem
23 | {
24 | friend class ViewNodeScene;
25 | friend class ViewNodeItem;
26 |
27 | public:
28 | ~ViewNodeLine() override;
29 | void updatePos();
30 | inline int getSlot() const { return slot; }
31 | inline int getStartItemId() const { return sourceItemId; }
32 | inline int getEndItemId() const { return receiverItemId; }
33 | void setHighlighted(bool highlighted);
34 | void setWidth(int width);
35 | void setColor(const QColor& color);
36 | void setNodes(int sourceNodeId, int receiverNodeId);
37 | void setPos(QPointF startPos, QPointF endPos);
38 | QRectF boundingRect() const override;
39 | QPainterPath shape() const override;
40 |
41 | protected:
42 | void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget) override;
43 | void mousePressEvent(QGraphicsSceneMouseEvent* event) override;
44 | void hoverEnterEvent(QGraphicsSceneHoverEvent* event) override;
45 | void hoverLeaveEvent(QGraphicsSceneHoverEvent* event) override;
46 |
47 | private:
48 | ViewNodeLine(ViewNodeScene* scene, int sourceItem, int receiverItem, int slot);
49 | ViewNodeScene* nodescene;
50 | int sourceItemId;
51 | int receiverItemId;
52 | int slot;
53 |
54 | QPointF sourcePos;
55 | QPointF receiverPos;
56 |
57 | QPolygonF arrowHead;
58 | QPen* myPen;
59 | bool infocus;
60 | };
61 |
62 | #endif // VIEWNODELINE_H
63 |
--------------------------------------------------------------------------------
/sceneview/viewnodescene.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Part of the ProceduralTextureMaker project.
3 | * http://github.com/johanokl/ProceduralTextureMaker
4 | * Released under GPLv3.
5 | * Johan Lindqvist (johan.lindqvist@gmail.com)
6 | */
7 |
8 | #ifndef VIEWNODESCENE_H
9 | #define VIEWNODESCENE_H
10 |
11 | #include "base/texturenode.h"
12 | #include
13 | #include
14 | #include
15 |
16 | class TextureProject;
17 | class ViewNodeItem;
18 | class ViewNodeLine;
19 | class TextureGenerator;
20 | class MainWindow;
21 | class QAction;
22 | class QGraphicsRectItem;
23 |
24 | /**
25 | * @brief The ViewNodeScene class
26 | *
27 | * The visualization of a TextureProject node scene.
28 | *
29 | * Manages the ViewNodeItem and ViewNodeLine object as well as
30 | * user's actions on it via the scene widget.
31 | */
32 | class ViewNodeScene : public QGraphicsScene
33 | {
34 | Q_OBJECT
35 | friend class ViewNodeItem;
36 |
37 | public:
38 | explicit ViewNodeScene(MainWindow* parent);
39 | ~ViewNodeScene() override = default;
40 | ViewNodeScene* clone() const;
41 | TextureProject* getTextureProject() const { return project; }
42 | MainWindow* getParent() const { return parent; }
43 | virtual void clear();
44 | void endLineDrawing(int endNode);
45 | void startLineDrawing(int nodeId);
46 | ViewNodeItem* getItem(int id) const;
47 |
48 | void setSelectedNode(int id);
49 | int getSelectedNode() const { return selectedNode; }
50 | void setSelectedLine(int sourceNode, int receiverNode, int slot);
51 | void connectNodes(int sourceNodeId, int receiverNodeId, int slotId);
52 | void removeConnection(int sourceNodeId, int receiverNodeId);
53 |
54 | protected:
55 | void mousePressEvent(QGraphicsSceneMouseEvent* mouseEvent) override;
56 | void mouseReleaseEvent(QGraphicsSceneMouseEvent* mouseEvent) override;
57 | void mouseMoveEvent(QGraphicsSceneMouseEvent* mouseEvent) override;
58 | void contextMenuEvent(QGraphicsSceneContextMenuEvent* event) override;
59 | void dragEnterEvent(QGraphicsSceneDragDropEvent* event) override;
60 | void dragMoveEvent(QGraphicsSceneDragDropEvent* event) override;
61 | void dragLeaveEvent(QGraphicsSceneDragDropEvent* event) override;
62 | void dropEvent(QGraphicsSceneDragDropEvent* event) override;
63 | void keyPressEvent(QKeyEvent* event) override;
64 |
65 | public slots:
66 | void addNode(const TextureNodePtr& newNode);
67 | void nodeRemoved(int id);
68 | void positionUpdated(int id);
69 | void nodeSettingsUpdated(int id);
70 | void imageUpdated(int id);
71 | void imageAvailable(int id, QSize size);
72 | void nodesConnected(int sourceid, int slot, int receiverid);
73 | void nodesDisconnected(int sourceid, int slot, int receiverid);
74 | void generatorUpdated(int id);
75 | void settingsUpdated();
76 |
77 | signals:
78 | void nodeSelected(int id);
79 | void lineSelected(int sourceNode, int receiverNode, int slot);
80 |
81 | private:
82 | MainWindow* parent;
83 | TextureProject* project;
84 | QMap nodeItems;
85 | QMap, ViewNodeLine*> nodeConnections;
86 |
87 | QGraphicsRectItem* dropItem;
88 | ViewNodeLine* lineItem;
89 | int startLineNode;
90 | int selectedNode;
91 | std::tuple selectedLine;
92 | bool lineDrawing;
93 | };
94 |
95 | #endif // VIEWNODESCENE_H
96 |
--------------------------------------------------------------------------------
/sceneview/viewnodeview.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Part of the ProceduralTextureMaker project.
3 | * http://github.com/johanokl/ProceduralTextureMaker
4 | * Released under GPLv3.
5 | * Johan Lindqvist (johan.lindqvist@gmail.com)
6 | */
7 |
8 | #include "viewnodeview.h"
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include
14 |
15 | /**
16 | * @brief ViewNodeView::ViewNodeView
17 | * @param defaultzoom Zoom factor in percentage, 100 is 1:1.
18 | */
19 | ViewNodeView::ViewNodeView(int defaultzoom)
20 | {
21 | setMouseTracking(true);
22 | // The mouse wheel scroll factor
23 | scrollZoomFactor = 1.0015;
24 | setDragMode(QGraphicsView::ScrollHandDrag);
25 | defaultZoomFactor = static_cast(defaultzoom) / 100;
26 | scale(defaultZoomFactor, defaultZoomFactor);
27 | }
28 |
29 | /**
30 | * @brief ViewNodeView::setDefaultZoom
31 | * @param zoom Zoom factor in percentage, 100 is 1:1.
32 | */
33 | void ViewNodeView::setDefaultZoom(int zoom)
34 | {
35 | defaultZoomFactor = static_cast(zoom) / 100;
36 | resetZoom();
37 | }
38 |
39 | /**
40 | * @brief ViewNodeView::resetZoom
41 | * Resets to the default zoom, 100%.
42 | */
43 | void ViewNodeView::resetZoom()
44 | {
45 | const ViewportAnchor anchor = transformationAnchor();
46 | setTransformationAnchor(QGraphicsView::AnchorViewCenter);
47 | resetTransform();
48 | scale(defaultZoomFactor, defaultZoomFactor);
49 | setTransformationAnchor(anchor);
50 | }
51 |
52 | /**
53 | * @brief ViewNodeView::wheelEvent
54 | * @param event
55 | *
56 | * Zooms in and out from the screen when the user scrolls the
57 | * mouse wheel while pressing the Shift or Alt keys.
58 | */
59 | void ViewNodeView::wheelEvent(QWheelEvent* event) {
60 | auto* wheel_event = static_cast(event);
61 | if (QApplication::keyboardModifiers() == Qt::ShiftModifier
62 | || QApplication::keyboardModifiers() == Qt::AltModifier) {
63 | const ViewportAnchor anchor = transformationAnchor();
64 | setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
65 | double angle = wheel_event->angleDelta().y();
66 | double factor = qPow(scrollZoomFactor, angle);
67 | scale(factor, factor);
68 | setTransformationAnchor(anchor);
69 | }
70 | QGraphicsView::wheelEvent(event);
71 | }
72 |
--------------------------------------------------------------------------------
/sceneview/viewnodeview.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Part of the ProceduralTextureMaker project.
3 | * http://github.com/johanokl/ProceduralTextureMaker
4 | * Released under GPLv3.
5 | * Johan Lindqvist (johan.lindqvist@gmail.com)
6 | */
7 |
8 | #ifndef VIEWNODEVIEW_H
9 | #define VIEWNODEVIEW_H
10 |
11 | #include
12 | #include
13 |
14 | /**
15 | * @brief The ViewNodeView class
16 | *
17 | * Displays a ViewNodeScene instance with ViewNodeItem/ViewNodeLine objects.
18 | * Supports zooming and scrolling, both with mouse dragging and scrollbars.
19 | */
20 | class ViewNodeView : public QGraphicsView
21 | {
22 | public:
23 | explicit ViewNodeView(int defaultZoom = 100);
24 | ~ViewNodeView() override = default;
25 |
26 | public slots:
27 | void resetZoom();
28 | void setDefaultZoom(int zoom);
29 |
30 | protected:
31 | void wheelEvent(QWheelEvent* event) override;
32 |
33 | private:
34 | double scrollZoomFactor;
35 | double defaultZoomFactor;
36 | };
37 |
38 | #endif // VIEWNODEVIEW_H
39 |
--------------------------------------------------------------------------------
/shaders.qrc:
--------------------------------------------------------------------------------
1 |
2 |
3 | 3d/vshader.glsl
4 | 3d/fshader.glsl
5 |
6 |
7 |
--------------------------------------------------------------------------------
/texgen.qrc:
--------------------------------------------------------------------------------
1 |
2 |
3 | images/copyicon.png
4 | images/cuticon.png
5 | images/new.png
6 | images/open.png
7 | images/pasteicon.png
8 | images/save.png
9 | images/mainicon.icns
10 | images/mainicon.ico
11 | images/mainicon.png
12 |
13 |
14 |
--------------------------------------------------------------------------------
/texgenapplication.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Part of the ProceduralTextureMaker project.
3 | * http://github.com/johanokl/ProceduralTextureMaker
4 | * Released under GPLv3.
5 | * Johan Lindqvist (johan.lindqvist@gmail.com)
6 | */
7 |
8 | #include "base/textureproject.h"
9 | #include "gui/mainwindow.h"
10 | #include "texgenapplication.h"
11 | #include
12 |
13 | /**
14 | * @brief TexGenApplication::TexGenApplication
15 | * @param argc Number of arguments passed (including the application name).
16 | * @param argv Array of arguments as C char strings.
17 | */
18 | TexGenApplication::TexGenApplication(int &argc, char* argv[]) : QApplication(argc, argv)
19 | {
20 | addWindow();
21 | #ifndef Q_OS_MAC
22 | // On Mac OS the platform handles this automatically,
23 | if (argc > 1) {
24 | mainwindows.first()->openFile(QString(argv[1]));
25 | }
26 | #endif
27 | }
28 |
29 | /**
30 | * @brief TexGenApplication::quit
31 | * Tries to close all windows. Stops if one can't be closed.
32 | */
33 | void TexGenApplication::quit()
34 | {
35 | QMutableVectorIterator it(mainwindows);
36 | it.toBack();
37 | while (it.hasPrevious()) {
38 | if (it.previous()->close() == false) {
39 | return;
40 | }
41 | }
42 | }
43 |
44 | /**
45 | * @brief TexGenApplication::addWindow
46 | * Adds a new MainWindow.
47 | */
48 | MainWindow* TexGenApplication::addWindow()
49 | {
50 | auto* newWindow = new MainWindow(this);
51 | QObject::connect(newWindow, &MainWindow::windowTitleChanged,
52 | this, &TexGenApplication::windowUpdated);
53 | QObject::connect(newWindow, &MainWindow::destroyed,
54 | this, &TexGenApplication::removeWindow);
55 | mainwindows.push_back(newWindow);
56 | newWindow->show();
57 | emit windowsChanged();
58 | return newWindow;
59 | }
60 |
61 | /**
62 | * @brief TexGenApplication::removeWindow
63 | * @param windowObj The window to be removed.
64 | * Removes a MainWindows from the window list.
65 | */
66 | void TexGenApplication::removeWindow(QObject* windowObj)
67 | {
68 | int index = mainwindows.indexOf(dynamic_cast(windowObj));
69 | if (index == -1) {
70 | return;
71 | }
72 | mainwindows.remove(index);
73 | emit windowsChanged();
74 | }
75 |
76 | /**
77 | * @brief TexGenApplication::windowUpdated
78 | *
79 | * Slot invoked when a program has updated its title.
80 | * Will emit windowsChanged to all the windows, telling them to update their window lists.
81 | */
82 | void TexGenApplication::windowUpdated(QString)
83 | {
84 | emit windowsChanged();
85 | }
86 |
87 | /**
88 | * @brief TexGenApplication::event
89 | * Used to handle files being dropped on the application icon in OS X.
90 | */
91 | bool TexGenApplication::event(QEvent* event) {
92 | if (event->type() == QEvent::FileOpen) {
93 | MainWindow* projectWindow = nullptr;
94 | if (!mainwindows.isEmpty()) {
95 | projectWindow = mainwindows.last();
96 | }
97 | if (mainwindows.length() != 1 ||
98 | (projectWindow && projectWindow->getTextureProject() &&
99 | projectWindow->getTextureProject()->isModified())) {
100 | // There are either multiple windows opened or the only one open
101 | // already contains data. Create a new fresh window for this project file.
102 | projectWindow = this->addWindow();
103 | }
104 | if (projectWindow != nullptr) {
105 | projectWindow->openFile(static_cast(event)->file());
106 | }
107 | return true;
108 | }
109 | return QApplication::event(event);
110 | }
111 |
--------------------------------------------------------------------------------
/texgenapplication.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Part of the ProceduralTextureMaker project.
3 | * http://github.com/johanokl/ProceduralTextureMaker
4 | * Released under GPLv3.
5 | * Johan Lindqvist (johan.lindqvist@gmail.com)
6 | */
7 |
8 | #ifndef TEXGENAPPLICATION_H
9 | #define TEXGENAPPLICATION_H
10 |
11 | #include