227 wiersze
6.6 KiB

  1. //
  2. // Lol Engine - Fractal tutorial
  3. //
  4. // Copyright: (c) 2011 Sam Hocevar <sam@hocevar.net>
  5. // This program is free software; you can redistribute it and/or
  6. // modify it under the terms of the Do What The Fuck You Want To
  7. // Public License, Version 2, as published by Sam Hocevar. See
  8. // http://sam.zoy.org/projects/COPYING.WTFPL for more details.
  9. //
  10. #if defined HAVE_CONFIG_H
  11. # include "config.h"
  12. #endif
  13. #include <cstring>
  14. #include "core.h"
  15. #include "lolgl.h"
  16. #include "loldebug.h"
  17. using namespace std;
  18. using namespace lol;
  19. #if USE_SDL && defined __APPLE__
  20. # include <SDL_main.h>
  21. #endif
  22. #if defined _WIN32
  23. # undef main /* FIXME: still needed? */
  24. # include <direct.h>
  25. #endif
  26. class Fractal : public WorldEntity
  27. {
  28. public:
  29. Fractal(ivec2 const &size)
  30. {
  31. m_size = size;
  32. m_pixels = new u8vec4[size.x * size.y];
  33. m_angle = 0.0f;
  34. m_ready = false;
  35. }
  36. ~Fractal()
  37. {
  38. delete m_pixels;
  39. }
  40. virtual void TickGame(float deltams)
  41. {
  42. WorldEntity::TickGame(deltams);
  43. m_angle += deltams * 0.0005f;
  44. cmplx r0(cosf(m_angle), sinf(m_angle));
  45. for (int j = 0; j < m_size.y; j++)
  46. for (int i = 0; i < m_size.x; i++)
  47. {
  48. float const maxlen = 128.0f;
  49. int const maxiter = 20;
  50. cmplx x0(4.0f / m_size.x * i - 2.5f, 3.0f / m_size.y * j - 1.5f);
  51. cmplx r = x0;
  52. cmplx z;
  53. int iter = maxiter;
  54. for (z = r; iter && z.sqlen() < maxlen * maxlen; z = z * z + r)
  55. --iter;
  56. float f = iter;
  57. float n = z.len();
  58. f += logf(logf(n) / logf(maxlen)) / logf(2.0f);
  59. if (iter)
  60. {
  61. uint8_t red = 255 - f * 11;
  62. uint8_t green = 255 - f * 11;
  63. uint8_t blue = (f * 23 > 255) ? 511 - f * 23 : 255;
  64. m_pixels[j * m_size.x + i] = u8vec4(red, green, blue, 0);
  65. }
  66. else
  67. {
  68. m_pixels[j * m_size.x + i] = u8vec4(0, 0, 0, 0);
  69. }
  70. }
  71. }
  72. virtual void TickDraw(float deltams)
  73. {
  74. WorldEntity::TickDraw(deltams);
  75. static float const vertices[] =
  76. {
  77. -1.0f, -1.0f,
  78. 1.0f, -1.0f,
  79. 1.0f, 1.0f,
  80. 1.0f, 1.0f,
  81. -1.0f, 1.0f,
  82. -1.0f, -1.0f,
  83. };
  84. static float const texcoords[] =
  85. {
  86. 0.0f, 0.0f,
  87. 1.0f, 0.0f,
  88. 1.0f, 1.0f,
  89. 1.0f, 1.0f,
  90. 0.0f, 1.0f,
  91. 0.0f, 0.0f,
  92. };
  93. if (!m_ready)
  94. {
  95. glGenTextures(1, &m_texid);
  96. glBindTexture(GL_TEXTURE_2D, m_texid);
  97. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_size.x, m_size.y, 0,
  98. GL_RGBA, GL_UNSIGNED_BYTE, m_pixels);
  99. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  100. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  101. m_shader = Shader::Create(
  102. "#version 120\n"
  103. "attribute vec2 in_TexCoord;\n"
  104. "attribute vec2 in_Vertex;"
  105. "void main(void) {"
  106. " gl_Position = vec4(in_Vertex, 0.0, 1.0);"
  107. " gl_TexCoord[0] = vec4(in_TexCoord, 0.0, 0.0);\n"
  108. "}",
  109. "#version 120\n"
  110. "uniform sampler2D in_Texture;\n"
  111. "void main(void) {"
  112. " gl_FragColor = texture2D(in_Texture, gl_TexCoord[0].xy);"
  113. "}");
  114. m_vertexattrib = m_shader->GetAttribLocation("in_Vertex");
  115. m_texattrib = m_shader->GetAttribLocation("in_TexCoord");
  116. m_ready = true;
  117. #if !defined __CELLOS_LV2__ && !defined __ANDROID__ && !defined __APPLE__
  118. /* Method 1: store vertex buffer on the GPU memory */
  119. glGenBuffers(1, &m_vbo);
  120. glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
  121. glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices,
  122. GL_STATIC_DRAW);
  123. glGenBuffers(1, &m_tbo);
  124. glBindBuffer(GL_ARRAY_BUFFER, m_tbo);
  125. glBufferData(GL_ARRAY_BUFFER, sizeof(texcoords), texcoords,
  126. GL_STATIC_DRAW);
  127. #elif !defined __CELLOS_LV2__ && !defined __ANDROID__ && !defined __APPLE__
  128. /* Method 2: upload vertex information at each frame */
  129. #else
  130. #endif
  131. /* FIXME: this object never cleans up */
  132. }
  133. glEnable(GL_TEXTURE_2D);
  134. glBindTexture(GL_TEXTURE_2D, m_texid);
  135. glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, m_size.x, m_size.y,
  136. GL_RGBA, GL_UNSIGNED_BYTE, m_pixels);
  137. m_shader->Bind();
  138. #if !defined __CELLOS_LV2__ && !defined __ANDROID__ && !defined __APPLE__
  139. glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
  140. glEnableVertexAttribArray(m_vertexattrib);
  141. glVertexAttribPointer(m_vertexattrib, 2, GL_FLOAT, GL_FALSE, 0, 0);
  142. glBindBuffer(GL_ARRAY_BUFFER, m_tbo);
  143. glEnableVertexAttribArray(m_texattrib);
  144. glVertexAttribPointer(m_texattrib, 2, GL_FLOAT, GL_FALSE, 0, 0);
  145. #elif !defined __CELLOS_LV2__ && !defined __ANDROID__ && !defined __APPLE__
  146. /* Never used for now */
  147. //glEnableVertexAttribArray(m_vertexattrib);
  148. //glVertexAttribPointer(m_vertexattrib, 2, GL_FLOAT, GL_FALSE, 0, vertices);
  149. #else
  150. //glEnableClientState(GL_VERTEX_ARRAY);
  151. //glVertexPointer(2, GL_FLOAT, 0, vertices);
  152. //glEnableClientState(GL_VERTEX_ARRAY);
  153. //glTexCoordPointer(2, GL_FLOAT, 0, texcoords);
  154. #endif
  155. glDrawArrays(GL_TRIANGLES, 0, 6);
  156. #if !defined __CELLOS_LV2__ && !defined __ANDROID__ && !defined __APPLE__
  157. glDisableVertexAttribArray(m_vertexattrib);
  158. glDisableVertexAttribArray(m_texattrib);
  159. glBindBuffer(GL_ARRAY_BUFFER, 0);
  160. #elif !defined __CELLOS_LV2__ && !defined __ANDROID__ && !defined __APPLE__
  161. /* Never used for now */
  162. //glDisableVertexAttribArray(m_vertexattrib);
  163. //glDisableVertexAttribArray(m_texattrib);
  164. #else
  165. //glDisableClientState(GL_VERTEX_ARRAY);
  166. //glDisableClientState(GL_TEXTURE_COORD_ARRAY);
  167. #endif
  168. }
  169. private:
  170. ivec2 m_size;
  171. u8vec4 *m_pixels;
  172. Shader *m_shader;
  173. GLuint m_texid;
  174. #if !defined __CELLOS_LV2__ && !defined __ANDROID__ && !defined __APPLE__
  175. GLuint m_vbo, m_tbo;
  176. GLuint m_tco;
  177. #endif
  178. int m_vertexattrib, m_texattrib;
  179. float m_angle;
  180. bool m_ready;
  181. };
  182. int main()
  183. {
  184. #if defined _WIN32
  185. _chdir("../..");
  186. #endif
  187. Application app("Tutorial 3: Fractal", ivec2(640, 480), 60.0f);
  188. new DebugFps(5, 5);
  189. new Fractal(ivec2(640, 480));
  190. app.Run();
  191. return EXIT_SUCCESS;
  192. }