source: trunk/src/debug/quad.cpp @ 803

Last change on this file since 803 was 803, checked in by sam, 10 years ago

debug: some code cleanup in the quad tests.

  • Property svn:keywords set to Id
File size: 18.0 KB
Line 
1//
2// Lol Engine
3//
4// Copyright: (c) 2010-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 <cmath>
16#include <cstdio>
17
18#include "core.h"
19#include "lolgl.h"
20#include "loldebug.h"
21
22using namespace std;
23
24namespace lol
25{
26
27/*
28 * DebugQuad implementation class
29 */
30
31static int const NUM_ARRAYS = 2;
32static int const NUM_BUFFERS = 6;
33static int const NUM_ATTRS = 6;
34static int const NUM_SHADERS = 6;
35static int const NUM_TEXTURES = 1;
36
37static int const TEX_SIZE = 32;
38
39class DebugQuadData
40{
41    friend class DebugQuad;
42
43private:
44    vec2 orig, step, aa, bb;
45
46    int initialised;
47    float time;
48    GLuint array[NUM_ARRAYS];
49    GLuint buffer[NUM_BUFFERS];
50    Shader *shader[NUM_SHADERS];
51    GLuint attr[NUM_ATTRS];
52    GLuint texture[NUM_TEXTURES];
53    uint8_t image[1][TEX_SIZE * TEX_SIZE * 4];
54};
55
56/*
57 * Public DebugQuad class
58 */
59
60DebugQuad::DebugQuad()
61  : data(new DebugQuadData())
62{
63    data->initialised = 0;
64    data->time = RandF(10000.0f);
65
66    drawgroup = DRAWGROUP_HUD;
67}
68
69void DebugQuad::TickGame(float deltams)
70{
71    Entity::TickGame(deltams);
72
73    data->time += deltams;
74}
75
76void DebugQuad::TickDraw(float deltams)
77{
78    Entity::TickDraw(deltams);
79
80    if (!data->initialised && !IsDestroying())
81    {
82        glGenVertexArrays(NUM_ARRAYS, data->array);
83        glGenBuffers(NUM_BUFFERS, data->buffer);
84        glGenTextures(NUM_TEXTURES, data->texture);
85        for (int i = 0; i < NUM_SHADERS; i++)
86            data->shader[i] = NULL;
87
88        /* Checkerboard texture */
89        glEnable(GL_TEXTURE_2D);
90        glBindTexture(GL_TEXTURE_2D, data->texture[0]);
91        for (int j = 0; j < TEX_SIZE; j++)
92            for (int i = 0; i < TEX_SIZE; i++)
93            {
94                uint8_t wb = (((i / 2) ^ (j / 2)) & 1) * 0xff;
95                data->image[0][(j * TEX_SIZE + i) * 4 + 0] = wb;
96                data->image[0][(j * TEX_SIZE + i) * 4 + 1] = wb;
97                data->image[0][(j * TEX_SIZE + i) * 4 + 2] = wb;
98                data->image[0][(j * TEX_SIZE + i) * 4 + 3] = 0xff;
99            }
100        /* Use GL_RGBA instead of 4 for the internal format (Android) */
101        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, TEX_SIZE, TEX_SIZE, 0,
102                     GL_RGBA, GL_UNSIGNED_BYTE, data->image[0]);
103        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
104        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
105
106        data->initialised = 1;
107    }
108    else if (data->initialised && IsDestroying())
109    {
110        glDeleteVertexArrays(NUM_ARRAYS, data->array);
111        glDeleteBuffers(NUM_BUFFERS, data->buffer);
112        glDeleteTextures(NUM_TEXTURES, data->texture);
113
114        for (int i = 0; i < NUM_SHADERS; i++)
115            if (data->shader[i])
116                Shader::Destroy(data->shader[i]);
117
118        data->initialised = 0;
119    }
120
121    /* Reset GL states to something reasonably safe */
122    glMatrixMode(GL_PROJECTION);
123    glLoadIdentity();
124    glMatrixMode(GL_MODELVIEW);
125    glLoadIdentity();
126    glDisable(GL_TEXTURE_2D);
127    glBindBuffer(GL_ARRAY_BUFFER, 0);
128    glUseProgram(0);
129
130    /* Prepare our quad coordinates */
131    vec2i const layout(4, 3);
132    data->step = vec2(2.0f, -2.0f) / (3 * layout + vec2i(1));
133    data->orig = vec2(-1.0f, 1.0f) + data->step;
134    data->aa = data->orig;
135    data->bb = data->orig + 2.0f * data->step;
136
137    /* Generate a few random numbers */
138    float f1 = 0.5f + 0.5f * sinf(0.00034f * data->time);
139    float f2 = 0.5f + 0.5f * sinf(0.00053f * data->time + 1.0f);
140    float f3 = 0.5f + 0.5f * sinf(0.00072f * data->time + 4.0f);
141    float f4 = 0.5f + 0.5f * sinf(0.00091f * data->time + 8.0f);
142
143    GLfloat const colors[] = { f1, f2, f3, f4, f2, f1, f3, f1, f4,
144                               f3, f1, f4, f4, f3, f2, f1, f2, f3 };
145    GLfloat const texcoords[] = { f1, f3, f3, f2, f2, f4,
146                                  f2, f4, f4, f1, f1, f3 };
147
148#if defined HAVE_GLBEGIN || defined USE_GLEW
149    /*
150     * Test #1: simple glBegin code
151     * Renders an orange square.
152     */
153    glColor3f(0.8f, 0.5f, 0.2f);
154    glBegin(GL_TRIANGLES);
155        glVertex3f(data->aa.x, data->bb.y, 0.0f);
156        glVertex3f(data->bb.x, data->bb.y, 0.0f);
157        glVertex3f(data->bb.x, data->aa.y, 0.0f);
158
159        glVertex3f(data->bb.x, data->aa.y, 0.0f);
160        glVertex3f(data->aa.x, data->aa.y, 0.0f);
161        glVertex3f(data->aa.x, data->bb.y, 0.0f);
162    glEnd();
163
164    Advance();
165
166    /*
167     * Test #2: glBegin + per-vertex coloring
168     * Renders a multicolored square with varying colors.
169     */
170    glBegin(GL_TRIANGLES);
171        glColor3f(f1, f2, f3);
172        glVertex3f(data->aa.x, data->bb.y, 0.0f);
173        glColor3f(f4, f2, f1);
174        glVertex3f(data->bb.x, data->bb.y, 0.0f);
175        glColor3f(f3, f1, f4);
176        glVertex3f(data->bb.x, data->aa.y, 0.0f);
177
178        glVertex3f(data->bb.x, data->aa.y, 0.0f);
179        glColor3f(f4, f3, f2);
180        glVertex3f(data->aa.x, data->aa.y, 0.0f);
181        glColor3f(f1, f2, f3);
182        glVertex3f(data->aa.x, data->bb.y, 0.0f);
183    glEnd();
184
185    Advance();
186
187    /*
188     * Test #3: glBegin + texture
189     * Renders an animated black-and-white distorted checkerboard.
190     */
191    glEnable(GL_TEXTURE_2D);
192    glBindTexture(GL_TEXTURE_2D, data->texture[0]);
193    glColor3f(1.0f, 1.0f, 1.0f);
194    glBegin(GL_TRIANGLES);
195        glTexCoord2f(f1, f3);
196        glVertex3f(data->aa.x, data->bb.y, 0.0f);
197        glTexCoord2f(f3, f2);
198        glVertex3f(data->bb.x, data->bb.y, 0.0f);
199        glTexCoord2f(f2, f4);
200        glVertex3f(data->bb.x, data->aa.y, 0.0f);
201
202        glTexCoord2f(f2, f4);
203        glVertex3f(data->bb.x, data->aa.y, 0.0f);
204        glTexCoord2f(f4, f1);
205        glVertex3f(data->aa.x, data->aa.y, 0.0f);
206        glTexCoord2f(f1, f3);
207        glVertex3f(data->aa.x, data->bb.y, 0.0f);
208    glEnd();
209    glDisable(GL_TEXTURE_2D);
210
211    Advance();
212
213    /*
214     * Test #4: glBegin + color in fragment shader
215     * Renders a static, coloured and tiled pattern.
216     */
217    if (!data->shader[0])
218        data->shader[0] = Shader::Create(
219            "#version 110\n"
220            "void main()"
221            "{"
222            "    gl_Position = gl_Vertex;"
223            "}",
224
225            "#version 110\n"
226            "void main()"
227            "{"
228            "    float dx = mod(gl_FragCoord.x * gl_FragCoord.y, 2.0);"
229            "    float dy = mod(gl_FragCoord.x * 0.125, 1.0);"
230            "    float dz = mod(gl_FragCoord.y * 0.125, 1.0);"
231            "    gl_FragColor = vec4(dx, dy, dz, 1.0);"
232            "}");
233    data->shader[0]->Bind();
234    glColor3f(0.0f, 1.0f, 1.0f);
235    glBegin(GL_TRIANGLES);
236        glVertex3f(data->aa.x, data->bb.y, 0.0f);
237        glVertex3f(data->bb.x, data->bb.y, 0.0f);
238        glVertex3f(data->bb.x, data->aa.y, 0.0f);
239
240        glVertex3f(data->bb.x, data->aa.y, 0.0f);
241        glVertex3f(data->aa.x, data->aa.y, 0.0f);
242        glVertex3f(data->aa.x, data->bb.y, 0.0f);
243    glEnd();
244    glUseProgram(0);
245
246    Advance();
247
248    /*
249     * Test #5: glBegin + pass color from vertex shader to fragment shader
250     * Renders a multicolored square with varying colors.
251     */
252    if (!data->shader[1])
253        data->shader[1] = Shader::Create(
254            "#version 110\n"
255            "varying vec4 pass_Color;"
256            "void main()"
257            "{"
258            "    float r = gl_MultiTexCoord0.x;"
259            "    float g = gl_MultiTexCoord0.y;"
260            "    pass_Color = vec4(1.0 - r, 1.0 - g, r, 1.0);"
261            "    gl_Position = gl_Vertex;"
262            "}",
263
264            "#version 110\n"
265            "varying vec4 pass_Color;"
266            "void main()"
267            "{"
268            "    gl_FragColor = pass_Color;"
269            "}");
270    data->shader[1]->Bind();
271    glColor3f(0.0f, 1.0f, 1.0f);
272    glBegin(GL_TRIANGLES);
273        glTexCoord2f(f1, f3);
274        glVertex3f(data->aa.x, data->bb.y, 0.0f);
275        glTexCoord2f(f3, f2);
276        glVertex3f(data->bb.x, data->bb.y, 0.0f);
277        glTexCoord2f(f2, f4);
278        glVertex3f(data->bb.x, data->aa.y, 0.0f);
279
280        glTexCoord2f(f2, f4);
281        glVertex3f(data->bb.x, data->aa.y, 0.0f);
282        glTexCoord2f(f4, f1);
283        glVertex3f(data->aa.x, data->aa.y, 0.0f);
284        glTexCoord2f(f1, f3);
285        glVertex3f(data->aa.x, data->bb.y, 0.0f);
286    glEnd();
287    glUseProgram(0);
288
289    Advance();
290
291    /*
292     * Test #6: glBegin + apply texture in fragment shader
293     * Renders an animated black-and-white distorted checkerboard with a
294     * zoom ratio twice the one in test #3.
295     */
296    if (!data->shader[2])
297        data->shader[2] = Shader::Create(
298            "#version 110\n"
299            "void main()"
300            "{"
301            "    gl_TexCoord[0] = gl_MultiTexCoord0;"
302            "    gl_Position = gl_Vertex;"
303            "}",
304
305            "#version 110\n"
306            "uniform sampler2D tex;"
307            "void main()"
308            "{"
309            "    gl_FragColor = texture2D(tex, gl_TexCoord[0].xy * 0.25);"
310            "}");
311    data->shader[2]->Bind();
312    glColor3f(0.0f, 1.0f, 1.0f);
313    glEnable(GL_TEXTURE_2D);
314    glBindTexture(GL_TEXTURE_2D, data->texture[0]);
315    glBegin(GL_TRIANGLES);
316        glTexCoord2f(f1, f3);
317        glVertex3f(data->aa.x, data->bb.y, 0.0f);
318        glTexCoord2f(f3, f2);
319        glVertex3f(data->bb.x, data->bb.y, 0.0f);
320        glTexCoord2f(f2, f4);
321        glVertex3f(data->bb.x, data->aa.y, 0.0f);
322
323        glTexCoord2f(f2, f4);
324        glVertex3f(data->bb.x, data->aa.y, 0.0f);
325        glTexCoord2f(f4, f1);
326        glVertex3f(data->aa.x, data->aa.y, 0.0f);
327        glTexCoord2f(f1, f3);
328        glVertex3f(data->aa.x, data->bb.y, 0.0f);
329    glEnd();
330    glUseProgram(0);
331    glDisable(GL_TEXTURE_2D);
332
333    Advance();
334#endif
335
336    /*
337     * Test #7: vertex buffer
338     * Renders a multicolored square with varying colors.
339     */
340    GLfloat const vertices1[] = { data->aa.x, data->bb.y, 0.0f,
341                                  data->bb.x, data->bb.y, 0.0f,
342                                  data->bb.x, data->aa.y, 0.0f,
343                                  data->bb.x, data->aa.y, 0.0f,
344                                  data->aa.x, data->aa.y, 0.0f,
345                                  data->aa.x, data->bb.y, 0.0f };
346
347    glEnableClientState(GL_COLOR_ARRAY);
348    glEnableClientState(GL_VERTEX_ARRAY);
349
350    glColorPointer(3, GL_FLOAT, 0, colors);
351    glVertexPointer(3, GL_FLOAT, 0, vertices1);
352    glDrawArrays(GL_TRIANGLES, 0, 6);
353
354    glDisableClientState(GL_VERTEX_ARRAY);
355    glDisableClientState(GL_COLOR_ARRAY);
356    glUseProgram(0);
357
358    Advance();
359
360    /*
361     * Test #8: vertex buffer + texture & color in 1.10 fragment shader
362     * Renders a multicolored square with varying colors xored with an
363     * animated distorted checkerboard.
364     */
365    if (!data->shader[3])
366        data->shader[3] = Shader::Create(
367            "#version 110\n"
368            "varying vec4 pass_Color;"
369            "void main()"
370            "{"
371            "    gl_TexCoord[0] = gl_MultiTexCoord0;"
372            "    pass_Color = gl_Color;"
373            "    gl_Position = gl_Vertex;"
374            "}",
375
376            "#version 110\n"
377            "varying vec4 pass_Color;"
378            "uniform sampler2D tex;"
379            "void main()"
380            "{"
381            "    vec4 tmp = texture2D(tex, gl_TexCoord[0].xy * 0.25);"
382            "    gl_FragColor = vec4(abs(tmp.xyz - pass_Color.xyz), 1.0);"
383            "}");
384
385    data->shader[3]->Bind();
386    GLfloat const vertices2[] = { data->aa.x, data->bb.y, 0.0f,
387                                  data->bb.x, data->bb.y, 0.0f,
388                                  data->bb.x, data->aa.y, 0.0f,
389                                  data->bb.x, data->aa.y, 0.0f,
390                                  data->aa.x, data->aa.y, 0.0f,
391                                  data->aa.x, data->bb.y, 0.0f };
392
393    glEnableClientState(GL_VERTEX_ARRAY);
394    glEnableClientState(GL_COLOR_ARRAY);
395    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
396
397    glVertexPointer(3, GL_FLOAT, 0, vertices2);
398    glColorPointer(3, GL_FLOAT, 0, colors);
399    glTexCoordPointer(2, GL_FLOAT, 0, texcoords);
400    glDrawArrays(GL_TRIANGLES, 0, 6);
401
402    glDisableClientState(GL_VERTEX_ARRAY);
403    glDisableClientState(GL_COLOR_ARRAY);
404    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
405    glUseProgram(0);
406
407    Advance();
408
409    /*
410     * Test #8: vertex buffer + texture & color in 1.20 fragment shader
411     * Renders a multicolored square with varying colors xored with an
412     * animated distorted checkerboard.
413     */
414    if (!data->shader[4])
415    {
416        data->shader[4] = Shader::Create(
417            "#version 120\n"
418            "attribute vec3 in_Vertex;"
419            "attribute vec3 in_Color;"
420            "attribute vec2 in_MultiTexCoord0;"
421            "varying vec4 pass_Color;"
422            "void main()"
423            "{"
424            "    gl_TexCoord[0] = vec4(in_MultiTexCoord0, 0.0, 0.0);"
425            "    pass_Color = vec4(in_Color, 1.0);"
426            "    gl_Position = vec4(in_Vertex, 1.0);"
427            "}",
428
429            "#version 120\n"
430            "varying vec4 pass_Color;"
431            "uniform sampler2D tex;"
432            "void main()"
433            "{"
434            "    vec4 tmp = texture2D(tex, gl_TexCoord[0].xy * 0.25);"
435            "    gl_FragColor = vec4(abs(tmp.xyz - pass_Color.xyz), 1.0);"
436            "}");
437        data->attr[0] = data->shader[4]->GetAttribLocation("in_Vertex");
438        data->attr[1] = data->shader[4]->GetAttribLocation("in_Color");
439        data->attr[2] = data->shader[4]->GetAttribLocation("in_MultiTexCoord0");
440    }
441    data->shader[4]->Bind();
442    GLfloat const vertices3[] = { data->aa.x, data->bb.y, 0.0f,
443                                  data->bb.x, data->bb.y, 0.0f,
444                                  data->bb.x, data->aa.y, 0.0f,
445                                  data->bb.x, data->aa.y, 0.0f,
446                                  data->aa.x, data->aa.y, 0.0f,
447                                  data->aa.x, data->bb.y, 0.0f };
448
449    glBindVertexArray(data->array[0]);
450
451    glBindBuffer(GL_ARRAY_BUFFER, data->buffer[0]);
452    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices3), vertices3,
453                 GL_DYNAMIC_DRAW);
454    glVertexAttribPointer(data->attr[0], 3, GL_FLOAT, GL_FALSE, 0, 0);
455    glEnableVertexAttribArray(data->attr[0]);
456
457    glBindBuffer(GL_ARRAY_BUFFER, data->buffer[1]);
458    glBufferData(GL_ARRAY_BUFFER, sizeof(colors), colors,
459                 GL_DYNAMIC_DRAW);
460    glVertexAttribPointer(data->attr[1], 3, GL_FLOAT, GL_FALSE, 0, 0);
461    glEnableVertexAttribArray(data->attr[1]);
462
463    glBindBuffer(GL_ARRAY_BUFFER, data->buffer[2]);
464    glBufferData(GL_ARRAY_BUFFER, sizeof(texcoords), texcoords,
465                 GL_DYNAMIC_DRAW);
466    glVertexAttribPointer(data->attr[2], 2, GL_FLOAT, GL_FALSE, 0, 0);
467    glEnableVertexAttribArray(data->attr[2]);
468
469    glDrawArrays(GL_TRIANGLES, 0, 6);
470    glBindVertexArray(0);
471
472    glDisableVertexAttribArray(data->attr[0]);
473    glDisableVertexAttribArray(data->attr[1]);
474    glDisableVertexAttribArray(data->attr[2]);
475    glUseProgram(0);
476
477    Advance();
478
479    /*
480     * Test #8: vertex buffer + texture & color in 1.30 fragment shader
481     * Renders a multicolored square with varying colors xored with an
482     * animated distorted checkerboard.
483     */
484    if (!data->shader[5])
485    {
486        data->shader[5] = Shader::Create(
487            "#version 130\n"
488            "in vec3 in_Vertex;"
489            "in vec3 in_Color;"
490            "in vec2 in_MultiTexCoord0;"
491            "out vec4 pass_Color;"
492            "void main()"
493            "{"
494            "    gl_TexCoord[0] = vec4(in_MultiTexCoord0, 0.0, 0.0);"
495            "    pass_Color = vec4(in_Color, 1.0);"
496            "    gl_Position = vec4(in_Vertex, 1.0);"
497            "}",
498
499            "#version 130\n"
500            "in vec4 pass_Color;"
501            "uniform sampler2D tex;"
502            "void main()"
503            "{"
504            "    vec4 tmp = texture2D(tex, gl_TexCoord[0].xy * 0.25);"
505            "    gl_FragColor = vec4(abs(tmp.xyz - pass_Color.xyz), 1.0);"
506            "}");
507        data->attr[3] = data->shader[4]->GetAttribLocation("in_Vertex");
508        data->attr[4] = data->shader[4]->GetAttribLocation("in_Color");
509        data->attr[5] = data->shader[4]->GetAttribLocation("in_MultiTexCoord0");
510    }
511    data->shader[5]->Bind();
512    GLfloat const vertices4[] = { data->aa.x, data->bb.y, 0.0f,
513                                  data->bb.x, data->bb.y, 0.0f,
514                                  data->bb.x, data->aa.y, 0.0f,
515                                  data->bb.x, data->aa.y, 0.0f,
516                                  data->aa.x, data->aa.y, 0.0f,
517                                  data->aa.x, data->bb.y, 0.0f };
518
519    glBindVertexArray(data->array[1]);
520
521    glBindBuffer(GL_ARRAY_BUFFER, data->buffer[3]);
522    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices4), vertices4,
523                 GL_DYNAMIC_DRAW);
524    glVertexAttribPointer(data->attr[3], 3, GL_FLOAT, GL_FALSE, 0, 0);
525    glEnableVertexAttribArray(data->attr[3]);
526
527    glBindBuffer(GL_ARRAY_BUFFER, data->buffer[4]);
528    glBufferData(GL_ARRAY_BUFFER, sizeof(colors), colors,
529                 GL_DYNAMIC_DRAW);
530    glVertexAttribPointer(data->attr[4], 3, GL_FLOAT, GL_FALSE, 0, 0);
531    glEnableVertexAttribArray(data->attr[4]);
532
533    glBindBuffer(GL_ARRAY_BUFFER, data->buffer[5]);
534    glBufferData(GL_ARRAY_BUFFER, sizeof(texcoords), texcoords,
535                 GL_DYNAMIC_DRAW);
536    glVertexAttribPointer(data->attr[5], 2, GL_FLOAT, GL_FALSE, 0, 0);
537    glEnableVertexAttribArray(data->attr[5]);
538
539    glDrawArrays(GL_TRIANGLES, 0, 6);
540    glBindVertexArray(0);
541
542    glDisableVertexAttribArray(data->attr[3]);
543    glDisableVertexAttribArray(data->attr[4]);
544    glDisableVertexAttribArray(data->attr[5]);
545    glUseProgram(0);
546
547    Advance();
548}
549
550void DebugQuad::Advance()
551{
552    data->aa.x += 3.0f * data->step.x;
553    data->bb.x += 3.0f * data->step.x;
554    if (data->bb.x > 1.0f)
555    {
556        data->aa.x = data->orig.x;
557        data->bb.x = data->orig.x + 2.0f * data->step.x;
558        data->aa.y += 3.0f * data->step.y;
559        data->bb.y += 3.0f * data->step.y;
560    }
561}
562
563DebugQuad::~DebugQuad()
564{
565    delete data;
566}
567
568} /* namespace lol */
569
Note: See TracBrowser for help on using the repository browser.