source: trunk/test/tutorial/tut03.cpp @ 1058

Last change on this file since 1058 was 1058, checked in by gary, 9 years ago

tutorial: port Mandelbrot tutorial to the PS3.

  • Property svn:keywords set to Id
File size: 7.7 KB
Line 
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
11#if defined HAVE_CONFIG_H
12#   include "config.h"
13#endif
14
15#include <cstring>
16
17#include "core.h"
18#include "lolgl.h"
19#include "loldebug.h"
20
21using namespace std;
22using namespace lol;
23
24#if USE_SDL && defined __APPLE__
25#   include <SDL_main.h>
26#endif
27
28#if defined _WIN32
29#   undef main /* FIXME: still needed? */
30#   include <direct.h>
31#endif
32
33class Fractal : public WorldEntity
34{
35public:
36    Fractal(ivec2 const &size)
37    {
38        m_size = size;
39        m_pixels = new u8vec4[size.x * size.y];
40        m_angle = 0.0f;
41        m_ready = false;
42    }
43
44    ~Fractal()
45    {
46        delete m_pixels;
47    }
48
49    virtual void TickGame(float deltams)
50    {
51        WorldEntity::TickGame(deltams);
52
53        m_angle += deltams * 0.0005f;
54
55        cmplx r0(cosf(m_angle), 0.8f * sinf(m_angle));
56        for (int j = 0; j < m_size.y; j++)
57        for (int i = 0; i < m_size.x; i++)
58        {
59            float const maxlen = 32.0f;
60            int const colors = 16;
61            int const maxiter = 30;
62
63            cmplx x0(4.0f / m_size.x * i - 2.0f, 3.0f / m_size.y * j - 1.5f);
64            cmplx r = x0 * r0;
65            cmplx z;
66            int iter = maxiter;
67            for (z = r; iter && z.sqlen() < maxlen * maxlen; z = z * z + r)
68                --iter;
69
70            float f = iter % colors;
71            float n = z.len();
72            f += logf(logf(n) / logf(maxlen)) / logf(2.0f);
73
74            if (iter)
75            {
76                uint8_t red = 255 - f * (255.0f / (colors + 1));
77                uint8_t green = 255 - f * (255.0f / (colors + 1));
78                uint8_t blue = (f * 512.0f / (colors + 1) > 255)
79                             ? 511 - (f * 512.0f / (colors + 1)) : 255;
80                m_pixels[j * m_size.x + i] = u8vec4(red, green, blue, 0);
81            }
82            else
83            {
84                m_pixels[j * m_size.x + i] = u8vec4(0, 0, 0, 0);
85            }
86        }
87    }
88
89    virtual void TickDraw(float deltams)
90    {
91        WorldEntity::TickDraw(deltams);
92
93        static float const vertices[] =
94        {
95            -1.0f, -1.0f,
96             1.0f, -1.0f,
97             1.0f,  1.0f,
98             1.0f,  1.0f,
99            -1.0f,  1.0f,
100            -1.0f, -1.0f,
101        };
102
103        static float const texcoords[] =
104        {
105             0.0f,  0.0f,
106             1.0f,  0.0f,
107             1.0f,  1.0f,
108             1.0f,  1.0f,
109             0.0f,  1.0f,
110             0.0f,  0.0f,
111        };
112
113        if (!m_ready)
114        {
115            glGenTextures(1, &m_texid);
116            glBindTexture(GL_TEXTURE_2D, m_texid);
117            glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_size.x, m_size.y, 0,
118                         GL_RGBA, GL_UNSIGNED_BYTE, m_pixels);
119            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
120            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
121
122            m_shader = Shader::Create(
123#if !defined __CELLOS_LV2__
124                "#version 120\n"
125                "attribute vec2 in_TexCoord;\n"
126                "attribute vec2 in_Vertex;"
127                "void main(void) {"
128                "    gl_Position = vec4(in_Vertex, 0.0, 1.0);"
129                "    gl_TexCoord[0] = vec4(in_TexCoord, 0.0, 0.0);\n"
130                "}",
131
132                "#version 120\n"
133                "uniform sampler2D in_Texture;\n"
134                "void main(void) {"
135                "    gl_FragColor = texture2D(in_Texture, gl_TexCoord[0].xy);"
136                "}"
137#else
138                "void main(float4 in_Position : POSITION,"
139                "          float2 in_TexCoord : TEXCOORD0,"
140                "          out float4 out_Position : POSITION,"
141                "          out float2 out_TexCoord : TEXCOORD0)"
142                "{"
143                "    out_TexCoord = in_TexCoord;"
144                "    out_Position = in_Position;"
145                "}",
146
147                "void main(float2 in_TexCoord : TEXCOORD0,"
148                "          uniform sampler2D tex,"
149                "          out float4 out_FragColor : COLOR)"
150                "{"
151                "    out_FragColor = tex2D(tex, in_TexCoord);"
152                "}"
153#endif
154            );
155            m_vertexattrib = m_shader->GetAttribLocation("in_Vertex");
156            m_texattrib = m_shader->GetAttribLocation("in_TexCoord");
157            m_ready = true;
158
159#if !defined __CELLOS_LV2__ && !defined __ANDROID__ && !defined __APPLE__
160            /* Method 1: store vertex buffer on the GPU memory */
161            glGenBuffers(1, &m_vbo);
162            glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
163            glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices,
164                         GL_STATIC_DRAW);
165            glGenBuffers(1, &m_tbo);
166            glBindBuffer(GL_ARRAY_BUFFER, m_tbo);
167            glBufferData(GL_ARRAY_BUFFER, sizeof(texcoords), texcoords,
168                         GL_STATIC_DRAW);
169#elif !defined __CELLOS_LV2__ && !defined __ANDROID__ && !defined __APPLE__
170            /* Method 2: upload vertex information at each frame */
171#else
172#endif
173
174            /* FIXME: this object never cleans up */
175        }
176
177        glEnable(GL_TEXTURE_2D);
178        glBindTexture(GL_TEXTURE_2D, m_texid);
179        glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, m_size.x, m_size.y,
180#if !defined __CELLOS_LV2__
181                        GL_RGBA, GL_UNSIGNED_BYTE,
182#else
183                        /* The PS3 is big-endian */
184                        GL_RGBA, GL_UNSIGNED_INT_8_8_8_8,
185#endif
186                        m_pixels);
187
188        m_shader->Bind();
189#if !defined __CELLOS_LV2__ && !defined __ANDROID__ && !defined __APPLE__
190        glBindBuffer(GL_ARRAY_BUFFER, m_vbo);
191        glEnableVertexAttribArray(m_vertexattrib);
192        glVertexAttribPointer(m_vertexattrib, 2, GL_FLOAT, GL_FALSE, 0, 0);
193
194        glBindBuffer(GL_ARRAY_BUFFER, m_tbo);
195        glEnableVertexAttribArray(m_texattrib);
196        glVertexAttribPointer(m_texattrib, 2, GL_FLOAT, GL_FALSE, 0, 0);
197#elif !defined __CELLOS_LV2__ && !defined __ANDROID__ && !defined __APPLE__
198        /* Never used for now */
199        //glEnableVertexAttribArray(m_vertexattrib);
200        //glVertexAttribPointer(m_vertexattrib, 2, GL_FLOAT, GL_FALSE, 0, vertices);
201#else
202        glEnableClientState(GL_VERTEX_ARRAY);
203        glVertexPointer(2, GL_FLOAT, 0, vertices);
204        glEnableClientState(GL_TEXTURE_COORD_ARRAY);
205        glTexCoordPointer(2, GL_FLOAT, 0, texcoords);
206#endif
207
208        glDrawArrays(GL_TRIANGLES, 0, 6);
209
210#if !defined __CELLOS_LV2__ && !defined __ANDROID__ && !defined __APPLE__
211        glDisableVertexAttribArray(m_vertexattrib);
212        glDisableVertexAttribArray(m_texattrib);
213        glBindBuffer(GL_ARRAY_BUFFER, 0);
214#elif !defined __CELLOS_LV2__ && !defined __ANDROID__ && !defined __APPLE__
215        /* Never used for now */
216        //glDisableVertexAttribArray(m_vertexattrib);
217        //glDisableVertexAttribArray(m_texattrib);
218#else
219        glDisableClientState(GL_VERTEX_ARRAY);
220        glDisableClientState(GL_TEXTURE_COORD_ARRAY);
221#endif
222    }
223
224private:
225    ivec2 m_size;
226    u8vec4 *m_pixels;
227    Shader *m_shader;
228    GLuint m_texid;
229#if !defined __CELLOS_LV2__ && !defined __ANDROID__ && !defined __APPLE__
230    GLuint m_vbo, m_tbo;
231    GLuint m_tco;
232#endif
233    int m_vertexattrib, m_texattrib;
234    float m_angle;
235    bool m_ready;
236};
237
238int main()
239{
240#if defined _WIN32
241    _chdir("../..");
242#endif
243
244    Application app("Tutorial 3: Fractal", ivec2(640, 480), 60.0f);
245
246    new DebugFps(5, 5);
247    new Fractal(ivec2(640, 480));
248
249    app.Run();
250
251    return EXIT_SUCCESS;
252}
253
Note: See TracBrowser for help on using the repository browser.