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

Last change on this file since 1051 was 1051, checked in by sam, 8 years ago

debug: fix a timing issue in the quad debug object.

  • Property svn:keywords set to Id
File size: 32.9 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#if defined WIN32 && !defined _XBOX
16#   define _USE_MATH_DEFINES /* for M_PI */
17#   define WIN32_LEAN_AND_MEAN
18#   include <windows.h>
19#endif
20
21#include <cmath>
22#include <cstdio>
23#include <cstring>
24
25#include "core.h"
26#include "lolgl.h"
27#include "loldebug.h"
28
29using namespace std;
30
31namespace lol
32{
33
34/*
35 * OpenGL Feature list:
36 *
37 * Android and iOS don't have GL_VERTEX_ARRAY.
38 *
39 * iOS does vertex buffers using glVertexAttribPointer(), and does not
40 * support glVertexPointer().
41 *
42 * PSGL (on the PS3) does vertex buffers using glVertexPointer(), and
43 * does not support glVertexAttribPointer().
44 */
45
46/*
47 * DebugQuad implementation class
48 */
49
50static int const NUM_ARRAYS = 10;
51static int const NUM_BUFFERS = 20;
52static int const NUM_ATTRS = 20;
53static int const NUM_UNIFORMS = 20;
54static int const NUM_SHADERS = 20;
55static int const NUM_TEXTURES = 10;
56
57static int const TEX_SIZE = 32;
58
59class DebugQuadData
60{
61    friend class DebugQuad;
62
63private:
64    vec2 orig, step, aa, bb;
65
66    int initialised;
67    float time;
68#if !defined __CELLOS_LV2__ && !defined __ANDROID__
69    GLuint array[NUM_ARRAYS];
70#endif
71    GLuint buffer[NUM_BUFFERS];
72    Shader *shader[NUM_SHADERS];
73    GLuint attr[NUM_ATTRS];
74    GLuint uni[NUM_UNIFORMS];
75    GLuint texture[NUM_TEXTURES];
76    uint8_t image[1][TEX_SIZE * TEX_SIZE * 4];
77
78    /* Cache a list of points for a quad at the proper coordinates. */
79    GLfloat const *GetVertexArray()
80    {
81        GLfloat tmp[18] = { aa.x, bb.y, 0, bb.x, bb.y, 0, bb.x, aa.y, 0,
82                            bb.x, aa.y, 0, aa.x, aa.y, 0, aa.x, bb.y, 0 };
83        memcpy(vertices, tmp, sizeof(tmp));
84        return vertices;
85    }
86    GLfloat vertices[18];
87
88    /* Cache a list of points for a sine wave, ensuring constant spacing
89     * between consecutive points. */
90    static int const SINE_SIZE = 256;
91    GLfloat const *GetSineArray()
92    {
93        static float const SINE_SPACE = 0.01f;
94        float x = 0.0f;
95        for (npoints = 0; npoints < SINE_SIZE && x <= 1.0f; npoints++)
96        {
97            float y = 0.5f + 0.5f * lol_sin(x * 2.0f * M_PI + time * 5e-3f);
98            points[npoints * 2] = aa.x + (bb.x - aa.x) * x;
99            points[npoints * 2 + 1] = aa.y + (bb.y - aa.y) * y;
100
101            float dy = M_PI * lol_cos(x * 2.0f * M_PI + time * 5e-3f);
102            float dx = SINE_SPACE / sqrtf(1.0f + dy * dy);
103            x += dx;
104        }
105        return points;
106
107    }
108    GLfloat points[2 * SINE_SIZE];
109    int npoints;
110};
111
112/*
113 * Public DebugQuad class
114 */
115
116DebugQuad::DebugQuad()
117  : data(new DebugQuadData())
118{
119    data->initialised = 0;
120    data->time = RandF(10000.0f);
121
122    drawgroup = DRAWGROUP_HUD;
123}
124
125DebugQuad::~DebugQuad()
126{
127    delete data;
128}
129
130void DebugQuad::Advance()
131{
132    data->aa.x += 4.0f * data->step.x;
133    data->bb.x += 4.0f * data->step.x;
134    if (data->bb.x > 1.0f)
135    {
136        data->aa.x = data->orig.x;
137        data->bb.x = data->orig.x + 3.0f * data->step.x;
138        data->aa.y += 4.0f * data->step.y;
139        data->bb.y += 4.0f * data->step.y;
140    }
141}
142
143void DebugQuad::TickGame(float deltams)
144{
145    Entity::TickGame(deltams);
146
147    data->time += deltams;
148}
149
150void DebugQuad::TickDraw(float deltams)
151{
152    Entity::TickDraw(deltams);
153
154    if (!data->initialised && !IsDestroying())
155    {
156#if !defined __CELLOS_LV2__ && !defined __ANDROID__ && !defined __APPLE__
157        glGenVertexArrays(NUM_ARRAYS, data->array);
158#endif
159        glGenBuffers(NUM_BUFFERS, data->buffer);
160        glGenTextures(NUM_TEXTURES, data->texture);
161        for (int i = 0; i < NUM_SHADERS; i++)
162            data->shader[i] = NULL;
163
164        /* Checkerboard texture */
165        glEnable(GL_TEXTURE_2D);
166        glBindTexture(GL_TEXTURE_2D, data->texture[0]);
167        for (int j = 0; j < TEX_SIZE; j++)
168            for (int i = 0; i < TEX_SIZE; i++)
169            {
170                uint8_t wb = (((i / 2) ^ (j / 2)) & 1) * 0xff;
171                data->image[0][(j * TEX_SIZE + i) * 4 + 0] = wb;
172                data->image[0][(j * TEX_SIZE + i) * 4 + 1] = wb;
173                data->image[0][(j * TEX_SIZE + i) * 4 + 2] = wb;
174                data->image[0][(j * TEX_SIZE + i) * 4 + 3] = 0xff;
175            }
176        /* Use GL_RGBA instead of 4 for the internal format (Android) */
177        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, TEX_SIZE, TEX_SIZE, 0,
178                     GL_RGBA, GL_UNSIGNED_BYTE, data->image[0]);
179        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
180        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
181
182        data->initialised = 1;
183    }
184    else if (data->initialised && IsDestroying())
185    {
186#if !defined __CELLOS_LV2__ && !defined __ANDROID__ && !defined __APPLE__
187        glDeleteVertexArrays(NUM_ARRAYS, data->array);
188#endif
189        glDeleteBuffers(NUM_BUFFERS, data->buffer);
190        glDeleteTextures(NUM_TEXTURES, data->texture);
191
192        for (int i = 0; i < NUM_SHADERS; i++)
193            if (data->shader[i])
194                Shader::Destroy(data->shader[i]);
195
196        data->initialised = 0;
197    }
198
199    /* Prepare our quad coordinates */
200    ivec2 const layout(7, 5);
201    data->step = vec2(2.0f, -2.0f) / (4 * layout + ivec2(1));
202    data->orig = vec2(-1.0f, 1.0f) + data->step;
203    data->aa = data->orig;
204    data->bb = data->orig + 3.0f * data->step;
205
206    /* These points form a [0,1][0,1] square */
207    GLfloat points[12] = { 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f,
208                           0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f };
209
210    GLfloat texcoords[12];
211    mat4 t1 = mat4::translate(0.5f, 0.5f, 0.0f)
212            * mat4::rotate(0.0254f * data->time, 0.0f, 0.0f, 1.0f)
213            * mat4::translate(-0.5f, -0.5f, 0.0f);
214    for (int i = 0; i < 6; i++)
215    {
216         vec4 p = t1 * vec4(points[i * 2], points[i * 2 + 1], 0.0f, 1.0f);
217         texcoords[i * 2] = p.x;
218         texcoords[i * 2 + 1] = p.y;
219    }
220
221    GLfloat colors[18];
222    mat4 t2 = mat4::translate(0.5f, 0.5f, 0.5f)
223            * mat4::rotate(0.0154f * data->time, 0.0f, 0.0f, 1.0f)
224            * mat4::rotate(0.0211f * data->time, 0.0f, 1.0f, 0.0f)
225            * mat4::rotate(0.0267f * data->time, 1.0f, 0.0f, 0.0f)
226            * mat4::translate(-0.5f, -0.5f, 0.0f);
227    for (int i = 0; i < 6; i++)
228    {
229         vec4 p = t2 * vec4(points[i * 2], points[i * 2 + 1], 0.0f, 1.0f);
230         colors[i * 3] = p.x;
231         colors[i * 3 + 1] = p.y;
232         colors[i * 3 + 2] = p.z;
233    }
234
235    /* Our default quad color */
236    vec4 orange(0.8f, 0.5f, 0.2f, 1.0f);
237
238    /* Cheap iterators */
239#if !defined __CELLOS_LV2__ && !defined __ANDROID__
240    GLuint *array = data->array;
241#endif
242    GLuint *buffer = data->buffer;
243    Shader **shader = data->shader;
244    GLuint *attr = data->attr;
245    GLuint *uni = data->uni;
246
247    /* These may be shared across calls */
248    GLfloat const *sine;
249
250    ResetState();
251
252    /*
253     * Test #1: simple glBegin + GL_TRIANGLES code
254     *
255     * Renders an orange square.
256     */
257#if defined HAVE_GLBEGIN || defined USE_GLEW
258    glColor3f(orange.x, orange.y, orange.z);
259    glBegin(GL_TRIANGLES);
260        glVertex3f(data->aa.x, data->bb.y, 0.0f);
261        glVertex3f(data->bb.x, data->bb.y, 0.0f);
262        glVertex3f(data->bb.x, data->aa.y, 0.0f);
263
264        glVertex3f(data->bb.x, data->aa.y, 0.0f);
265        glVertex3f(data->aa.x, data->aa.y, 0.0f);
266        glVertex3f(data->aa.x, data->bb.y, 0.0f);
267    glEnd();
268#endif
269
270    Advance();
271    ResetState();
272
273    /*
274     * Test #2: glBegin + per-vertex coloring
275     *
276     * Renders a multicoloured square with varying colors.
277     */
278#if defined HAVE_GLBEGIN || defined USE_GLEW
279    glBegin(GL_TRIANGLES);
280        glColor3f(colors[0], colors[1], colors[2]);
281        glVertex3f(data->aa.x, data->bb.y, 0.0f);
282        glColor3f(colors[3], colors[4], colors[5]);
283        glVertex3f(data->bb.x, data->bb.y, 0.0f);
284        glColor3f(colors[6], colors[7], colors[8]);
285        glVertex3f(data->bb.x, data->aa.y, 0.0f);
286
287        glColor3f(colors[9], colors[10], colors[11]);
288        glVertex3f(data->bb.x, data->aa.y, 0.0f);
289        glColor3f(colors[12], colors[13], colors[14]);
290        glVertex3f(data->aa.x, data->aa.y, 0.0f);
291        glColor3f(colors[15], colors[16], colors[17]);
292        glVertex3f(data->aa.x, data->bb.y, 0.0f);
293    glEnd();
294#endif
295
296    Advance();
297    ResetState();
298
299    /*
300     * Test #3: glBegin + texture
301     *
302     * Renders a multicoloured square with varying colors multiplied with an
303     * animated distorted checkerboard.
304     */
305#if defined HAVE_GLBEGIN || defined USE_GLEW
306    glEnable(GL_TEXTURE_2D);
307    glBindTexture(GL_TEXTURE_2D, data->texture[0]);
308    glColor3f(1.0f, 1.0f, 1.0f);
309    glBegin(GL_TRIANGLES);
310        glColor3f(colors[0], colors[1], colors[2]);
311        glTexCoord2f(texcoords[0], texcoords[1]);
312        glVertex3f(data->aa.x, data->bb.y, 0.0f);
313        glColor3f(colors[3], colors[4], colors[5]);
314        glTexCoord2f(texcoords[2], texcoords[3]);
315        glVertex3f(data->bb.x, data->bb.y, 0.0f);
316        glColor3f(colors[6], colors[7], colors[8]);
317        glTexCoord2f(texcoords[4], texcoords[5]);
318        glVertex3f(data->bb.x, data->aa.y, 0.0f);
319
320        glColor3f(colors[9], colors[10], colors[11]);
321        glTexCoord2f(texcoords[6], texcoords[7]);
322        glVertex3f(data->bb.x, data->aa.y, 0.0f);
323        glColor3f(colors[12], colors[13], colors[14]);
324        glTexCoord2f(texcoords[8], texcoords[9]);
325        glVertex3f(data->aa.x, data->aa.y, 0.0f);
326        glColor3f(colors[15], colors[16], colors[17]);
327        glTexCoord2f(texcoords[10], texcoords[11]);
328        glVertex3f(data->aa.x, data->bb.y, 0.0f);
329    glEnd();
330    glDisable(GL_TEXTURE_2D);
331#endif
332
333    Advance();
334    ResetState();
335
336    /*
337     * Test #4: glBegin + color in fragment shader
338     *
339     * Renders a static, coloured and tiled pattern.
340     */
341#if defined HAVE_GLBEGIN || defined USE_GLEW
342    if (!shader[0])
343        shader[0] = Shader::Create(
344            "#version 110\n"
345            "void main()"
346            "{"
347            "    gl_Position = gl_Vertex;"
348            "}",
349
350            "#version 110\n"
351            "void main()"
352            "{"
353            "    float dx = mod(gl_FragCoord.x * gl_FragCoord.y, 2.0);"
354            "    float dy = mod(gl_FragCoord.x * 0.125, 1.0);"
355            "    float dz = mod(gl_FragCoord.y * 0.125, 1.0);"
356            "    gl_FragColor = vec4(dx, dy, dz, 1.0);"
357            "}");
358    shader[0]->Bind();
359    shader++;
360    glColor3f(0.0f, 1.0f, 1.0f);
361    glBegin(GL_TRIANGLES);
362        glVertex3f(data->aa.x, data->bb.y, 0.0f);
363        glVertex3f(data->bb.x, data->bb.y, 0.0f);
364        glVertex3f(data->bb.x, data->aa.y, 0.0f);
365
366        glVertex3f(data->bb.x, data->aa.y, 0.0f);
367        glVertex3f(data->aa.x, data->aa.y, 0.0f);
368        glVertex3f(data->aa.x, data->bb.y, 0.0f);
369    glEnd();
370#endif
371
372    Advance();
373    ResetState();
374
375    /*
376     * Test #5: glBegin + pass vertex coord from vertex shader to fragment
377     * shader for use as color information.
378     *
379     * Renders a multicoloured square with varying colors.
380     */
381#if defined HAVE_GLBEGIN || defined USE_GLEW
382    if (!shader[0])
383        shader[0] = Shader::Create(
384            "#version 110\n"
385            "varying vec4 pass_Color;"
386            "void main()"
387            "{"
388            "    float r = gl_MultiTexCoord0.x;"
389            "    float g = gl_MultiTexCoord0.y;"
390            "    float b = gl_MultiTexCoord0.z;"
391            "    pass_Color = vec4(r, g, b, 1.0);"
392            "    gl_Position = gl_Vertex;"
393            "}",
394
395            "#version 110\n"
396            "varying vec4 pass_Color;"
397            "void main()"
398            "{"
399            "    gl_FragColor = pass_Color;"
400            "}");
401    shader[0]->Bind();
402    shader++;
403    glColor3f(0.0f, 1.0f, 1.0f);
404    glBegin(GL_TRIANGLES);
405        glTexCoord3f(colors[0], colors[1], colors[2]);
406        glVertex3f(data->aa.x, data->bb.y, 0.0f);
407        glTexCoord3f(colors[3], colors[4], colors[5]);
408        glVertex3f(data->bb.x, data->bb.y, 0.0f);
409        glTexCoord3f(colors[6], colors[7], colors[8]);
410        glVertex3f(data->bb.x, data->aa.y, 0.0f);
411
412        glTexCoord3f(colors[9], colors[10], colors[11]);
413        glVertex3f(data->bb.x, data->aa.y, 0.0f);
414        glTexCoord3f(colors[12], colors[13], colors[14]);
415        glVertex3f(data->aa.x, data->aa.y, 0.0f);
416        glTexCoord3f(colors[15], colors[16], colors[17]);
417        glVertex3f(data->aa.x, data->bb.y, 0.0f);
418    glEnd();
419#endif
420
421    Advance();
422    ResetState();
423
424    /*
425     * Test #6: glBegin + apply texture in fragment shader
426     *
427     * Renders an animated black-and-white distorted checkerboard with a
428     * zoom ratio twice the one in test #3.
429     *
430     * Note: there is no need to glEnable(GL_TEXTURE_2D) when the
431     * texture lookup is done in a shader.
432     */
433#if defined HAVE_GLBEGIN || defined USE_GLEW
434    if (!shader[0])
435        shader[0] = Shader::Create(
436            "#version 110\n"
437            "void main()"
438            "{"
439            "    gl_TexCoord[0] = gl_MultiTexCoord0;"
440            "    gl_Position = gl_Vertex;"
441            "}",
442
443            "#version 110\n"
444            "uniform sampler2D tex;"
445            "void main()"
446            "{"
447            "    gl_FragColor = texture2D(tex, gl_TexCoord[0].xy * 0.25);"
448            "}");
449    shader[0]->Bind();
450    shader++;
451    glColor3f(0.0f, 1.0f, 1.0f);
452    glBindTexture(GL_TEXTURE_2D, data->texture[0]);
453    glBegin(GL_TRIANGLES);
454        glTexCoord2f(texcoords[0], texcoords[1]);
455        glVertex3f(data->aa.x, data->bb.y, 0.0f);
456        glTexCoord2f(texcoords[2], texcoords[3]);
457        glVertex3f(data->bb.x, data->bb.y, 0.0f);
458        glTexCoord2f(texcoords[4], texcoords[5]);
459        glVertex3f(data->bb.x, data->aa.y, 0.0f);
460
461        glTexCoord2f(texcoords[6], texcoords[7]);
462        glVertex3f(data->bb.x, data->aa.y, 0.0f);
463        glTexCoord2f(texcoords[8], texcoords[9]);
464        glVertex3f(data->aa.x, data->aa.y, 0.0f);
465        glTexCoord2f(texcoords[10], texcoords[11]);
466        glVertex3f(data->aa.x, data->bb.y, 0.0f);
467    glEnd();
468#endif
469
470    Advance();
471    ResetState();
472
473    /*
474     * Test #7: glBegin + GL_POINTS
475     *
476     * Renders a green sine wave made of 1-pixel points.
477     */
478#if defined HAVE_GLBEGIN || defined USE_GLEW
479    glColor3f(0.0f, 1.0f, 0.0f);
480    glPointSize(1.0f);
481
482    sine = data->GetSineArray();
483    glBegin(GL_POINTS);
484        for (int i = 0; i < data->npoints; i++)
485            glVertex3f(sine[i * 2], sine[i * 2 + 1], 0.0f);
486    glEnd();
487#endif
488
489    Advance();
490    ResetState();
491
492    /*
493     * Test #8: simple vertex buffer
494     *
495     * Renders an orange square.
496     */
497#if !defined __ANDROID__ && !defined __APPLE__
498    glColor4f(orange.x, orange.y, orange.z, orange.w);
499    glEnableClientState(GL_VERTEX_ARRAY);
500
501    glVertexPointer(3, GL_FLOAT, 0, data->GetVertexArray());
502    glDrawArrays(GL_TRIANGLES, 0, 6);
503
504    glDisableClientState(GL_VERTEX_ARRAY);
505#endif
506
507    Advance();
508    ResetState();
509
510    /*
511     * Test #9: simple point buffer
512     *
513     * Renders a green sine wave made of 1-pixel points.
514     */
515#if !defined __ANDROID__ && !defined __APPLE__
516    glColor4f(0.0f, 1.0f, 0.0f, 1.0f);
517    glPointSize(1.0f);
518    glEnableClientState(GL_VERTEX_ARRAY);
519
520    glVertexPointer(2, GL_FLOAT, 0, data->GetSineArray());
521    glDrawArrays(GL_POINTS, 0, data->npoints);
522
523    glDisableClientState(GL_VERTEX_ARRAY);
524#endif
525
526    Advance();
527    ResetState();
528
529    /*
530     * Test #10: vertex buffer + per-vertex coloring
531     *
532     * Renders a multicoloured square with varying colors.
533     */
534#if !defined __ANDROID__ && !defined __APPLE__
535    glEnableClientState(GL_VERTEX_ARRAY);
536    glEnableClientState(GL_COLOR_ARRAY);
537
538    glVertexPointer(3, GL_FLOAT, 0, data->GetVertexArray());
539    glColorPointer(3, GL_FLOAT, 0, colors);
540    glDrawArrays(GL_TRIANGLES, 0, 6);
541
542    glDisableClientState(GL_VERTEX_ARRAY);
543    glDisableClientState(GL_COLOR_ARRAY);
544#endif
545
546    Advance();
547    ResetState();
548
549    /*
550     * Test #11: vertex buffer + per-vertex coloring + texture
551     *
552     * Renders a multicoloured square with varying colors multiplied with an
553     * animated distorted checkerboard.
554     */
555#if !defined __ANDROID__ && !defined __APPLE__
556    glEnable(GL_TEXTURE_2D);
557    glBindTexture(GL_TEXTURE_2D, data->texture[0]);
558    glEnableClientState(GL_VERTEX_ARRAY);
559    glEnableClientState(GL_COLOR_ARRAY);
560    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
561
562    glVertexPointer(3, GL_FLOAT, 0, data->GetVertexArray());
563    glColorPointer(3, GL_FLOAT, 0, colors);
564    glTexCoordPointer(2, GL_FLOAT, 0, texcoords);
565
566    glDrawArrays(GL_TRIANGLES, 0, 6);
567
568    glDisableClientState(GL_VERTEX_ARRAY);
569    glDisableClientState(GL_COLOR_ARRAY);
570    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
571    glDisable(GL_TEXTURE_2D);
572#endif
573
574    Advance();
575    ResetState();
576
577    /*
578     * Test #12: vertex buffer + hardcoded color in 1.10 fragment shader
579     * (GLSL) or in Cg fragment shader (PS3)
580     *
581     * Renders an orange square.
582     */
583#if !defined __ANDROID__ && !defined __APPLE__
584    if (!shader[0])
585#if !defined __CELLOS_LV2__
586        shader[0] = Shader::Create(
587            "#version 110\n"
588            "void main()"
589            "{"
590            "    gl_Position = gl_Vertex;"
591            "}",
592
593            "#version 110\n"
594            "void main()"
595            "{"
596            "    gl_FragColor = vec4(0.8, 0.5, 0.2, 1.0);"
597            "}");
598#else
599        shader[0] = Shader::Create(
600            "void main(float4 in_Position : POSITION,"
601            "          out float4 out_Position : POSITION)"
602            "{"
603            "    out_Position = in_Position;"
604            "}",
605
606            "void main(out float4 out_FragColor : COLOR)"
607            "{"
608            "    out_FragColor = float4(0.8, 0.5, 0.2, 1.0);"
609            "}");
610#endif
611    shader[0]->Bind();
612    shader++;
613
614    glEnableClientState(GL_VERTEX_ARRAY);
615    glVertexPointer(3, GL_FLOAT, 0, data->GetVertexArray());
616    glDrawArrays(GL_TRIANGLES, 0, 6);
617    glDisableClientState(GL_VERTEX_ARRAY);
618#endif
619
620    Advance();
621    ResetState();
622
623    /*
624     * Test #13: vertex buffer + uniform color in 1.10 fragment shader
625     * (GLSL) or in Cg fragment shader (PS3)
626     *
627     * Renders an orange square.
628     */
629#if !defined __ANDROID__ && !defined __APPLE__
630    if (!shader[0])
631    {
632#if !defined __CELLOS_LV2__
633        shader[0] = Shader::Create(
634            "#version 110\n"
635            "void main()"
636            "{"
637            "    gl_Position = gl_Vertex;"
638            "}",
639
640            "#version 110\n"
641            "uniform vec4 in_Color;"
642            "void main()"
643            "{"
644            "    gl_FragColor = in_Color;"
645            "}");
646#else
647        shader[0] = Shader::Create(
648            "void main(float4 in_Position : POSITION,"
649            "          out float4 out_Position : POSITION)"
650            "{"
651            "    out_Position = in_Position;"
652            "}",
653
654            "uniform float4 in_Color;"
655            "void main(out float4 out_FragColor : COLOR)"
656            "{"
657            "    out_FragColor = in_Color;"
658            "}");
659#endif
660        uni[0] = shader[0]->GetUniformLocation("in_Color");
661    }
662    shader[0]->Bind();
663    shader[0]->SetUniform(uni[0], orange);
664    shader++;
665    uni++;
666
667    glEnableClientState(GL_VERTEX_ARRAY);
668    glVertexPointer(3, GL_FLOAT, 0, data->GetVertexArray());
669    glDrawArrays(GL_TRIANGLES, 0, 6);
670    glDisableClientState(GL_VERTEX_ARRAY);
671#endif
672
673    Advance();
674    ResetState();
675
676    /*
677     * Test #14: vertex buffer + color in 1.10 fragment shader (GLSL) or
678     * in Cg fragment shader (PS3)
679     *
680     * Renders a static, coloured and tiled pattern.
681     */
682#if !defined __ANDROID__ && !defined __APPLE__
683    if (!shader[0])
684#if !defined __CELLOS_LV2__
685        shader[0] = Shader::Create(
686            "#version 110\n"
687            "void main()"
688            "{"
689            "    gl_Position = gl_Vertex;"
690            "}",
691
692            "#version 110\n"
693            "void main()"
694            "{"
695            "    float dx = mod(gl_FragCoord.x * gl_FragCoord.y, 2.0);"
696            "    float dy = mod(gl_FragCoord.x * 0.125, 1.0);"
697            "    float dz = mod(gl_FragCoord.y * 0.125, 1.0);"
698            "    gl_FragColor = vec4(dx, dy, dz, 1.0);"
699            "}");
700#else
701        shader[0] = Shader::Create(
702            "void main(float4 in_Position : POSITION,"
703            "          out float4 out_Position : POSITION)"
704            "{"
705            "    out_Position = in_Position;"
706            "}",
707
708            "void main(float4 in_FragCoord : WPOS,"
709            "          out float4 out_FragColor : COLOR)"
710            "{"
711            "    float dx = frac(in_FragCoord.x * in_FragCoord.y * 0.5) * 2.0;"
712            "    float dy = frac(in_FragCoord.x * 0.125);"
713            "    float dz = frac(in_FragCoord.y * 0.125);"
714            "    out_FragColor = float4(dx, dy, dz, 1.0);"
715            "}");
716#endif
717    shader[0]->Bind();
718    shader++;
719
720    glEnableClientState(GL_VERTEX_ARRAY);
721    glVertexPointer(3, GL_FLOAT, 0, data->GetVertexArray());
722    glDrawArrays(GL_TRIANGLES, 0, 6);
723    glDisableClientState(GL_VERTEX_ARRAY);
724#endif
725
726    Advance();
727    ResetState();
728
729    /*
730     * Test #15: vertex buffer + uniform matrix for color transform in 1.10
731     * or Cg fragment shader
732     *
733     * Renders a multicoloured square with varying colors.
734     */
735#if !defined __ANDROID__ && !defined __APPLE__
736    if (!shader[0])
737    {
738#if !defined __CELLOS_LV2__
739        shader[0] = Shader::Create(
740            "#version 110\n"
741            "varying vec4 pass_Color;"
742            "uniform mat4 in_Matrix;"
743            "void main()"
744            "{"
745            "    gl_Position = gl_Vertex;"
746            "    pass_Color = in_Matrix * vec4(gl_MultiTexCoord0.xy, 0.0, 1.0);"
747            "}",
748
749            "#version 110\n"
750            "varying vec4 pass_Color;"
751            "void main()"
752            "{"
753            "    gl_FragColor = pass_Color;"
754            "}");
755#else
756        shader[0] = Shader::Create(
757            "void main(float4 in_Position : POSITION,"
758            "          float2 in_TexCoord : TEXCOORD0,"
759            "          uniform float4x4 in_Matrix,"
760            "          out float4 out_Color : COLOR,"
761            "          out float4 out_Position : POSITION)"
762            "{"
763            "    out_Position = in_Position;"
764            "    out_Color = mul(in_Matrix, float4(in_TexCoord, 0, 1));"
765            "}",
766
767            "void main(float4 in_Color : COLOR,"
768            "          out float4 out_FragColor : COLOR)"
769            "{"
770            "    out_FragColor = in_Color;"
771            "}");
772#endif
773        uni[0] = shader[0]->GetUniformLocation("in_Matrix");
774    }
775    shader[0]->Bind();
776    shader[0]->SetUniform(uni[0], t2);
777    shader++;
778    uni++;
779
780    glEnableClientState(GL_VERTEX_ARRAY);
781    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
782
783    glVertexPointer(3, GL_FLOAT, 0, data->GetVertexArray());
784    glTexCoordPointer(2, GL_FLOAT, 0, points);
785    glDrawArrays(GL_TRIANGLES, 0, 6);
786
787    glDisableClientState(GL_VERTEX_ARRAY);
788    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
789#endif
790
791    Advance();
792    ResetState();
793
794    /*
795     * Test #16: simple point buffer
796     *
797     * Renders an antialiased green sine wave made of 1-pixel points.
798     */
799#if !defined __ANDROID__ && !defined __APPLE__ && !defined __CELLOS_LV2__
800    if (!shader[0])
801        shader[0] = Shader::Create(
802            "#version 120\n"
803            "varying vec4 pass_Color;"
804            "void main()"
805            "{"
806            "    pass_Color = vec4(0.0, 1.0, 0.0, 1.0);"
807            "    gl_Position = gl_Vertex;"
808            "}",
809
810            "#version 120\n"
811            "varying vec4 pass_Color;"
812            "void main()"
813            "{"
814            "    vec2 d = gl_PointCoord.st - vec2(0.5, 0.5);"
815            "    float k = max(0.0, 2.0 * (0.5 - sqrt(dot(d, d))));"
816            "    gl_FragColor = vec4(pass_Color.xyz, k);"
817            "}");
818
819    shader[0]->Bind();
820    shader++;
821
822    glEnable(GL_POINT_SPRITE);
823    glEnable(GL_BLEND);
824    glTexEnvi(GL_POINT_SPRITE, GL_COORD_REPLACE, GL_TRUE);
825    glPointSize(3.0f);
826    glEnableClientState(GL_VERTEX_ARRAY);
827
828    glVertexPointer(2, GL_FLOAT, 0, data->GetSineArray());
829    glDrawArrays(GL_POINTS, 0, data->npoints);
830
831    glDisableClientState(GL_VERTEX_ARRAY);
832    glDisable(GL_POINT_SPRITE);
833    glTexEnvi(GL_POINT_SPRITE, GL_COORD_REPLACE, GL_FALSE);
834#endif
835
836    Advance();
837    ResetState();
838
839    /*
840     * Test #17: vertex buffer + texture & color in 1.10 fragment shader
841     *
842     * Renders a multicoloured square with varying colors xored with an
843     * animated distorted checkerboard.
844     */
845#if !defined __ANDROID__ && !defined __APPLE__
846    if (!shader[0])
847#if !defined __CELLOS_LV2__
848        shader[0] = Shader::Create(
849            "#version 110\n"
850            "varying vec4 pass_Color;"
851            "void main()"
852            "{"
853            "    gl_TexCoord[0] = gl_MultiTexCoord0;"
854            "    pass_Color = gl_Color;"
855            "    gl_Position = gl_Vertex;"
856            "}",
857
858            "#version 110\n"
859            "varying vec4 pass_Color;"
860            "uniform sampler2D tex;"
861            "void main()"
862            "{"
863            "    vec4 tmp = texture2D(tex, gl_TexCoord[0].xy * 0.25);"
864            "    gl_FragColor = vec4(abs(tmp.xyz - pass_Color.xyz), 1.0);"
865            "}");
866#else
867        shader[0] = Shader::Create(
868            "void main(float4 in_Position : POSITION,"
869            "          float2 in_TexCoord : TEXCOORD0,"
870            "          float4 in_Color : COLOR,"
871            "          out float4 out_Color : COLOR,"
872            "          out float4 out_Position : POSITION,"
873            "          out float2 out_TexCoord : TEXCOORD0)"
874            "{"
875            "    out_TexCoord = in_TexCoord;"
876            "    out_Color = in_Color;"
877            "    out_Position = in_Position;"
878            "}",
879
880            "void main(float2 in_TexCoord : TEXCOORD0,"
881            "          float4 in_Color : COLOR,"
882            "          uniform sampler2D tex,"
883            "          out float4 out_FragColor : COLOR)"
884            "{"
885            "    float4 tmp = tex2D(tex, in_TexCoord * 0.25);"
886            "    out_FragColor = float4(abs(tmp.xyz - in_Color.xyz), 1);"
887            "}");
888#endif
889
890    shader[0]->Bind();
891    shader++;
892
893    glBindTexture(GL_TEXTURE_2D, data->texture[0]);
894
895    glEnableClientState(GL_VERTEX_ARRAY);
896    glEnableClientState(GL_COLOR_ARRAY);
897    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
898
899    glVertexPointer(3, GL_FLOAT, 0, data->GetVertexArray());
900    glColorPointer(3, GL_FLOAT, 0, colors);
901    glTexCoordPointer(2, GL_FLOAT, 0, texcoords);
902    glDrawArrays(GL_TRIANGLES, 0, 6);
903
904    glDisableClientState(GL_VERTEX_ARRAY);
905    glDisableClientState(GL_COLOR_ARRAY);
906    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
907#endif
908
909    Advance();
910    ResetState();
911
912    /*
913     * Test #18: vertex buffer + texture & color in 1.20 fragment shader
914     *
915     * Renders a multicoloured square with varying colors xored with an
916     * animated distorted checkerboard.
917     */
918#if !defined __CELLOS_LV2__ && !defined __ANDROID__ && !defined __APPLE__
919    if (!shader[0])
920    {
921        shader[0] = Shader::Create(
922            "#version 120\n"
923            "attribute vec3 in_Vertex;"
924            "attribute vec3 in_Color;"
925            "attribute vec2 in_MultiTexCoord0;"
926            "varying vec4 pass_Color;"
927            "void main()"
928            "{"
929            "    gl_TexCoord[0] = vec4(in_MultiTexCoord0, 0.0, 0.0);"
930            "    pass_Color = vec4(in_Color, 1.0);"
931            "    gl_Position = vec4(in_Vertex, 1.0);"
932            "}",
933
934            "#version 120\n"
935            "varying vec4 pass_Color;"
936            "uniform sampler2D tex;"
937            "void main()"
938            "{"
939            "    vec4 tmp = texture2D(tex, gl_TexCoord[0].xy * 0.25);"
940            "    gl_FragColor = vec4(abs(tmp.xyz - pass_Color.xyz), 1.0);"
941            "}");
942        attr[0] = shader[0]->GetAttribLocation("in_Vertex");
943        attr[1] = shader[0]->GetAttribLocation("in_Color");
944        attr[2] = shader[0]->GetAttribLocation("in_MultiTexCoord0");
945    }
946    shader[0]->Bind();
947    shader++;
948
949    glBindTexture(GL_TEXTURE_2D, data->texture[0]);
950
951    glBindVertexArray(*array++);
952
953    glBindBuffer(GL_ARRAY_BUFFER, *buffer++);
954    glBufferData(GL_ARRAY_BUFFER, 3 * 6 * sizeof(GLfloat),
955                 data->GetVertexArray(), GL_DYNAMIC_DRAW);
956    glVertexAttribPointer(attr[0], 3, GL_FLOAT, GL_FALSE, 0, 0);
957    glEnableVertexAttribArray(attr[0]);
958
959    glBindBuffer(GL_ARRAY_BUFFER, *buffer++);
960    glBufferData(GL_ARRAY_BUFFER, sizeof(colors), colors,
961                 GL_DYNAMIC_DRAW);
962    glVertexAttribPointer(attr[1], 3, GL_FLOAT, GL_FALSE, 0, 0);
963    glEnableVertexAttribArray(attr[1]);
964
965    glBindBuffer(GL_ARRAY_BUFFER, *buffer++);
966    glBufferData(GL_ARRAY_BUFFER, sizeof(texcoords), texcoords,
967                 GL_DYNAMIC_DRAW);
968    glVertexAttribPointer(attr[2], 2, GL_FLOAT, GL_FALSE, 0, 0);
969    glEnableVertexAttribArray(attr[2]);
970
971    glDrawArrays(GL_TRIANGLES, 0, 6);
972    glBindVertexArray(0);
973
974    glDisableVertexAttribArray(*attr++);
975    glDisableVertexAttribArray(*attr++);
976    glDisableVertexAttribArray(*attr++);
977#endif
978
979    Advance();
980    ResetState();
981
982    /*
983     * Test #19: vertex buffer + texture & color in 1.30 fragment shader
984     *
985     * Renders a multicoloured square with varying colors xored with an
986     * animated distorted checkerboard.
987     */
988#if !defined __CELLOS_LV2__ && !defined __ANDROID__ && !defined __APPLE__
989    if (!shader[0])
990    {
991        shader[0] = Shader::Create(
992            "#version 130\n"
993            "in vec3 in_Vertex;"
994            "in vec3 in_Color;"
995            "in vec2 in_MultiTexCoord0;"
996            "out vec4 pass_Color;"
997            "void main()"
998            "{"
999            "    gl_TexCoord[0] = vec4(in_MultiTexCoord0, 0.0, 0.0);"
1000            "    pass_Color = vec4(in_Color, 1.0);"
1001            "    gl_Position = vec4(in_Vertex, 1.0);"
1002            "}",
1003
1004            "#version 130\n"
1005            "in vec4 pass_Color;"
1006            "uniform sampler2D tex;"
1007            "void main()"
1008            "{"
1009            "    vec4 tmp = texture2D(tex, gl_TexCoord[0].xy * 0.25);"
1010            "    gl_FragColor = vec4(abs(tmp.xyz - pass_Color.xyz), 1.0);"
1011            "}");
1012        attr[0] = shader[0]->GetAttribLocation("in_Vertex");
1013        attr[1] = shader[0]->GetAttribLocation("in_Color");
1014        attr[2] = shader[0]->GetAttribLocation("in_MultiTexCoord0");
1015    }
1016    shader[0]->Bind();
1017    shader++;
1018
1019    glBindTexture(GL_TEXTURE_2D, data->texture[0]);
1020
1021    glBindVertexArray(*array++);
1022
1023    glBindBuffer(GL_ARRAY_BUFFER, *buffer++);
1024    glBufferData(GL_ARRAY_BUFFER, 3 * 6 * sizeof(GLfloat),
1025                 data->GetVertexArray(), GL_DYNAMIC_DRAW);
1026    glVertexAttribPointer(attr[0], 3, GL_FLOAT, GL_FALSE, 0, 0);
1027    glEnableVertexAttribArray(attr[0]);
1028
1029    glBindBuffer(GL_ARRAY_BUFFER, *buffer++);
1030    glBufferData(GL_ARRAY_BUFFER, sizeof(colors), colors,
1031                 GL_DYNAMIC_DRAW);
1032    glVertexAttribPointer(attr[1], 3, GL_FLOAT, GL_FALSE, 0, 0);
1033    glEnableVertexAttribArray(attr[1]);
1034
1035    glBindBuffer(GL_ARRAY_BUFFER, *buffer++);
1036    glBufferData(GL_ARRAY_BUFFER, sizeof(texcoords), texcoords,
1037                 GL_DYNAMIC_DRAW);
1038    glVertexAttribPointer(attr[2], 2, GL_FLOAT, GL_FALSE, 0, 0);
1039    glEnableVertexAttribArray(attr[2]);
1040
1041    glDrawArrays(GL_TRIANGLES, 0, 6);
1042    glBindVertexArray(0);
1043
1044    glDisableVertexAttribArray(*attr++);
1045    glDisableVertexAttribArray(*attr++);
1046    glDisableVertexAttribArray(*attr++);
1047#endif
1048
1049    Advance();
1050    ResetState();
1051
1052    /* Check that we didn't overflow our list */
1053#if !defined __CELLOS_LV2__ && !defined __ANDROID__
1054    if (array > data->array + NUM_ARRAYS)
1055        Log::Error("too many arrays used\n");
1056#endif
1057    if (buffer > data->buffer + NUM_BUFFERS)
1058        Log::Error("too many buffers used\n");
1059    if (shader > data->shader + NUM_SHADERS)
1060        Log::Error("too many shaders used\n");
1061    if (attr > data->attr + NUM_ATTRS)
1062        Log::Error("too many attributes used\n");
1063}
1064
1065void DebugQuad::ResetState()
1066{
1067    /* Reset GL states to something reasonably safe */
1068
1069#if defined HAVE_GLBEGIN || defined USE_GLEW || defined __CELLOS_LV2__
1070    glMatrixMode(GL_PROJECTION);
1071    glLoadIdentity();
1072    glMatrixMode(GL_MODELVIEW);
1073    glLoadIdentity();
1074#endif
1075
1076#if !defined __ANDROID__ && !defined __APPLE__
1077    glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
1078#endif
1079
1080    glEnable(GL_TEXTURE_2D);
1081    glBindTexture(GL_TEXTURE_2D, 0);
1082#if defined HAVE_GLBEGIN || defined USE_GLEW || defined __CELLOS_LV2__
1083    glClientActiveTexture(GL_TEXTURE0);
1084#endif
1085#if !defined __CELLOS_LV2__ && !defined __ANDROID__ && !defined __APPLE__
1086    glTexEnvi(GL_POINT_SPRITE, GL_COORD_REPLACE, GL_FALSE);
1087#endif
1088    glDisable(GL_TEXTURE_2D);
1089
1090    glDisable(GL_BLEND);
1091#if !defined __CELLOS_LV2__ && !defined __ANDROID__ && !defined __APPLE__
1092    glDisable(GL_POINT_SPRITE);
1093#endif
1094
1095    glBindBuffer(GL_ARRAY_BUFFER, 0);
1096#if !defined __CELLOS_LV2__
1097    glUseProgram(0);
1098#else
1099    cgGLDisableProfile(cgGLGetLatestProfile(CG_GL_VERTEX));
1100    cgGLDisableProfile(cgGLGetLatestProfile(CG_GL_FRAGMENT));
1101#endif
1102
1103#if !defined __CELLOS_LV2__ && !defined __ANDROID__ && !defined __APPLE__
1104    glDisable(GL_VERTEX_PROGRAM_POINT_SIZE);
1105#endif
1106}
1107
1108} /* namespace lol */
1109
Note: See TracBrowser for help on using the repository browser.