diff options
| author | Aiden Woodruff <aiden.woodruff@gmail.com> | 2023-11-29 22:14:48 -0500 |
|---|---|---|
| committer | Aiden Woodruff <aiden.woodruff@gmail.com> | 2023-11-29 22:14:48 -0500 |
| commit | 3e55710755603c0236191ee95fe6f54bc4124c8f (patch) | |
| tree | 78002d798b8b43c838093803c6568fa183020ab4 | |
| parent | ba891ea777d9495bb584c7dab1c7871c494e50b2 (diff) | |
| download | noise-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.txt | 8 | ||||
| -rw-r--r-- | README.md | 4 | ||||
| -rw-r--r-- | TODO.md | 2 | ||||
| -rw-r--r-- | brush.cc | 46 | ||||
| -rw-r--r-- | brush.h | 38 | ||||
| -rw-r--r-- | brushes.h | 10 | ||||
| -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 | ||
| 5 | find_package(SFML COMPONENTS graphics REQUIRED) | 5 | find_package(SFML COMPONENTS graphics REQUIRED) |
| 6 | 6 | ||
| 7 | add_executable(noise noise.cpp) | 7 | add_executable(noise noise.cc brush.cc) |
| 8 | target_link_libraries(noise sfml-graphics) | 8 | target_link_libraries(noise sfml-graphics) |
| 9 | target_compile_features(noise PRIVATE cxx_std_17) | 9 | target_compile_features(noise PRIVATE cxx_std_17) |
| 10 | file(COPY_FILE | 10 | configure_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 | ) | ||
| @@ -2,7 +2,9 @@ | |||
| 2 | Texture generation. | 2 | Texture 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 | ``` |
| @@ -1,4 +1,4 @@ | |||
| 1 | Todo list | 1 | Todo 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 | |||
| 3 | namespace { | ||
| 4 | static 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 | |||
| 9 | sf::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 | } | ||
| 30 | sf::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 | } | ||
| @@ -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 | |||
| 8 | class 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 | |||
| 17 | class 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 | |||
| 23 | class 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 | |||
| 6 | namespace 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 | ||
| @@ -6,6 +6,8 @@ | |||
| 6 | 6 | ||
| 7 | #include <SFML/Graphics.hpp> | 7 | #include <SFML/Graphics.hpp> |
| 8 | 8 | ||
| 9 | #include "brushes.h" | ||
| 10 | |||
| 9 | namespace fs = std::filesystem; | 11 | namespace fs = std::filesystem; |
| 10 | 12 | ||
| 11 | namespace { | 13 | namespace { |
| @@ -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) { |
