aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAiden Woodruff <aiden.woodruff@gmail.com>2023-11-29 22:14:48 -0500
committerAiden Woodruff <aiden.woodruff@gmail.com>2023-11-29 22:14:48 -0500
commit3e55710755603c0236191ee95fe6f54bc4124c8f (patch)
tree78002d798b8b43c838093803c6568fa183020ab4
parentba891ea777d9495bb584c7dab1c7871c494e50b2 (diff)
downloadnoise-3e55710755603c0236191ee95fe6f54bc4124c8f.tar.gz
noise-3e55710755603c0236191ee95fe6f54bc4124c8f.tar.bz2
noise-3e55710755603c0236191ee95fe6f54bc4124c8f.zip
Add abstract brush class and cardinal average
Add FuncBlur (i.e. with inverse distance function) Add ListBlur to average a list of points Use configure_file instead of file(COPY) bc it uses relative paths. - Also it is more declarative. Rename cpp to cc Update README Update TODO
-rw-r--r--CMakeLists.txt8
-rw-r--r--README.md4
-rw-r--r--TODO.md2
-rw-r--r--brush.cc46
-rw-r--r--brush.h38
-rw-r--r--brushes.h10
-rw-r--r--noise.cc (renamed from noise.cpp)8
7 files changed, 105 insertions, 11 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index ee0c65a..b2facc6 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -4,11 +4,7 @@ project(noise VERSION 0.0 LANGUAGES CXX)
4 4
5find_package(SFML COMPONENTS graphics REQUIRED) 5find_package(SFML COMPONENTS graphics REQUIRED)
6 6
7add_executable(noise noise.cpp) 7add_executable(noise noise.cc brush.cc)
8target_link_libraries(noise sfml-graphics) 8target_link_libraries(noise sfml-graphics)
9target_compile_features(noise PRIVATE cxx_std_17) 9target_compile_features(noise PRIVATE cxx_std_17)
10file(COPY_FILE 10configure_file(OpenSans-Regular.ttf OpenSans.ttf COPYONLY)
11 ${CMAKE_CURRENT_SOURCE_DIR}/OpenSans-Regular.ttf
12 ${CMAKE_CURRENT_BINARY_DIR}/OpenSans.ttf
13 ONLY_IF_DIFFERENT
14)
diff --git a/README.md b/README.md
index 6d021ae..0056553 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,9 @@
2Texture generation. 2Texture generation.
3 3
4## Requirements 4## Requirements
5- SFML 5- CMake >= 3.8
6- SFML >= 2
7- C++ compiler with C++17 support
6 8
7## Build instructions 9## Build instructions
8``` 10```
diff --git a/TODO.md b/TODO.md
index 7d97ad6..c9f92f6 100644
--- a/TODO.md
+++ b/TODO.md
@@ -1,4 +1,4 @@
1Todo list 1Todo list
2========= 2=========
3- Split app and functions into files. 3- Split app and functions into files.
4- Add brush class - virtual getColor(int i, int j). 4- CMake check for filesystem vs. experimental/filesystem.
diff --git a/brush.cc b/brush.cc
new file mode 100644
index 0000000..cb9a5b9
--- /dev/null
+++ b/brush.cc
@@ -0,0 +1,46 @@
1#include "brush.h"
2
3namespace {
4static bool in_range(const sf::Vector2u& size, const sf::Vector2u& v) {
5 return v.x < size.x && v.y < size.y;
6}
7} // namespace
8
9sf::Color FuncBlur::getColor(const sf::Image& im, unsigned i,
10 unsigned j) const {
11 int radius = 3;
12 float sum = 0.0;
13 sf::Uint16 r = 0, g = 0, b = 0, a = 0;
14 for (int di = -radius; di <= radius; ++di) {
15 for (int dj = -radius; dj <= radius; ++dj) {
16 sf::Vector2u v(i + di, j + dj);
17 if (in_range(im.getSize(), v)) {
18 sf::Color c = im.getPixel(v.x, v.y);
19 float w = weight(di, dj);
20 r += c.r * w;
21 g += c.g * w;
22 b += c.b * w;
23 a += c.a * w;
24 sum += w;
25 }
26 }
27 }
28 return sf::Color(r / sum, g / sum, b / sum, a / sum);
29}
30sf::Color ListBlur::getColor(const sf::Image& im, unsigned i,
31 unsigned j) const {
32 float sum = 0.0;
33 sf::Uint16 r = 0, g = 0, b = 0, a = 0;
34 for (const Info& in : weights) {
35 sf::Vector2u v(i + in.di, j + in.dj);
36 if (in_range(im.getSize(), v)) {
37 sf::Color c = im.getPixel(v.x, v.y);
38 r += c.r * in.weight;
39 g += c.g * in.weight;
40 b += c.b * in.weight;
41 a += c.a * in.weight;
42 sum += in.weight;
43 }
44 }
45 return sf::Color(r / sum, g / sum, b / sum, a / sum);
46}
diff --git a/brush.h b/brush.h
new file mode 100644
index 0000000..62a06b4
--- /dev/null
+++ b/brush.h
@@ -0,0 +1,38 @@
1#include <vector>
2
3#include <SFML/Graphics.hpp>
4
5#ifndef NOISE_BRUSH_H_
6#define NOISE_BRUSH_H_
7
8class BlurBrush {
9 virtual sf::Color getColor(const sf::Image &im, unsigned i, unsigned j) const = 0;
10 public:
11 sf::Color operator()(const sf::Image &im, unsigned i, unsigned j) const {
12 return getColor(im, i, j);
13 }
14};
15
16
17class FuncBlur : public BlurBrush {
18 sf::Color getColor(const sf::Image &im, unsigned i, unsigned j) const;
19 virtual float weight (int di, int dj) const = 0;
20};
21
22
23class ListBlur : public BlurBrush {
24 sf::Color getColor(const sf::Image &im, unsigned i, unsigned j) const;
25 public:
26 struct Info {
27 int di, dj;
28 float weight;
29 Info (int di_, int dj_, float w): di(di_), dj(dj_), weight(w) {}
30 };
31
32 ListBlur(const std::vector<Info> &w) : weights(w) {}
33
34 private:
35 std::vector<Info> weights;
36};
37
38#endif // NOISE_BRUSH_H_
diff --git a/brushes.h b/brushes.h
new file mode 100644
index 0000000..7018a55
--- /dev/null
+++ b/brushes.h
@@ -0,0 +1,10 @@
1#include "brush.h"
2
3#ifndef NOISE_BRUSHES_H_
4#define NOISE_BRUSHES_H_
5
6namespace brushes {
7 ListBlur CardinalAverage({{0, 0, 1}, {1, 0, 1}, {0, 1, 1}, {-1, 0, 1}, {0, -1, 1}});
8}
9
10#endif // NOISE_BRUSHES_H_ \ No newline at end of file
diff --git a/noise.cpp b/noise.cc
index 2b2279d..b5651e8 100644
--- a/noise.cpp
+++ b/noise.cc
@@ -6,6 +6,8 @@
6 6
7#include <SFML/Graphics.hpp> 7#include <SFML/Graphics.hpp>
8 8
9#include "brushes.h"
10
9namespace fs = std::filesystem; 11namespace fs = std::filesystem;
10 12
11namespace { 13namespace {
@@ -19,7 +21,7 @@ sf::Color random_color() {
19 engine.seed(std::random_device{}()); 21 engine.seed(std::random_device{}());
20 seeded = true; 22 seeded = true;
21 } 23 }
22#define COLOR_MODE 4 24#define COLOR_MODE 2
23#if (COLOR_MODE == 1) 25#if (COLOR_MODE == 1)
24 sf::Color c = sf::Color(color_dist(engine)); 26 sf::Color c = sf::Color(color_dist(engine));
25 c.a = 255; 27 c.a = 255;
@@ -103,14 +105,14 @@ void noise(sf::Image& im, int mode) {
103 im3.create(im.getSize().x * 2, im.getSize().y * 2); 105 im3.create(im.getSize().x * 2, im.getSize().y * 2);
104 for (unsigned i = 0; i < im2.getSize().x; ++i) { 106 for (unsigned i = 0; i < im2.getSize().x; ++i) {
105 for (unsigned j = 0; j < im2.getSize().y; ++j) { 107 for (unsigned j = 0; j < im2.getSize().y; ++j) {
106 im3.setPixel(i, j, avg_card(im2, i, j)); 108 im3.setPixel(i, j, brushes::CardinalAverage(im2, i, j));
107 } 109 }
108 } 110 }
109 } else if (mode == 2) { 111 } else if (mode == 2) {
110 im3.create(im.getSize().x, im.getSize().y); 112 im3.create(im.getSize().x, im.getSize().y);
111 for (unsigned i = 0; i < im.getSize().x; ++i) { 113 for (unsigned i = 0; i < im.getSize().x; ++i) {
112 for (unsigned j = 0; j < im.getSize().y; ++j) { 114 for (unsigned j = 0; j < im.getSize().y; ++j) {
113 im3.setPixel(i, j, avg_card(im, i, j)); 115 im3.setPixel(i, j, brushes::CardinalAverage(im, i, j));
114 } 116 }
115 } 117 }
116 } else if (mode == 3) { 118 } else if (mode == 3) {