textures_screen_buffer.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. /*******************************************************************************************
  2. *
  3. * raylib [textures] example - screen buffer
  4. *
  5. * Example complexity rating: [★★☆☆] 2/4
  6. *
  7. * Example originally created with raylib 5.5, last time updated with raylib 5.5
  8. *
  9. * Example contributed by Agnis Aldiņš (@nezvers) and reviewed by Ramon Santamaria (@raysan5)
  10. *
  11. * Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
  12. * BSD-like license that allows static linking with closed source software
  13. *
  14. * Copyright (c) 2025 Agnis Aldiņš (@nezvers)
  15. *
  16. ********************************************************************************************/
  17. #include "raylib.h"
  18. #include <stdlib.h> // Required for: calloc(), free()
  19. #define MAX_COLORS 256
  20. #define SCALE_FACTOR 2
  21. //------------------------------------------------------------------------------------
  22. // Program main entry point
  23. //------------------------------------------------------------------------------------
  24. int main(void)
  25. {
  26. // Initialization
  27. //--------------------------------------------------------------------------------------
  28. const int screenWidth = 800;
  29. const int screenHeight = 450;
  30. InitWindow(screenWidth, screenHeight, "raylib [textures] example - screen buffer");
  31. int imageWidth = screenWidth/SCALE_FACTOR;
  32. int imageHeight = screenHeight/SCALE_FACTOR;
  33. int flameWidth = screenWidth/SCALE_FACTOR;
  34. Color palette[MAX_COLORS] = { 0 };
  35. unsigned char *indexBuffer = RL_CALLOC(imageWidth*imageWidth, sizeof(unsigned char));
  36. unsigned char *flameRootBuffer = RL_CALLOC(flameWidth, sizeof(unsigned char));
  37. Image screenImage = GenImageColor(imageWidth, imageHeight, BLACK);
  38. Texture screenTexture = LoadTextureFromImage(screenImage);
  39. // Generate flame color palette
  40. for (int i = 0; i < MAX_COLORS; i++)
  41. {
  42. float t = (float)i/(float)(MAX_COLORS - 1);
  43. float hue = t*t;
  44. float saturation = t;
  45. float value = t;
  46. palette[i] = ColorFromHSV(250.0f + 150.0f*hue, saturation, value);
  47. }
  48. SetTargetFPS(60);
  49. //--------------------------------------------------------------------------------------
  50. // Main game loop
  51. while (!WindowShouldClose()) // Detect window close button or ESC key
  52. {
  53. // Update
  54. //----------------------------------------------------------------------------------
  55. // Grow flameRoot
  56. for (int x = 2; x < flameWidth; x++)
  57. {
  58. unsigned short flame = flameRootBuffer[x];
  59. if (flame == 255) continue;
  60. flame += GetRandomValue(0, 2);
  61. if (flame > 255) flame = 255;
  62. flameRootBuffer[x] = flame;
  63. }
  64. // Transfer flameRoot to indexBuffer
  65. for (int x = 0; x < flameWidth; x++)
  66. {
  67. int i = x + (imageHeight - 1)*imageWidth;
  68. indexBuffer[i] = flameRootBuffer[x];
  69. }
  70. // Clear top row, because it can't move any higher
  71. for (int x = 0; x < imageWidth; x++)
  72. {
  73. if (indexBuffer[x] == 0) continue;
  74. indexBuffer[x] = 0;
  75. }
  76. // Skip top row, it is already cleared
  77. for (int y = 1; y < imageHeight; y++)
  78. {
  79. for (int x = 0; x < imageWidth; x++)
  80. {
  81. unsigned int i = x + y*imageWidth;
  82. unsigned char colorIndex = indexBuffer[i];
  83. if (colorIndex == 0) continue;
  84. // Move pixel a row above
  85. indexBuffer[i] = 0;
  86. int moveX = GetRandomValue(0, 2) - 1;
  87. int newX = x + moveX;
  88. if (newX < 0 || newX >= imageWidth) continue;
  89. unsigned int iabove = i - imageWidth + moveX;
  90. int decay = GetRandomValue(0, 3);
  91. colorIndex -= (decay < colorIndex)? decay : colorIndex;
  92. indexBuffer[iabove] = colorIndex;
  93. }
  94. }
  95. // Update screenImage with palette colors
  96. for (int y = 1; y < imageHeight; y++)
  97. {
  98. for (int x = 0; x < imageWidth; x++)
  99. {
  100. unsigned int i = x + y*imageWidth;
  101. unsigned char colorIndex = indexBuffer[i];
  102. Color col = palette[colorIndex];
  103. ImageDrawPixel(&screenImage, x, y, col);
  104. }
  105. }
  106. UpdateTexture(screenTexture, screenImage.data);
  107. //----------------------------------------------------------------------------------
  108. // Draw
  109. //----------------------------------------------------------------------------------
  110. BeginDrawing();
  111. ClearBackground(RAYWHITE);
  112. DrawTextureEx(screenTexture, (Vector2){ 0, 0 }, 0.0f, 2.0f, WHITE);
  113. EndDrawing();
  114. //----------------------------------------------------------------------------------
  115. }
  116. // De-Initialization
  117. //--------------------------------------------------------------------------------------
  118. RL_FREE(indexBuffer);
  119. RL_FREE(flameRootBuffer);
  120. UnloadTexture(screenTexture);
  121. UnloadImage(screenImage);
  122. CloseWindow(); // Close window and OpenGL context
  123. //--------------------------------------------------------------------------------------
  124. return 0;
  125. }