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