source: trunk/src/debugquad.cpp @ 773

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

debug: add vertex shader examples to the debug quad.

  • Property svn:keywords set to Id
File size: 14.6 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
31#define NUM_SHADERS 3
32
33class DebugQuadData
34{
35    friend class DebugQuad;
36
37private:
38    vec2 orig, step, aa, bb;
39
40    int initialised;
41    float time;
42    GLuint buflist[3];
43    Shader *shader[NUM_SHADERS];
44    GLuint texlist[1];
45    uint8_t image[1][32 * 32 * 4];
46};
47
48/*
49 * Public DebugQuad class
50 */
51
52DebugQuad::DebugQuad()
53  : data(new DebugQuadData())
54{
55    data->initialised = 0;
56    data->time = RandF(10000.0f);
57
58    drawgroup = DRAWGROUP_HUD;
59}
60
61void DebugQuad::TickGame(float deltams)
62{
63    Entity::TickGame(deltams);
64
65    data->time += deltams;
66}
67
68void DebugQuad::TickDraw(float deltams)
69{
70    Entity::TickDraw(deltams);
71
72    if (!data->initialised && !IsDestroying())
73    {
74        glGenBuffers(3, data->buflist);
75
76        static char const *vertexshader =
77            "//#version 130\n"
78            "varying vec2 in_Position;\n"
79            "varying vec4 in_Color;\n"
80            "varying vec2 in_TexCoord;\n"
81            "varying vec4 pass_Color;\n"
82            "void main()\n"
83            "{\n"
84            "gl_TexCoord[0] = gl_MultiTexCoord0;\n"
85            "    gl_Position = vec4(in_Position, 0.0f, 1.0f);\n"
86            "    gl_TexCoord[0] = vec4(in_TexCoord, 0.0, 0.0);\n"
87            "    pass_Color = in_Color;\n"
88            "}\n";
89        static char const *fragmentshader =
90            "//#version 130\n"
91            "varying vec4 pass_Color;\n"
92            "uniform sampler2D in_Texture;\n"
93            "void main()\n"
94            "{\n"
95            "    vec4 col = pass_Color;\n"
96            "    vec4 tex = texture2D(in_Texture, vec2(gl_TexCoord[0]));\n"
97            "    gl_FragColor = col * tex;\n"
98            "    gl_FragColor = vec4(1.0, 1.0, 1.0, 0.0);\n"
99            "}\n";
100        data->shader[0] = Shader::Create(vertexshader, fragmentshader);
101        glGenTextures(1, data->texlist);
102
103        glEnable(GL_TEXTURE_2D);
104        glBindTexture(GL_TEXTURE_2D, data->texlist[0]);
105        for (int j = 0; j < 32; j++)
106            for (int i = 0; i < 32; i++)
107            {
108                uint8_t wb = (((i / 2) ^ (j / 2)) & 1) * 0xff;
109                data->image[0][(j * 32 + i) * 4 + 0] = wb;
110                data->image[0][(j * 32 + i) * 4 + 1] = wb;
111                data->image[0][(j * 32 + i) * 4 + 2] = wb;
112                data->image[0][(j * 32 + i) * 4 + 3] = 0xff;
113            }
114        /* Use GL_RGBA instead of 4 for the internal format (Android) */
115        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 32, 32, 0,
116                     GL_RGBA, GL_UNSIGNED_BYTE, data->image[0]);
117        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
118        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
119
120        /* Quad #4: create texture in fragment shader */
121        data->shader[0] = Shader::Create(
122            "#version 120\n"
123            "void main()"
124            "{"
125            "    gl_Position = gl_Vertex;"
126            "}",
127
128            "#version 120\n"
129            "void main()"
130            "{"
131            "    float dx = mod(gl_FragCoord.x * gl_FragCoord.y, 2.0);"
132            "    float dy = mod(gl_FragCoord.x * 0.125, 1.0);"
133            "    float dz = mod(gl_FragCoord.y * 0.125, 1.0);"
134            "    gl_FragColor = vec4(dx, dy, dz, 1.0);"
135            "}");
136
137        /* Quad #5: pass color from vertex shader to fragment shader */
138        data->shader[1] = Shader::Create(
139            "#version 120\n"
140            "varying vec4 color;"
141            "void main()"
142            "{"
143            "    float r = gl_MultiTexCoord0.x;"
144            "    float g = gl_MultiTexCoord0.y;"
145            "    color = vec4(1.0 - r, 1.0 - g, r, 1.0);"
146            "    gl_Position = gl_Vertex;"
147            "}",
148
149            "#version 120\n"
150            "varying vec4 color;"
151            "void main()"
152            "{"
153            "    gl_FragColor = color;"
154            "}");
155
156        /* Quad #6: apply texture in fragment shader */
157        /* Quad #8: vertex buffer, apply texture in fragment shader */
158        data->shader[2] = Shader::Create(
159            "void main()"
160            "{"
161            "    gl_TexCoord[0] = gl_MultiTexCoord0;"
162            "    gl_Position = gl_Vertex;"
163            "}",
164
165            "uniform sampler2D tex;"
166            "void main()"
167            "{"
168            "    gl_FragColor = texture2D(tex, gl_TexCoord[0].xy * 0.25);"
169            "}");
170
171        data->initialised = 1;
172    }
173    else if (data->initialised && IsDestroying())
174    {
175        glDeleteBuffers(3, data->buflist);
176        Shader::Destroy(data->shader[0]);
177        Shader::Destroy(data->shader[1]);
178        Shader::Destroy(data->shader[2]);
179        glDeleteTextures(1, data->texlist);
180
181        data->initialised = 0;
182    }
183
184    float const st = sinf(0.0005f * data->time);
185    float const ct = cosf(0.0005f * data->time);
186
187    GLfloat const verts[6][2] =
188    {
189        { -0.7f * (st + ct),  0.7f * (st - ct) },
190        {  0.7f * (st - ct),  0.7f * (st + ct) },
191        { -0.7f * (st - ct), -0.7f * (st + ct) },
192
193        { -0.7f * (st - ct), -0.7f * (st + ct) },
194        {  0.7f * (st - ct),  0.7f * (st + ct) },
195        {  0.7f * (st + ct), -0.7f * (st - ct) },
196    };
197
198    /* Using only 3 components breaks on Android for some reason. */
199    static GLfloat const cols[6][4] =
200    {
201        { 1.0f, 0.2f, 0.2f, 1.0f },
202        { 0.2f, 0.2f, 1.0f, 1.0f },
203        { 1.0f, 1.0f, 0.2f, 1.0f },
204
205        { 1.0f, 1.0f, 0.2f, 1.0f },
206        { 0.2f, 0.2f, 1.0f, 1.0f },
207        { 0.2f, 1.0f, 0.2f, 1.0f },
208    };
209
210    static GLfloat const tcs[6][2] =
211    {
212        { 0.0f, 1.0f }, { 1.0f, 1.0f }, { 0.0f, 0.0f },
213        { 0.0f, 0.0f }, { 1.0f, 1.0f }, { 1.0f, 0.0f },
214    };
215
216#if defined __CELLOS_LV2__
217    glEnableClientState(GL_VERTEX_ARRAY);
218    glEnableClientState(GL_COLOR_ARRAY);
219    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
220
221    glActiveTexture(GL_TEXTURE0);
222    glBindTexture(GL_TEXTURE_2D, data->texlist[0]);
223
224    glBindBuffer(GL_ARRAY_BUFFER, data->buflist[0]);
225    glBufferData(GL_ARRAY_BUFFER, 12 * sizeof(GLfloat), verts, GL_STATIC_DRAW);
226    glVertexPointer(2, GL_FLOAT, GL_FALSE, 0);
227
228    glBindBuffer(GL_ARRAY_BUFFER, data->buflist[1]);
229    glBufferData(GL_ARRAY_BUFFER, 24 * sizeof(GLfloat), cols, GL_STATIC_DRAW);
230    glColorPointer(4, GL_FLOAT, GL_FALSE, 0);
231
232    glBindBuffer(GL_ARRAY_BUFFER, data->buflist[2]);
233    glBufferData(GL_ARRAY_BUFFER, 12 * sizeof(GLfloat), tcs, GL_STATIC_DRAW);
234    glTexCoordPointer(2, GL_FLOAT, GL_FALSE, 0);
235
236    glDrawArrays(GL_TRIANGLES, 0, 6);
237
238    glDisableClientState(GL_VERTEX_ARRAY);
239    glDisableClientState(GL_COLOR_ARRAY);
240    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
241#else
242    data->shader[0]->Bind();
243    GLuint attr_pos, attr_col, attr_tex;
244    attr_pos = data->shader[0]->GetAttribLocation("in_Position");
245    attr_col = data->shader[0]->GetAttribLocation("in_Color");
246    attr_tex = data->shader[0]->GetAttribLocation("in_TexCoord");
247
248    glEnableVertexAttribArray(attr_pos);
249    glEnableVertexAttribArray(attr_col);
250    glEnableVertexAttribArray(attr_tex);
251
252    /* Bind texture */
253    glActiveTexture(GL_TEXTURE0);
254    glBindTexture(GL_TEXTURE_2D, data->texlist[0]);
255
256    glBindBuffer(GL_ARRAY_BUFFER, data->buflist[0]);
257    glBufferData(GL_ARRAY_BUFFER, 12 * sizeof(GLfloat), verts, GL_STATIC_DRAW);
258    glVertexAttribPointer(attr_pos, 2, GL_FLOAT, GL_FALSE, 0, 0);
259
260    glBindBuffer(GL_ARRAY_BUFFER, data->buflist[1]);
261    glBufferData(GL_ARRAY_BUFFER, 24 * sizeof(GLfloat), cols, GL_STATIC_DRAW);
262    glVertexAttribPointer(attr_col, 4, GL_FLOAT, GL_FALSE, 0, 0);
263
264    glBindBuffer(GL_ARRAY_BUFFER, data->buflist[2]);
265    glBufferData(GL_ARRAY_BUFFER, 12 * sizeof(GLfloat), tcs, GL_STATIC_DRAW);
266    glVertexAttribPointer(attr_tex, 2, GL_FLOAT, GL_FALSE, 0, 0);
267
268    glBindBuffer(GL_ARRAY_BUFFER, 0);
269
270    glDrawArrays(GL_TRIANGLES, 0, 6);
271
272    glDisableVertexAttribArray(attr_pos);
273    glDisableVertexAttribArray(attr_col);
274    glDisableVertexAttribArray(attr_tex);
275#endif
276
277    /* Reset GL states */
278    glMatrixMode(GL_PROJECTION);
279    glLoadIdentity();
280    glMatrixMode(GL_MODELVIEW);
281    glLoadIdentity();
282    glDisable(GL_TEXTURE_2D);
283    glBindBuffer(GL_ARRAY_BUFFER, 0);
284    glUseProgram(0);
285
286    /* Prepare our quad coordinates */
287    vec2i const layout(4, 3);
288    data->step = vec2(2.0f, -2.0f) / (3 * layout + vec2i(1));
289    data->orig = vec2(-1.0f, 1.0f) + data->step;
290    data->aa = data->orig;
291    data->bb = data->orig + 2.0f * data->step;
292
293    /* Generate a few random numbers */
294    float f1 = 0.5f + 0.5f * sinf(0.00034f * data->time);
295    float f2 = 0.5f + 0.5f * sinf(0.00053f * data->time + 1.0f);
296    float f3 = 0.5f + 0.5f * sinf(0.00072f * data->time + 4.0f);
297    float f4 = 0.5f + 0.5f * sinf(0.00091f * data->time + 8.0f);
298
299    /* Quad #1: simple glBegin program */
300    glColor3f(0.8f, 0.5f, 0.2f);
301    glBegin(GL_TRIANGLES);
302        glVertex3f(data->aa.x, data->bb.y, 0.0f);
303        glVertex3f(data->bb.x, data->bb.y, 0.0f);
304        glVertex3f(data->bb.x, data->aa.y, 0.0f);
305
306        glVertex3f(data->bb.x, data->aa.y, 0.0f);
307        glVertex3f(data->aa.x, data->aa.y, 0.0f);
308        glVertex3f(data->aa.x, data->bb.y, 0.0f);
309    glEnd();
310
311    Advance();
312
313    /* Quad #2: glBegin program with varying color */
314    glBegin(GL_TRIANGLES);
315        glColor3f(f1, f2, f3);
316        glVertex3f(data->aa.x, data->bb.y, 0.0f);
317        glColor3f(f4, f2, f1);
318        glVertex3f(data->bb.x, data->bb.y, 0.0f);
319        glColor3f(f3, f1, f4);
320        glVertex3f(data->bb.x, data->aa.y, 0.0f);
321
322        glVertex3f(data->bb.x, data->aa.y, 0.0f);
323        glColor3f(f4, f3, f2);
324        glVertex3f(data->aa.x, data->aa.y, 0.0f);
325        glColor3f(f1, f2, f3);
326        glVertex3f(data->aa.x, data->bb.y, 0.0f);
327    glEnd();
328
329    Advance();
330
331    /* Quad #3: textured quad */
332    glEnable(GL_TEXTURE_2D);
333    glBindTexture(GL_TEXTURE_2D, data->texlist[0]);
334    glColor3f(1.0f, 1.0f, 1.0f);
335    glBegin(GL_TRIANGLES);
336        glTexCoord2f(f1, f3);
337        glVertex3f(data->aa.x, data->bb.y, 0.0f);
338        glTexCoord2f(f3, f2);
339        glVertex3f(data->bb.x, data->bb.y, 0.0f);
340        glTexCoord2f(f2, f4);
341        glVertex3f(data->bb.x, data->aa.y, 0.0f);
342
343        glTexCoord2f(f2, f4);
344        glVertex3f(data->bb.x, data->aa.y, 0.0f);
345        glTexCoord2f(f4, f1);
346        glVertex3f(data->aa.x, data->aa.y, 0.0f);
347        glTexCoord2f(f1, f3);
348        glVertex3f(data->aa.x, data->bb.y, 0.0f);
349    glEnd();
350    glDisable(GL_TEXTURE_2D);
351
352    Advance();
353
354    /* Quad #4: set color in fragment shader */
355    data->shader[0]->Bind();
356    glColor3f(0.0f, 1.0f, 1.0f);
357    glBegin(GL_TRIANGLES);
358        glVertex3f(data->aa.x, data->bb.y, 0.0f);
359        glVertex3f(data->bb.x, data->bb.y, 0.0f);
360        glVertex3f(data->bb.x, data->aa.y, 0.0f);
361
362        glVertex3f(data->bb.x, data->aa.y, 0.0f);
363        glVertex3f(data->aa.x, data->aa.y, 0.0f);
364        glVertex3f(data->aa.x, data->bb.y, 0.0f);
365    glEnd();
366    glUseProgram(0);
367
368    Advance();
369
370    /* Quad #5: pass color from vertex shader to fragment shader */
371    data->shader[1]->Bind();
372    glColor3f(0.0f, 1.0f, 1.0f);
373    glBegin(GL_TRIANGLES);
374        glTexCoord2f(f1, f3);
375        glVertex3f(data->aa.x, data->bb.y, 0.0f);
376        glTexCoord2f(f3, f2);
377        glVertex3f(data->bb.x, data->bb.y, 0.0f);
378        glTexCoord2f(f2, f4);
379        glVertex3f(data->bb.x, data->aa.y, 0.0f);
380
381        glTexCoord2f(f2, f4);
382        glVertex3f(data->bb.x, data->aa.y, 0.0f);
383        glTexCoord2f(f4, f1);
384        glVertex3f(data->aa.x, data->aa.y, 0.0f);
385        glTexCoord2f(f1, f3);
386        glVertex3f(data->aa.x, data->bb.y, 0.0f);
387    glEnd();
388    glUseProgram(0);
389
390    Advance();
391
392    /* Quad #6: apply texture in fragment shader */
393    data->shader[2]->Bind();
394    glColor3f(0.0f, 1.0f, 1.0f);
395    glEnable(GL_TEXTURE_2D);
396    glBindTexture(GL_TEXTURE_2D, data->texlist[0]);
397    glBegin(GL_TRIANGLES);
398        glTexCoord2f(f1, f3);
399        glVertex3f(data->aa.x, data->bb.y, 0.0f);
400        glTexCoord2f(f3, f2);
401        glVertex3f(data->bb.x, data->bb.y, 0.0f);
402        glTexCoord2f(f2, f4);
403        glVertex3f(data->bb.x, data->aa.y, 0.0f);
404
405        glTexCoord2f(f2, f4);
406        glVertex3f(data->bb.x, data->aa.y, 0.0f);
407        glTexCoord2f(f4, f1);
408        glVertex3f(data->aa.x, data->aa.y, 0.0f);
409        glTexCoord2f(f1, f3);
410        glVertex3f(data->aa.x, data->bb.y, 0.0f);
411    glEnd();
412    glUseProgram(0);
413    glDisable(GL_TEXTURE_2D);
414
415    Advance();
416
417    /* Quad #7: simple vertex buffer */
418    GLfloat const v1[] = { data->aa.x, data->bb.y, 0.0f,
419                           data->bb.x, data->bb.y, 0.0f,
420                           data->bb.x, data->aa.y, 0.0f,
421                           data->bb.x, data->aa.y, 0.0f,
422                           data->aa.x, data->aa.y, 0.0f,
423                           data->aa.x, data->bb.y, 0.0f };
424    GLfloat const c1[] = { f1, f2, f3, f4, f2, f1, f3, f1, f4,
425                           f3, f1, f4, f4, f3, f2, f1, f2, f3 };
426
427    glEnableClientState(GL_COLOR_ARRAY);
428    glEnableClientState(GL_VERTEX_ARRAY);
429
430    glColorPointer(3, GL_FLOAT, 0, c1);
431    glVertexPointer(3, GL_FLOAT, 0, v1);
432    glDrawArrays(GL_TRIANGLES, 0, 6);
433
434    glDisableClientState(GL_VERTEX_ARRAY);
435    glDisableClientState(GL_COLOR_ARRAY);
436
437    Advance();
438
439    /* Quad #8: vertex buffer, apply texture in fragment shader */
440    data->shader[2]->Bind();
441    GLfloat const v2[] = { data->aa.x, data->bb.y, 0.0f,
442                           data->bb.x, data->bb.y, 0.0f,
443                           data->bb.x, data->aa.y, 0.0f,
444                           data->bb.x, data->aa.y, 0.0f,
445                           data->aa.x, data->aa.y, 0.0f,
446                           data->aa.x, data->bb.y, 0.0f };
447    GLfloat const t2[] = { f1, f3, f3, f2, f2, f4, f2, f4, f4, f1, f1, f3 };
448
449    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
450    glEnableClientState(GL_VERTEX_ARRAY);
451
452    glTexCoordPointer(2, GL_FLOAT, 0, t2);
453    glVertexPointer(3, GL_FLOAT, 0, v2);
454    glDrawArrays(GL_TRIANGLES, 0, 6);
455
456    glDisableClientState(GL_VERTEX_ARRAY);
457    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
458
459    Advance();
460
461}
462
463void DebugQuad::Advance()
464{
465    data->aa.x += 3.0f * data->step.x;
466    data->bb.x += 3.0f * data->step.x;
467    if (data->bb.x > 1.0f)
468    {
469        data->aa.x = data->orig.x;
470        data->bb.x = data->orig.x + 2.0f * data->step.x;
471        data->aa.y += 3.0f * data->step.y;
472        data->bb.y += 3.0f * data->step.y;
473    }
474}
475
476DebugQuad::~DebugQuad()
477{
478    delete data;
479}
480
481} /* namespace lol */
482
Note: See TracBrowser for help on using the repository browser.