You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

225 lines
6.7 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 TickDraw(float deltams)
  41. {
  42. WorldEntity::TickDraw(deltams);
  43. static float const vertices[] =
  44. {
  45. -1.0f, -1.0f,
  46. 1.0f, -1.0f,
  47. 1.0f, 1.0f,
  48. 1.0f, 1.0f,
  49. -1.0f, 1.0f,
  50. -1.0f, -1.0f,
  51. };
  52. static float const texcoords[] =
  53. {
  54. 0.0f, 0.0f,
  55. 1.0f, 0.0f,
  56. 1.0f, 1.0f,
  57. 1.0f, 1.0f,
  58. 0.0f, 1.0f,
  59. 0.0f, 0.0f,
  60. };
  61. if (!m_ready)
  62. {
  63. glGenTextures(1, &m_texid);
  64. glBindTexture(GL_TEXTURE_2D, m_texid);
  65. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_size.x, m_size.y, 0,
  66. GL_RGBA, GL_UNSIGNED_BYTE, m_pixels);
  67. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  68. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  69. m_shader = Shader::Create(
  70. "#version 120\n"
  71. "attribute vec2 in_TexCoord;\n"
  72. "attribute vec2 in_Vertex;"
  73. "void main(void) {"
  74. " gl_Position = vec4(in_Vertex, 0.0, 1.0);"
  75. " gl_TexCoord[0] = vec4(in_TexCoord, 0.0, 0.0);\n"
  76. "}",
  77. "#version 120\n"
  78. "uniform sampler2D in_Texture;\n"
  79. "void main(void) {"
  80. " gl_FragColor = texture2D(in_Texture, gl_TexCoord[0].xy);"
  81. "}");
  82. m_vertexattrib = m_shader->GetAttribLocation("in_Vertex");
  83. m_texattrib = m_shader->GetAttribLocation("in_TexCoord");
  84. m_ready = true;
  85. #if !defined __CELLOS_LV2__ && !defined __ANDROID__ && !defined __APPLE__
  86. /* Method 1: store vertex buffer on the GPU memory */
  87. glGenBuffers(1, &m_vbo);
  88. glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
  89. glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices,
  90. GL_STATIC_DRAW);
  91. glGenBuffers(1, &m_tbo);
  92. glBindBuffer(GL_ARRAY_BUFFER, m_tbo);
  93. glBufferData(GL_ARRAY_BUFFER, sizeof(texcoords), texcoords,
  94. GL_STATIC_DRAW);
  95. #elif !defined __CELLOS_LV2__ && !defined __ANDROID__ && !defined __APPLE__
  96. /* Method 2: upload vertex information at each frame */
  97. #else
  98. #endif
  99. /* FIXME: this object never cleans up */
  100. }
  101. m_angle += deltams * 0.0001f;
  102. cmplx r0(cosf(m_angle), 0.5f * sinf(m_angle));
  103. for (int j = 0; j < m_size.y; j++)
  104. for (int i = 0; i < m_size.x; i++)
  105. {
  106. cmplx x0(4.0f / m_size.x * i - 2.5f, 3.0f / m_size.y * j - 1.5f);
  107. cmplx r = x0 * r0;
  108. cmplx z;
  109. int iter = 20;
  110. for (z = r; iter && z.sqlen() < 4.0f; z = z * z + r)
  111. --iter;
  112. float f = iter;
  113. float n = z.sqlen();
  114. if (n > 36.0f)
  115. f += 2.0f;
  116. if (n > 16.0f)
  117. f += 1.0f + (n - 16.0f) / 20.0f;
  118. else if (n > 4.0f)
  119. f += (n - 4.0f) / 12.0f;
  120. if (iter)
  121. {
  122. uint8_t red = 255 - f * 11;
  123. uint8_t green = 255 - f * 11;
  124. uint8_t blue = (f * 23 > 255) ? 511 - f * 23 : 255;
  125. //uint8_t blue = f * 36 < 255 ? f * 36 : 255;
  126. m_pixels[j * m_size.x + i] = u8vec4(red, green, blue, 0);
  127. }
  128. else
  129. {
  130. m_pixels[j * m_size.x + i] = u8vec4(0, 0, 0, 0);
  131. }
  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. }