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

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

shader: factor the uniform handling logic into platform-independent methods
for both OpenGL and the PS3.

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