198 lines
5.9 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. #endif
  25. class Fractal : public WorldEntity
  26. {
  27. public:
  28. Fractal(ivec2 const &size)
  29. {
  30. m_size = size;
  31. m_pixels = new u8vec4[size.x * size.y];
  32. m_angle = 0.0f;
  33. m_ready = false;
  34. }
  35. ~Fractal()
  36. {
  37. delete m_pixels;
  38. }
  39. virtual void TickDraw(float deltams)
  40. {
  41. WorldEntity::TickDraw(deltams);
  42. static float const vertices[] =
  43. {
  44. -1.0f, -1.0f,
  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. };
  51. static float const texcoords[] =
  52. {
  53. 0.0f, 0.0f,
  54. 1.0f, 0.0f,
  55. 1.0f, 1.0f,
  56. 1.0f, 1.0f,
  57. 0.0f, 1.0f,
  58. 0.0f, 0.0f,
  59. };
  60. if (!m_ready)
  61. {
  62. glGenTextures(1, &m_texid);
  63. glBindTexture(GL_TEXTURE_2D, m_texid);
  64. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_size.x, m_size.y, 0,
  65. GL_RGBA, GL_UNSIGNED_BYTE, m_pixels);
  66. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  67. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  68. m_shader = Shader::Create(
  69. "#version 120\n"
  70. "attribute vec2 in_TexCoord;\n"
  71. "attribute vec2 in_Vertex;"
  72. "void main(void) {"
  73. " gl_Position = vec4(in_Vertex, 0.0, 1.0);"
  74. " gl_TexCoord[0] = vec4(in_TexCoord, 0.0, 0.0);\n"
  75. "}",
  76. "#version 120\n"
  77. "uniform sampler2D in_Texture;\n"
  78. "void main(void) {"
  79. " gl_FragColor = texture2D(in_Texture, gl_TexCoord[0].xy);"
  80. "}");
  81. m_vertexattrib = m_shader->GetAttribLocation("in_Vertex");
  82. m_texattrib = m_shader->GetAttribLocation("in_TexCoord");
  83. m_ready = true;
  84. #if !defined __CELLOS_LV2__ && !defined __ANDROID__ && !defined __APPLE__
  85. /* Method 1: store vertex buffer on the GPU memory */
  86. glGenBuffers(1, &m_vbo);
  87. glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
  88. glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices,
  89. GL_STATIC_DRAW);
  90. glGenBuffers(1, &m_tbo);
  91. glBindBuffer(GL_ARRAY_BUFFER, m_tbo);
  92. glBufferData(GL_ARRAY_BUFFER, sizeof(texcoords), texcoords,
  93. GL_STATIC_DRAW);
  94. #elif !defined __CELLOS_LV2__ && !defined __ANDROID__ && !defined __APPLE__
  95. /* Method 2: upload vertex information at each frame */
  96. #else
  97. #endif
  98. /* FIXME: this object never cleans up */
  99. }
  100. m_angle += deltams * 0.001f;
  101. cmplx r0(cosf(m_angle), 0.3f * sinf(m_angle));
  102. for (int j = 0; j < m_size.y; j++)
  103. for (int i = 0; i < m_size.x; i++)
  104. {
  105. cmplx x0(4.0f / m_size.x * i - 2.5f, 3.0f / m_size.y * j - 1.5f);
  106. cmplx r = x0 * r0;
  107. int iter = 20;
  108. for (cmplx z = r; iter && z.sqlen() < 4.0f; z = z * z + r)
  109. --iter;
  110. m_pixels[j * m_size.x + i] = u8vec4(0, iter * 12, iter * 12, 0);
  111. }
  112. glEnable(GL_TEXTURE_2D);
  113. glBindTexture(GL_TEXTURE_2D, m_texid);
  114. glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, m_size.x, m_size.y,
  115. GL_RGBA, GL_UNSIGNED_BYTE, m_pixels);
  116. m_shader->Bind();
  117. #if !defined __CELLOS_LV2__ && !defined __ANDROID__ && !defined __APPLE__
  118. glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
  119. glEnableVertexAttribArray(m_vertexattrib);
  120. glVertexAttribPointer(m_vertexattrib, 2, GL_FLOAT, GL_FALSE, 0, 0);
  121. glBindBuffer(GL_ARRAY_BUFFER, m_tbo);
  122. glEnableVertexAttribArray(m_texattrib);
  123. glVertexAttribPointer(m_texattrib, 2, GL_FLOAT, GL_FALSE, 0, 0);
  124. #elif !defined __CELLOS_LV2__ && !defined __ANDROID__ && !defined __APPLE__
  125. /* Never used for now */
  126. //glEnableVertexAttribArray(m_vertexattrib);
  127. //glVertexAttribPointer(m_vertexattrib, 2, GL_FLOAT, GL_FALSE, 0, vertices);
  128. #else
  129. //glEnableClientState(GL_VERTEX_ARRAY);
  130. //glVertexPointer(2, GL_FLOAT, 0, vertices);
  131. //glEnableClientState(GL_VERTEX_ARRAY);
  132. //glTexCoordPointer(2, GL_FLOAT, 0, texcoords);
  133. #endif
  134. glDrawArrays(GL_TRIANGLES, 0, 6);
  135. #if !defined __CELLOS_LV2__ && !defined __ANDROID__ && !defined __APPLE__
  136. glDisableVertexAttribArray(m_vertexattrib);
  137. glDisableVertexAttribArray(m_texattrib);
  138. glBindBuffer(GL_ARRAY_BUFFER, 0);
  139. #elif !defined __CELLOS_LV2__ && !defined __ANDROID__ && !defined __APPLE__
  140. /* Never used for now */
  141. //glDisableVertexAttribArray(m_vertexattrib);
  142. //glDisableVertexAttribArray(m_texattrib);
  143. #else
  144. //glDisableClientState(GL_VERTEX_ARRAY);
  145. //glDisableClientState(GL_TEXTURE_COORD_ARRAY);
  146. #endif
  147. }
  148. private:
  149. ivec2 m_size;
  150. u8vec4 *m_pixels;
  151. Shader *m_shader;
  152. GLuint m_texid;
  153. #if !defined __CELLOS_LV2__ && !defined __ANDROID__ && !defined __APPLE__
  154. GLuint m_vbo, m_tbo;
  155. GLuint m_tco;
  156. #endif
  157. int m_vertexattrib, m_texattrib;
  158. float m_angle;
  159. bool m_ready;
  160. };
  161. int main()
  162. {
  163. Application app("Tutorial 3: Fractal", ivec2(640, 480), 60.0f);
  164. new DebugFps(5, 5);
  165. new Fractal(ivec2(640, 480));
  166. app.Run();
  167. return EXIT_SUCCESS;
  168. }