fork download
  1. #include <SFML/Graphics.hpp>
  2. #include <algorithm>
  3. #include <vector>
  4. #include <map>
  5. #include <cstdlib>
  6. #include <ctime>
  7. #include <cmath>
  8.  
  9. void noise(sf::Image & image) {
  10.  
  11. sf::Vector2u imageSize = image.getSize() ;
  12.  
  13. for (unsigned i = 0; i < imageSize.x; ++ i) {
  14. for (unsigned j = 0; j < imageSize.y; ++ j) {
  15.  
  16. int val = std::rand() % 256;
  17.  
  18. image.setPixel(i, j, sf::Color(val, val, val));
  19. }
  20. }
  21. }
  22.  
  23. void wall(sf::Image & image, bool cool) {
  24.  
  25. std::map<int, int> interiorId2offset;
  26.  
  27. const sf::Vector2u imageSize = image.getSize() ;
  28.  
  29. for (unsigned i = 0; i < imageSize.x ; ++ i) {
  30. for (unsigned j = 0; j < imageSize.y; ++ j) {
  31.  
  32. int val = 0;
  33. int offset = 0;
  34.  
  35. if (j % 128 < 64) offset = 40;
  36.  
  37. bool one = ((i + offset) % 128 < 2 || (i + offset) % 128 > 126);
  38. bool two = ( j % 64 < 2 || j % 64 > 62);
  39.  
  40. bool nearOne = (i % 128 < 8 || i % 128 > 120);
  41. bool nearTwo = (j % 64 < 8 || j % 64 > 56);
  42.  
  43. if (one && !nearTwo || two && !nearOne) val = 225;
  44.  
  45. bool interior = !one && !two;
  46.  
  47. if (interior) {
  48.  
  49. unsigned x = (i + offset) / 128;
  50. unsigned y = j / 64;
  51.  
  52. if (x >= imageSize.x / 128) x = 0; // in order to be tileable
  53.  
  54. int interiorOffset = interiorId2offset[x + 100 * y];
  55.  
  56. if (interiorOffset == 0) {
  57.  
  58. interiorOffset = std::rand() % 3 * 30 + 1;
  59. interiorId2offset[x + 100 * y] = interiorOffset;
  60. }
  61.  
  62. val = ((i + offset) % 128 + j % 64 + interiorOffset) % 256;
  63.  
  64. if (val < 25) val = 25;
  65. if (val > 175) val = 175;
  66. }
  67.  
  68. if (cool) val = (val + std::rand() % 15 + 35) % 256;
  69.  
  70. image.setPixel(i, j, sf::Color(val, val, val));
  71. }
  72. }
  73. }
  74.  
  75. void whiteDrops(sf::Image & image, int count, int minSize, int maxSize, bool filled = true, int thickness = 0) {
  76.  
  77. const sf::Vector2u imageSize = image.getSize() ;
  78.  
  79. for (int i = 0; i < count; ++ i) {
  80.  
  81. int cx = std::rand() % imageSize.x;
  82. int cy = std::rand() % imageSize.y;
  83.  
  84. int size = std::rand() % (maxSize - minSize + 1) + minSize;
  85.  
  86. for (int x = cx - size; x <= cx + size; ++ x) {
  87. for (int y = cy - size; y <= cy + size; ++ y) {
  88.  
  89. int d2 = (x - cx) * (x - cx) + (y - cy) * (y - cy);
  90. int s2 = size * size;
  91.  
  92. if (d2 <= s2) {
  93.  
  94. int px = (x % imageSize.x + imageSize.x) % imageSize.x;
  95. int py = (y % imageSize.y + imageSize.y) % imageSize.y;
  96.  
  97. if (d2 <= s2 - thickness) {
  98. if (filled)
  99. image.setPixel(px, py, sf::Color::Black);
  100. } else {
  101. image.setPixel(px, py, sf::Color::White);
  102. }
  103. }
  104. }
  105. }
  106. }
  107. }
  108.  
  109. void bit(sf::Image & image, int a, int b, int c) {
  110.  
  111. const sf::Vector2u imageSize = image.getSize() ;
  112.  
  113. for (unsigned i = 0; i < imageSize.x; ++ i) {
  114. for (unsigned j = 0; j < imageSize.y; ++ j) {
  115.  
  116. int val = (a * (i & j) + b * (i ^ j) + c * (i | j)) % 256;
  117.  
  118. image.setPixel(i, j, sf::Color(val, val, val));
  119. }
  120. }
  121. }
  122.  
  123. void median(sf::Image & image, int size, bool red = true, bool green = true, bool blue = true) {
  124.  
  125. sf::Image image2(image);
  126.  
  127. const sf::Vector2u imageSize = image.getSize() ;
  128.  
  129. for (unsigned i = 0; i < imageSize.x; ++ i) {
  130. for (unsigned j = 0; j < imageSize.y; ++ j) {
  131.  
  132. std::vector<int> rs, gs, bs;
  133.  
  134. sf::Color c;
  135.  
  136. for (int x = -size; x <= size; ++ x) {
  137. for (int y = -size; y <= size; ++ y) {
  138.  
  139. int a = ((x + i) % imageSize.x + imageSize.x) % imageSize.x;
  140. int b = ((y + j) % imageSize.y + imageSize.y) % imageSize.y;
  141.  
  142. c = image2.getPixel(a, b);
  143.  
  144. rs.push_back(c.r);
  145. gs.push_back(c.g);
  146. bs.push_back(c.b);
  147. }
  148. }
  149.  
  150. c = image2.getPixel(i, j);
  151.  
  152. if (red) {
  153. std::sort(rs.begin(), rs.end());
  154. c.r = rs[rs.size() / 2];
  155. }
  156.  
  157. if (green) {
  158. std::sort(gs.begin(), gs.end());
  159. c.g = gs[gs.size() / 2];
  160. }
  161.  
  162. if (blue) {
  163. std::sort(bs.begin(), bs.end());
  164. c.b = bs[bs.size() / 2];
  165. }
  166.  
  167. image.setPixel(i, j, c);
  168. }
  169. }
  170. }
  171.  
  172. void blend(sf::Image & dest, sf::Image source1, sf::Image source2, int w1, int w2) {
  173.  
  174. const sf::Vector2u destSize = dest.getSize() ;
  175.  
  176. for (unsigned i = 0; i < destSize.x ; ++ i) {
  177. for (unsigned j = 0; j < destSize.y ; ++ j) {
  178.  
  179. int r = 0, g = 0, b = 0;
  180.  
  181. sf::Color p1 = source1.getPixel(i, j);
  182. sf::Color p2 = source2.getPixel(i, j);
  183.  
  184. r += w1 * p1.r;
  185. r += w2 * p2.r;
  186.  
  187. g += w1 * p1.g;
  188. g += w2 * p2.g;
  189.  
  190. b += w1 * p1.b;
  191. b += w2 * p2.b;
  192.  
  193. r /= (w1 + w2);
  194. g /= (w1 + w2);
  195. b /= (w1 + w2);
  196.  
  197. dest.setPixel(i, j, sf::Color(r, g, b));
  198. }
  199. }
  200. }
  201.  
  202. void pixelize(sf::Image & image, int size) {
  203.  
  204. const sf::Vector2u imageSize = image.getSize() ;
  205.  
  206. sf::Image image2(image);
  207.  
  208. for (unsigned i = 0; i < imageSize.x; i += size) {
  209. for (unsigned j = 0; j < imageSize.y; j += size) {
  210.  
  211. sf::Color curColor = image2.getPixel(i, j);
  212.  
  213. for (int x = 0; x < size; ++ x) {
  214. for (int y = 0; y < size; ++ y) {
  215.  
  216. int a = ((x + i) % imageSize.x + imageSize.x) % imageSize.x;
  217. int b = ((y + j) % imageSize.y + imageSize.y) % imageSize.y;
  218.  
  219. image.setPixel(a, b, curColor);
  220. }
  221. }
  222. }
  223. }
  224. }
  225.  
  226. void magnifyingDrops(sf::Image & image, int count, int minSize, int maxSize, double exponent) {
  227.  
  228. const sf::Vector2u imageSize = image.getSize() ;
  229.  
  230. sf::Image image2(image);
  231.  
  232. for (int i = 0; i < count; ++ i) {
  233.  
  234. int cx = std::rand() % imageSize.x;
  235. int cy = std::rand() % imageSize.y;
  236.  
  237. int size = std::rand() % (maxSize - minSize + 1) + minSize;
  238.  
  239. int s2 = size * size;
  240.  
  241. double m = std::pow(size, 1 - exponent);
  242.  
  243. for (int x = - size; x <= size; ++ x) {
  244. for (int y = - size; y <= size; ++ y) {
  245.  
  246. int signx = x < 0 ? -1 : 1;
  247. int signy = y < 0 ? -1 : 1;
  248.  
  249. int d2 = x * x + y * y;
  250.  
  251. if (d2 > s2) continue;
  252.  
  253. int sx = (int(cx + signx * std::pow(signx * x, exponent) * m) % imageSize.x + imageSize.x) % imageSize.x;
  254. int sy = (int(cy + signy * std::pow(signy * y, exponent) * m) % imageSize.y + imageSize.y) % imageSize.y;
  255.  
  256. int tx = ((cx + x) % imageSize.x + imageSize.x) % imageSize.x;
  257. int ty = ((cy + y) % imageSize.y + imageSize.y) % imageSize.y;
  258.  
  259. image.setPixel(tx, ty, image2.getPixel(sx, sy));
  260. }
  261. }
  262. }
  263. }
  264.  
  265. int main()
  266. {
  267. std::srand(static_cast<unsigned>(std::time(0)));
  268.  
  269. const int width = 512;
  270. const int height = 256;
  271.  
  272. sf::Image txt_bit;
  273. sf::Image txt_wall;
  274. sf::Image txt_noise;
  275. sf::Image txt_drops;
  276. sf::Image txt_result;
  277.  
  278. txt_bit.create(width, height, sf::Color::Black) ;
  279. txt_wall.create(width, height, sf::Color::Black) ;
  280. txt_noise.create(width, height, sf::Color::Black) ;
  281. txt_drops.create(width, height, sf::Color::Black) ;
  282. txt_result.create(width, height, sf::Color::Black) ;
  283.  
  284. //txt_bit.setSmooth(false);
  285. //txt_wall.SetSmooth(false);
  286. //txt_noise.SetSmooth(false);
  287. //txt_drops.SetSmooth(false);
  288. //txt_result.SetSmooth(false);
  289.  
  290. /*
  291.   bit(txt_bit, 16, 64, 32);
  292.   median(txt_bit, 2);
  293.   //*/
  294.  
  295. /*
  296.   bit(txt_bit, 32, 64, 16);
  297.   median(txt_bit, 2);
  298.   //*/
  299.  
  300. /*
  301.   bit(txt_bit, 64, 32, 16);
  302.   median(txt_bit, 2);
  303.   //*/
  304.  
  305. /*
  306.   bit(txt_bit, 4, 8, 16);
  307.   median(txt_bit, 1);
  308.   median(txt_bit, 1);
  309.   //*/
  310.  
  311. /*
  312.   bit(txt_bit, 16, 8, 16);
  313.   median(txt_bit, 1);
  314.   median(txt_bit, 1);
  315.   //*/
  316.  
  317. /*
  318.   bit(txt_bit, 15, 16, 17);
  319.   median(txt_bit, 1);
  320.   median(txt_bit, 1);
  321.   median(txt_bit, 1);
  322.   //*/
  323.  
  324. ///*
  325. bit(txt_bit, 35, 70, 140);
  326. median(txt_bit, 1);
  327. median(txt_bit, 2);
  328. //*/
  329.  
  330. wall(txt_wall, true);
  331. noise(txt_noise);
  332. whiteDrops(txt_drops, 250, 40, 80, false, 125);
  333. blend(txt_result, txt_drops, txt_noise, 15, 5);
  334. median(txt_result, 1);
  335. blend(txt_result, txt_wall, txt_result, 13, 2);
  336. magnifyingDrops(txt_result, 10, 40, 50, 1.15);
  337. pixelize(txt_result, 4);
  338.  
  339. sf::Texture resultTexture ;
  340. resultTexture.loadFromImage(txt_result) ;
  341. resultTexture.setSmooth(true) ;
  342. sf::Sprite sprite(resultTexture);
  343.  
  344.  
  345. //pixelize(txt_bit, 2);
  346. //sf::Sprite sprite(txt_bit);
  347.  
  348. sf::RenderWindow window(sf::VideoMode(width * 2, height * 2, 32), "Procedural Textures!");
  349.  
  350. window.setVerticalSyncEnabled(true);
  351.  
  352. bool Running = true;
  353.  
  354. while (Running)
  355. {
  356. sf::Event Event;
  357.  
  358. while (window.pollEvent(Event))
  359. {
  360. if (Event.type == sf::Event::Closed)
  361. Running = false;
  362.  
  363. if ((Event.type == sf::Event::KeyPressed) && (Event.key.code == sf::Keyboard::Escape))
  364. Running = false;
  365. }
  366.  
  367.  
  368. window.clear();
  369.  
  370. window.draw(sprite);
  371. sprite.move(static_cast<float>(width), 0.0f);
  372. window.draw(sprite);
  373. sprite.move(0.0f, static_cast<float>(height));
  374. window.draw(sprite);
  375. sprite.move(static_cast<float>(- width), 0.0f);
  376. window.draw(sprite);
  377. sprite.move(0.0f, static_cast<float>(- height));
  378.  
  379. window.display();
  380. }
  381. }
Not running #stdin #stdout 0s 0KB
stdin
Standard input is empty
stdout
Standard output is empty