source: trunk/tools/neercs/video/render.cpp @ 2043

Last change on this file since 2043 was 2043, checked in by rez, 8 years ago

neercs: early integration of theme support

File size: 51.9 KB
Line 
1//
2// Neercs
3//
4
5#if defined HAVE_CONFIG_H
6#   include "config.h"
7#endif
8
9#if defined _XBOX
10#   define _USE_MATH_DEFINES /* for M_PI */
11#   include <xtl.h>
12#elif defined _WIN32
13#   define _USE_MATH_DEFINES /* for M_PI */
14#   define WIN32_LEAN_AND_MEAN
15#   include <windows.h>
16#endif
17
18#include <cmath>
19#include <cstdio>
20#include <cstdlib>
21#include <ctime>
22#include <string>
23
24#include "core.h"
25#include "lolgl.h"
26#include "loldebug.h"
27
28using namespace std;
29using namespace lol;
30
31#include "../neercs.h"
32#include "render.h"
33#include "text-render.h"
34
35extern char const *lolfx_simple;
36extern char const *lolfx_blurh;
37extern char const *lolfx_blurv;
38extern char const *lolfx_glow;
39extern char const *lolfx_remanence;
40extern char const *lolfx_copper;
41extern char const *lolfx_color;
42extern char const *lolfx_noise;
43extern char const *lolfx_postfx;
44extern char const *lolfx_mirror;
45extern char const *lolfx_radial;
46
47#define PID M_PI/180.0f    // pi ratio
48
49/*
50 * Global variable -- ugly (<rez> sam: c'est toi qui est ugly! \:D/)
51 */
52bool g_setup = false;
53
54/*
55 * Various variables
56 */
57
58int active = true;         // window active flag
59float nearplane = 0.1f;    // nearplane
60float farplane = 1000.0f;  // farplane
61/* timer variable */
62float timer = 0;           // timer
63/* window variable */
64ivec2 screen_size;         // screen size
65/* object variable */
66float main_angle = 0.0f;   // main angle
67float part_angle = 0.0f;   // part angle
68float fx_angle;            // current angle
69/* fs_quad variable */
70float fs_quad_vtx[] = {-1.0f, 1.0f, 0, 1.0f, -1.0f, -1.0f, 0, 1.0f, 1.0f, -1.0f, 0, 1.0f, 1.0f, 1.0f, 0, 1.0f};
71float fs_quad_tex[] = {0, 1.0f, 0, 0, 1.0f, 0, 1.0f, 1.0f};
72/* flash variable */
73bool flash_flag = false;   // flag
74float flash_angle = 0;     // angle
75float flash_value = 0;     // value
76float flash_speed = 2.0f;  // speed
77/* fade variable */
78bool fade_flag = false;    // flag
79float fade_angle = 0;      // angle
80float fade_value = 0;      // value
81float fade_speed = 0.2f;   // speed
82/* sync variable */
83bool sync_flag = false;    // flagsh
84float sync_angle = 0;      // angle
85float sync_value = 0;      // value
86float sync_speed = 1.0f;   // speed
87/* beat variable */
88bool beat_flag = false;    // flag
89float beat_angle = 0;      // angle
90float beat_value = 0;      // value
91float beat_speed = 2.0f;   // speed
92/* common variable */
93float value, angle, radius, scale, speed;
94/* text variable */
95ivec2 map_size(256,256);        // texture map size
96ivec2 canvas_char(0,0);         // canvas char number
97ivec2 canvas_size(0,0);         // caca size
98ivec2 font_size(8,8);           // font size
99ivec2 ratio_2d(1,1);            // 2d ratio
100ivec2 border(0,0);              // border width
101/* shader variable */
102vec2 buffer(1.0f,0.0f);         // [new frame mix,old frame mix]
103vec2 remanence(0.0f,0.0f);      // remanence [source mix,buffer mix]
104vec2 glow_mix(0.7f,0.3f);       // glow mix [source mix,glow mix]
105vec2 glow_large(3.0f,0.0f);     // large glow radius [center,corner]
106vec2 glow_small(1.5f,0.0f);     // small glow radius [center,corner]
107vec2 blur(0.5f,0.0f);           // blur radius [center,corner]
108vec4 copper_copper(0.75f,0.25f,0.42f,4.0f);     // copper [base,variable,repeat,color cycle]
109vec3 copper_mask_color(4.0f,4.0f,4.0f);         // color [red,green,blue]
110vec3 color_filter(0.9f,0.95f,0.85f);            // color filter [red,green,blue]
111vec4 color_color(1.0f,1.25f,0.1f,0.4f);         // color modifier [brightness,contrast,level,grayscale]
112vec2 noise_offset(1.0f,1.0f);                   // random line [horizontal,vertical]
113float noise_noise = 0.15f;                      // noise
114vec3 noise_retrace(1.0f,1.0f,0.5f);             // retrace [strength,length,speed]
115vec2 postfx_deform(0.8f,0.48f);                 // deformation [ratio,zoom]
116float postfx_vignetting = 0.5f;                 // vignetting strength
117float postfx_aberration = 4.0f;                 // chromatic aberration
118vec4 postfx_ghost1(1.0f,0.0f,0.0f,-0.25f);      // ghost picture 1 [position x,position y,position z,strength]
119vec4 postfx_ghost2(1.5f,0.0f,0.0f,0.25f);       // ghost picture 2 [position x,position y,position z,strength]
120vec4 postfx_glass(8.0f,0.25f,0.75f,0.2f);       // glass [depth,thickness,strength,deform ratio]
121vec4 postfx_moire_h(0.75f,-0.25f,0.0f,1.0f);    // vertical moire [base,variable,repeat,shift]
122vec4 postfx_moire_v(0.75f,-0.25f,1.0f,2.0f);    // horizontal moire [base,variable,repeat,shift]
123vec4 postfx_scanline_h(1.0f,0.0f,0.0f,0.0f);    // vertical scanline [base,variable,repeat,shift]
124vec4 postfx_scanline_v(0.75f,-0.25f,2.0f,0.0f); // horizontal scanline [base,variable,repeat,shift]
125vec3 postfx_corner(0.0f,0.8f,0.96f);            // corner [width,radius,blur]
126vec4 mirror(0.95f,0.9f,0.4f,4.0f);              // mirror [width,height,strength,ratio]
127vec4 radial(4.0f,0.9f,16,0.25f);                // radial [distance,fade ratio,iteration,strength]
128/* theme variable */
129int theme_i = 0;                // current theme
130int theme_n = 2;                // theme number
131int theme_var_n = 79;           // var number
132/* setup variable */
133bool setup_switch = false;      // switch [option/item]
134int setup_n = 0;                // item/option number
135int setup_h = 8;                // height
136int setup_cursor = 0;           // cursor position
137int setup_option_i = 0;         // selected option
138int setup_option_n = 14;        // option number
139int setup_option_p = 0;         // option position
140int setup_item_i = 0;           // selected item
141int setup_item_n = 8;           // item number
142int setup_item_p = 0;           // item position
143int setup_item_key = 0;         // item array key
144ivec3 setup_size(29,9,12);      // size [w,h,split]
145ivec2 setup_canvas_size(ivec2(setup_size.x + 1, setup_size.y + 1) * font_size * ivec2(2,4));
146ivec2 setup_color(0xaaa,0x222); // color [foreground,background] 0x678,0x234
147char const *setup_text[]={
148    "main",
149        "2d ratio w",
150        "2d ratio h",
151        "border w",
152        "border h",
153        "",
154        "",
155        "",
156        "",
157    "remanence",
158        "enable",
159        "buffer new frame",
160        "buffer old frame",
161        "source mix",
162        "buffer mix",
163        "",
164        "",
165        "",
166    "glow",
167        "enable",
168        "source mix",
169        "glow mix",
170        "large center",
171        "large corner",
172        "small center",
173        "small corner",
174        "",
175    "blur",
176        "enable",
177        "blur center",
178        "blur corner",
179        "",
180        "",
181        "",
182        "",
183        "",
184    "screen",
185        "enable",
186        "deform ratio",
187        "zoom base",
188        "corner width",
189        "corner radius",
190        "corner blur",
191        "vignetting",
192        "",
193    "copper",
194        "enable",
195        "base",
196        "variable",
197        "repeat",
198        "color cycle",
199        "color r",
200        "color g",
201        "color b",
202    "color",
203        "filter red",
204        "filter green",
205        "filter blue",
206        "brightness",
207        "contrast",
208        "level",
209        "grayscale",
210        "aberration",
211    "noise",
212        "enable",
213        "offset h",
214        "offset v",
215        "noise",
216        "retrace strength",
217        "retrace length",
218        "retrace speed",
219        "",
220    "ghost",
221        "back x",
222        "back y",
223        "back z",
224        "back strength",
225        "front x",
226        "front y",
227        "front z",
228        "front strength",
229    "glass",
230        "depth",
231        "thickness",
232        "strength",
233        "deform ratio",
234        "",
235        "",
236        "",
237        "",
238    "moire",
239        "h base",
240        "h variable",
241        "h repeat",
242        "h shift",
243        "v base",
244        "v variable",
245        "v repeat",
246        "v shift",
247    "scanline",
248        "h base",
249        "h variable",
250        "h repeat",
251        "h shift",
252        "v base",
253        "v variable",
254        "v repeat",
255        "v shift",
256    "mirror",
257        "enable",
258        "width",
259        "height",
260        "strength",
261        "ratio",
262        "",
263        "",
264        "",
265    "radial",
266        "enable",
267        "distance",
268        "fade ratio",
269        "iteration",
270        "strength",
271        "",
272        "",
273        ""
274    };
275
276float theme_var[]={
277    /* default */
278    2,3,                      // ratio_2d
279    2,1,                      // border
280    0.2f,0.8f,                // buffer
281    0.6f,0.4f,                // remanence
282    0.7f,0.3f,                // glow_mix
283    3.0f,0.0f,                // glow_large
284    1.5f,0.0f,                // glow_small
285    0.5f,0.0f,                // blur
286    0.8f,0.48f,               // postfx_deform
287    0.0f,0.8f,0.96f,          // postfx_corner
288    0.5f,                     // postfx_vignetting
289    0.75f,0.25f,0.42f,4.0f,   // copper_copper
290    4.0f,4.0f,4.0f,           // copper_mask_color
291    0.9f,0.95f,0.85f,         // color_filter
292    1.0f,1.25f,0.1f,0.4f,     // color_color
293    4.0f,                     // postfx_aberration
294    1.0f,1.0f,                // noise_offset
295    0.15f,                    // noise_noise
296    1.0f,1.0f,0.5f,           // noise_retrace
297    1.0f,0.0f,0.0f,-0.25f,    // postfx_ghost1
298    1.5f,0.0f,0.0f,0.25f,     // postfx_ghost2
299    8.0f,0.25f,0.75f,0.2f,    // postfx_glass
300    0.75f,-0.25f,0.0f,1.0f,   // postfx_moire_h
301    0.75f,-0.25f,1.0f,2.0f,   // postfx_moire_v
302    1.0f,0.0f,0.0f,0.0f,      // postfx_scanline_h
303    0.75f,-0.25f,2.0f,0.0f,   // postfx_scanline_v
304    0.95f,0.9f,0.4f,4.0f,     // mirror
305    4.0f,0.9f,16,0.25f,       // radial
306    /* crt */
307    /* green screen */
308    /* granpa tv */
309    0.0f
310    };
311
312void Render::InitVar()
313{
314    int k = theme_i * theme_var_n;
315    ratio_2d = vec2(theme_var[k], theme_var[k + 1]);
316    border = vec2(theme_var[k + 2], theme_var[k + 3]);
317    buffer = vec2(theme_var[k + 4], theme_var[k + 5]);
318    remanence = vec2(theme_var[k + 6], theme_var[k + 7]);
319    glow_mix = vec2(theme_var[k + 8], theme_var[k + 9]);
320    glow_large = vec2(theme_var[k + 10], theme_var[k + 11]);
321    glow_small = vec2(theme_var[k + 12], theme_var[k + 13]);
322    blur = vec2(theme_var[k + 14], theme_var[k + 15]);
323    postfx_deform = vec2(theme_var[k + 16], theme_var[k + 17]);
324    postfx_corner = vec3(theme_var[k + 18], theme_var[k + 19], theme_var[k + 20]);
325    postfx_vignetting = theme_var[k + 21],
326    copper_copper = vec4(theme_var[k + 22], theme_var[k + 23], theme_var[k + 24], theme_var[k + 25]);
327    copper_mask_color = vec3(theme_var[k + 26], theme_var[k + 27], theme_var[k + 28]);
328    color_filter = vec3(theme_var[k + 29], theme_var[k + 30], theme_var[k + 31]);
329    color_color = vec4(theme_var[k + 32], theme_var[k + 33], theme_var[k + 34], theme_var[k + 35]);
330    postfx_aberration = theme_var[k + 36];
331    noise_offset = vec2(theme_var[k + 37], theme_var[k + 38]);
332    noise_noise = theme_var[k + 39];
333    noise_retrace = vec3(theme_var[k + 40], theme_var[k + 41], theme_var[k + 42]);
334    postfx_ghost1 = vec4(theme_var[k + 43], theme_var[k + 44], theme_var[k + 45], theme_var[k + 46]);
335    postfx_ghost2 = vec4(theme_var[k + 47], theme_var[k + 48], theme_var[k + 49], theme_var[k + 50]);
336    postfx_glass = vec4(theme_var[k + 51], theme_var[k + 52], theme_var[k + 53], theme_var[k + 54]);
337    postfx_moire_h = vec4(theme_var[k + 55], theme_var[k + 56], theme_var[k + 57], theme_var[k + 58]);
338    postfx_moire_v = vec4(theme_var[k + 59], theme_var[k + 60], theme_var[k + 61], theme_var[k + 62]);
339    postfx_scanline_h = vec4(theme_var[k + 63], theme_var[k + 64], theme_var[k + 65], theme_var[k + 66]);
340    postfx_scanline_v = vec4(theme_var[k + 67], theme_var[k + 68], theme_var[k + 69], theme_var[k + 70]);
341    mirror = vec4(theme_var[k + 71], theme_var[k + 72], theme_var[k + 73], theme_var[k + 74]);
342    radial = vec4(theme_var[k + 75], theme_var[k + 76], theme_var[k + 77], theme_var[k + 78]);
343}
344
345vec4 setup_var[]={ // setup variable [start,end,step,value]
346    vec4(0), /* main */
347        vec4(1,  8, 1, ratio_2d.x),
348        vec4(1,  8, 1, ratio_2d.y),
349        vec4(0, 16, 1, border.x),
350        vec4(0, 16, 1, border.y),
351        vec4(0),
352        vec4(0),
353        vec4(0),
354        vec4(0),
355    vec4(0), /* remanence */
356        vec4(0, 1, 1, 1),
357        vec4(0.0f, 1.0f, 0.1f, buffer.x),
358        vec4(0.0f, 1.0f, 0.1f, buffer.y),
359        vec4(0.0f, 1.0f, 0.1f, remanence.x),
360        vec4(0.0f, 1.0f, 0.1f, remanence.y),
361        vec4(0),
362        vec4(0),
363        vec4(0),
364    vec4(0), /* glow */
365        vec4(0, 1, 1, 1),
366        vec4(0.0f, 1.0f, 0.1f, glow_mix.x),
367        vec4(0.0f, 1.0f, 0.1f, glow_mix.y),
368        vec4(0.0f, 4.0f, 0.1f, glow_large.x),
369        vec4(0.0f, 4.0f, 0.1f, glow_large.y),
370        vec4(0.0f, 2.0f, 0.1f, glow_small.x),
371        vec4(0.0f, 2.0f, 0.1f, glow_small.y),
372        vec4(0),
373    vec4(0), /* blur */
374        vec4(0, 1, 1, 1),
375        vec4(0, 2, 0.05f, blur.x),
376        vec4(0, 2, 0.05f, blur.y),
377        vec4(0),
378        vec4(0),
379        vec4(0),
380        vec4(0),
381        vec4(0),
382    vec4(0), /* screen */
383        vec4(0, 1, 1, 1),
384        vec4(0.0f, 1.0f, 0.05f, postfx_deform.x),
385        vec4(0.2f, 0.7f, 0.01f, postfx_deform.y),
386        vec4(0.0f, 4.0f, 0.10f, postfx_corner.x),
387        vec4(0.0f, 1.0f, 0.05f, postfx_corner.y),
388        vec4(0.8f, 1.0f, 0.01f, postfx_corner.z),
389        vec4(0.0f, 1.0f, 0.10f, postfx_vignetting),
390        vec4(0),
391    vec4(0), /* copper */
392        vec4(0, 1, 1, 1),
393        vec4(0.0f, 1.0f, 0.05f, copper_copper.x),
394        vec4(0.0f, 1.0f, 0.05f, copper_copper.y),
395        vec4(0.0f, 1.0f, 0.02f, copper_copper.z),
396        vec4(1.0f, 8.0f, 0.25f, copper_copper.w),
397        vec4(0.0f, 4.0f, 0.25f, copper_mask_color.x),
398        vec4(0.0f, 4.0f, 0.25f, copper_mask_color.y),
399        vec4(0.0f, 4.0f, 0.25f, copper_mask_color.z),
400    vec4(0), /* color */
401        vec4( 0.0f, 1.0f, 0.05f, color_filter.x),
402        vec4( 0.0f, 1.0f, 0.05f, color_filter.y),
403        vec4( 0.0f, 1.0f, 0.05f, color_filter.z),
404        vec4( 0.0f, 2.0f, 0.05f, color_color.x),
405        vec4( 0.0f, 2.0f, 0.05f, color_color.y),
406        vec4(-1.0f, 1.0f, 0.05f, color_color.z),
407        vec4( 0.0f, 1.0f, 0.05f, color_color.w),
408        vec4( 0.0f, 8.0f, 0.50f, postfx_aberration),
409    vec4(0), /* noise */
410        vec4(0, 1, 1, 1),
411        vec4(0.0f, 4.0f, 0.50f, noise_offset.x),
412        vec4(0.0f, 4.0f, 0.50f, noise_offset.y),
413        vec4(0.0f, 0.5f, 0.05f, noise_noise),
414        vec4(0.0f, 4.0f, 0.25f, noise_retrace.x),
415        vec4(0.0f, 8.0f, 0.50f, noise_retrace.y),
416        vec4(0.0f, 4.0f, 0.25f, noise_retrace.z),
417        vec4(0),
418    vec4(0), /* ghost */
419        vec4(-2.0f, 2.0f, 0.10f, postfx_ghost1.x),
420        vec4(-2.0f, 2.0f, 0.10f, postfx_ghost1.y),
421        vec4(-2.0f, 2.0f, 0.10f, postfx_ghost1.z),
422        vec4(-1.0f, 1.0f, 0.05f, postfx_ghost1.w),
423        vec4(-2.0f, 2.0f, 0.10f, postfx_ghost2.x),
424        vec4(-2.0f, 2.0f, 0.10f, postfx_ghost2.y),
425        vec4(-2.0f, 2.0f, 0.10f, postfx_ghost2.z),
426        vec4(-1.0f, 1.0f, 0.05f, postfx_ghost2.w),
427    vec4(0), /* glass */
428        vec4(0.0f, 16.0f, 0.50f, postfx_glass.x),
429        vec4(0.0f,  1.0f, 0.05f, postfx_glass.y),
430        vec4(0.0f,  2.0f, 0.05f, postfx_glass.z),
431        vec4(0.0f,  1.0f, 0.05f, postfx_glass.w),
432        vec4(0),
433        vec4(0),
434        vec4(0),
435        vec4(0),
436    vec4(0), /* moire */
437        vec4( 0.5f, 1.0f, 0.05f, postfx_moire_h.x),
438        vec4(-0.5f, 0.5f, 0.05f, postfx_moire_h.y),
439        vec4( 0.0f, 4.0f, 0.50f, postfx_moire_h.z),
440        vec4( 0.0f, 4.0f, 0.50f, postfx_moire_h.w),
441        vec4( 0.5f, 1.0f, 0.05f, postfx_moire_v.x),
442        vec4(-0.5f, 0.5f, 0.05f, postfx_moire_v.y),
443        vec4( 0.0f, 4.0f, 0.50f, postfx_moire_v.z),
444        vec4( 0.0f, 4.0f, 0.50f, postfx_moire_v.w),
445    vec4(0), /* scanline */
446        vec4( 0.5f, 1.0f, 0.05f, postfx_scanline_h.x),
447        vec4(-0.5f, 0.5f, 0.05f, postfx_scanline_h.y),
448        vec4( 0.0f, 4.0f, 0.50f, postfx_scanline_h.z),
449        vec4( 0.0f, 4.0f, 0.50f, postfx_scanline_h.w),
450        vec4( 0.5f, 1.0f, 0.05f, postfx_scanline_v.x),
451        vec4(-0.5f, 0.5f, 0.05f, postfx_scanline_v.y),
452        vec4( 0.0f, 4.0f, 0.50f, postfx_scanline_v.z),
453        vec4( 0.0f, 4.0f, 0.50f, postfx_scanline_v.w),
454    vec4(0), /* mirror */
455        vec4(0, 1, 1, 1),
456        vec4(0.0f, 2.0f, 0.05f, mirror.x),
457        vec4(0.0f, 2.0f, 0.05f, mirror.y),
458        vec4(0.0f, 1.0f, 0.05f, mirror.z),
459        vec4(1.0f, 8.0f, 1.00f, mirror.w),
460        vec4(0),
461        vec4(0),
462        vec4(0),
463    vec4(0), /* radial blur */
464        vec4(0, 1, 1, 1),
465        vec4(2.0f, 8.0f, 0.25f, radial.x),
466        vec4(0.8f, 1.0f, 0.01f, radial.y),
467        vec4(2.0f,32.0f, 2.00f, radial.z),
468        vec4(0.0f, 1.0f, 0.05f, radial.w),
469        vec4(0),
470        vec4(0),
471        vec4(0),
472    vec4(0) /* ? */
473    };
474
475void Render::UpdateVar()
476{
477    int k = 1; /* main */
478    ratio_2d = vec2(setup_var[k].w, setup_var[k + 1].w); k += 2;
479    border = vec2(setup_var[k].w, setup_var[k + 1].w); k += 2;
480    k += 5; /* remanence */
481    m_shader_remanence = (setup_var[k].w == 1) ? true : false; k++;
482    buffer = vec2(setup_var[k].w, setup_var[k + 1].w); k += 2;
483    remanence = vec2(setup_var[k].w, setup_var[k + 1].w); k += 2;
484    k += 4; /* glow */
485    m_shader_glow = (setup_var[k].w == 1) ? true : false; k++;
486    glow_mix = vec2(setup_var[k].w, setup_var[k + 1].w); k += 2;
487    glow_large = vec2(setup_var[k].w, setup_var[k + 1].w); k += 2;
488    glow_small = vec2(setup_var[k].w, setup_var[k + 1].w); k += 2;
489    k += 2; /* blur */
490    m_shader_blur = (setup_var[k].w == 1) ? true : false; k++;
491    blur = vec2(setup_var[k].w, setup_var[k + 1].w); k += 2;
492    k += 6; /* screen */
493    m_shader_postfx = (setup_var[k].w == 1) ? true : false; k++;
494    postfx_deform = vec2(setup_var[k].w, setup_var[k + 1].w); k += 2;
495    postfx_corner = vec3(setup_var[k].w, setup_var[k + 1].w, setup_var[k + 2].w); k += 3;
496    postfx_vignetting = setup_var[k].w; k++;
497    k += 2; /* copper */
498    m_shader_copper = (setup_var[k].w == 1) ? true : false; k++;
499    copper_copper = vec4(setup_var[k].w, setup_var[k + 1].w, setup_var[k + 2].w, setup_var[k + 3].w); k += 4;
500    copper_mask_color = vec3(setup_var[k].w, setup_var[k + 1].w, setup_var[k + 2].w); k += 3;
501    k += 1; /* color */
502    color_filter = vec3(setup_var[k].w, setup_var[k + 1].w, setup_var[k + 2].w); k += 3;
503    color_color = vec4(setup_var[k].w, setup_var[k + 1].w, setup_var[k + 2].w, setup_var[k + 3].w); k += 4;
504    postfx_aberration = setup_var[k].w; k++;
505    k += 1; /* noise */
506    m_shader_noise = (setup_var[k].w == 1) ? true : false; k++;
507    noise_offset = vec2(setup_var[k].w, setup_var[k + 1].w); k += 2;
508    noise_noise = setup_var[k].w; k++;
509    noise_retrace = vec3(setup_var[k].w, setup_var[k + 1].w, setup_var[k + 2].w); k += 3;
510    k += 2; /* ghost */
511    postfx_ghost1 = vec4(setup_var[k].w, setup_var[k + 1].w, setup_var[k + 2].w, setup_var[k + 3].w); k += 4;
512    postfx_ghost2 = vec4(setup_var[k].w, setup_var[k + 1].w, setup_var[k + 2].w, setup_var[k + 3].w); k += 4;
513    k += 1; /* glass */
514    postfx_glass = vec4(setup_var[k].w, setup_var[k + 1].w, setup_var[k + 2].w, setup_var[k + 3].w); k += 4;
515    k += 5; /* moire */
516    postfx_moire_h = vec4(setup_var[k].w, setup_var[k + 1].w, setup_var[k + 2].w, setup_var[k + 3].w); k += 4;
517    postfx_moire_v = vec4(setup_var[k].w, setup_var[k + 1].w, setup_var[k + 2].w, setup_var[k + 3].w); k += 4;
518    k += 1; /* scanline */
519    postfx_scanline_h = vec4(setup_var[k].w, setup_var[k + 1].w, setup_var[k + 2].w, setup_var[k + 3].w); k += 4;
520    postfx_scanline_v = vec4(setup_var[k].w, setup_var[k + 1].w, setup_var[k + 2].w, setup_var[k + 3].w); k += 4;
521    k += 1; /* mirror */
522    m_shader_mirror = (setup_var[k].w == 1) ? true : false; k++;
523    mirror = vec4(setup_var[k].w, setup_var[k + 1].w, setup_var[k + 2].w, setup_var[k + 3].w); k += 4;
524    k += 4; /* radial blur */
525    m_shader_radial = (setup_var[k].w == 1) ? true : false; k++;
526    radial = vec4(setup_var[k].w, setup_var[k + 1].w, setup_var[k + 2].w, setup_var[k + 3].w); k += 4;
527    UpdateSize();
528}
529
530void Render::UpdateSize()
531{
532    screen_size = Video::GetSize();
533    canvas_char = (screen_size - border * ratio_2d * font_size * 2) / (font_size * ratio_2d);
534    canvas_char = max(canvas_char, ivec2(1, 1));
535    canvas_size = canvas_char * font_size * ratio_2d;
536
537    border = (screen_size - canvas_size) / 2;
538
539    caca_set_canvas_size(m_cv_screen, canvas_char.x, canvas_char.y);
540    caca_set_canvas_size(m_cv_setup, setup_size.x + 1, setup_size.y + 1);
541}
542
543int calc_item_length()
544{
545    int n = !setup_switch ? setup_option_n : setup_item_n;
546    for (int i = 0; i < n; i++)
547    {
548        int k = !setup_switch ? (i * (setup_item_n + 1)) : (setup_option_i * (setup_item_n + 1) + 1 + i);
549        if (setup_text[k][0] == '\0') return i - 1;
550    }
551    return n - 1;
552}
553
554Shader *shader_simple;
555Shader *shader_blur_h, *shader_blur_v, *shader_glow;
556Shader *shader_remanence, *shader_copper, *shader_color;
557Shader *shader_noise, *shader_postfx, *shader_mirror, *shader_radial;
558// shader variables
559ShaderUniform shader_simple_texture;
560ShaderUniform shader_blur_h_texture,
561              shader_blur_h_radius,
562              shader_blur_v_texture,
563              shader_blur_v_radius;
564ShaderUniform shader_glow_glow,
565              shader_glow_source,
566              shader_glow_mix;
567ShaderUniform shader_remanence_source,
568              shader_remanence_buffer,
569              shader_remanence_mix;
570ShaderUniform shader_copper_texture,
571              shader_copper_screen_size,
572              shader_copper_time,
573              shader_copper_copper,
574              shader_copper_mask_color;
575ShaderUniform shader_color_texture,
576              shader_color_screen_size,
577              shader_color_filter,
578              shader_color_color,
579              shader_color_flash;
580ShaderUniform shader_noise_texture,
581              shader_noise_screen_size,
582              shader_noise_time,
583              shader_noise_offset,
584              shader_noise_noise,
585              shader_noise_retrace;
586ShaderUniform shader_postfx_texture,
587              shader_postfx_texture_2d,
588              shader_postfx_screen_size,
589              shader_postfx_ratio_2d,
590              shader_postfx_time,
591              shader_postfx_deform,
592              shader_postfx_ghost1,
593              shader_postfx_ghost2,
594              shader_postfx_glass,
595              shader_postfx_vignetting,
596              shader_postfx_aberration,
597              shader_postfx_moire_h,
598              shader_postfx_moire_v,
599              shader_postfx_scanline_h,
600              shader_postfx_scanline_v,
601              shader_postfx_corner,
602              shader_postfx_sync,
603              shader_postfx_beat;
604ShaderUniform shader_mirror_texture,
605              shader_mirror_screen_size,
606              shader_mirror_mirror;
607ShaderUniform shader_radial_texture,
608              shader_radial_screen_size,
609              shader_radial_radial;
610
611FrameBuffer *fbo_back, *fbo_front, *fbo_screen;
612FrameBuffer *fbo_blur_h, *fbo_blur_v;
613FrameBuffer *fbo_tmp, *fbo_buffer;
614
615void Render::TraceQuad()
616{
617    glLoadIdentity();
618    glDrawArrays(GL_QUADS, 0, 4);
619}
620
621void Render::ShaderSimple(FrameBuffer *fbo_output, int n)
622{
623    shader_simple->Bind();
624    shader_simple->SetUniform(shader_simple_texture, fbo_output->GetTexture(), n);
625    TraceQuad();
626    shader_simple->Unbind();
627}
628
629int Render::InitDraw(void)
630{
631    glDepthMask(GL_TRUE);     // do not write z-buffer
632    glEnable(GL_CULL_FACE);   // disable cull face
633    glCullFace(GL_BACK);      // don't draw front face
634    /* initialise framebuffer objects */
635    fbo_back = new FrameBuffer(screen_size);
636    fbo_screen = new FrameBuffer(screen_size);
637    fbo_front = new FrameBuffer(screen_size);
638    fbo_buffer = new FrameBuffer(screen_size);
639    fbo_blur_h = new FrameBuffer(screen_size);
640    fbo_blur_v = new FrameBuffer(screen_size);
641    fbo_tmp = new FrameBuffer(screen_size);
642    // shader simple
643    shader_simple = Shader::Create(lolfx_simple);
644    shader_simple_texture = shader_simple->GetUniformLocation("texture");
645    // shader glow
646    shader_glow = Shader::Create(lolfx_glow);
647    shader_glow_glow = shader_glow->GetUniformLocation("glow");
648    shader_glow_source = shader_glow->GetUniformLocation("source");
649    shader_glow_mix = shader_glow->GetUniformLocation("mix");
650    // shader blur horizontal
651    shader_blur_h = Shader::Create(lolfx_blurh);
652    shader_blur_h_texture = shader_blur_h->GetUniformLocation("texture");
653    shader_blur_h_radius = shader_blur_h->GetUniformLocation("radius");
654    // shader blur vertical
655    shader_blur_v = Shader::Create(lolfx_blurv);
656    shader_blur_v_texture = shader_blur_v->GetUniformLocation("texture");
657    shader_blur_v_radius = shader_blur_v->GetUniformLocation("radius");
658    // shader remanence
659    shader_remanence = Shader::Create(lolfx_remanence);
660    shader_remanence_source = shader_remanence->GetUniformLocation("source");
661    shader_remanence_buffer = shader_remanence->GetUniformLocation("buffer");
662    shader_remanence_mix = shader_remanence->GetUniformLocation("mix");
663    // shader copper
664    shader_copper = Shader::Create(lolfx_copper);
665    shader_copper_texture = shader_copper->GetUniformLocation("texture");
666    shader_copper_screen_size = shader_copper->GetUniformLocation("screen_size");
667    shader_copper_time = shader_copper->GetUniformLocation("time");
668    shader_copper_copper = shader_copper->GetUniformLocation("copper");
669    shader_copper_mask_color = shader_copper->GetUniformLocation("mask_color");
670    // shader color
671    shader_color = Shader::Create(lolfx_color);
672    shader_color_texture = shader_color->GetUniformLocation("texture");
673    shader_color_screen_size = shader_color->GetUniformLocation("screen_size");
674    shader_color_filter = shader_color->GetUniformLocation("filter");
675    shader_color_color = shader_color->GetUniformLocation("color");
676    shader_color_flash = shader_color->GetUniformLocation("flash");
677    // shader noise
678    shader_noise = Shader::Create(lolfx_noise);
679    shader_noise_texture = shader_noise->GetUniformLocation("texture");
680    shader_noise_screen_size = shader_noise->GetUniformLocation("screen_size");
681    shader_noise_time = shader_noise->GetUniformLocation("time");
682    shader_noise_offset = shader_noise->GetUniformLocation("offset");
683    shader_noise_noise = shader_noise->GetUniformLocation("noise");
684    shader_noise_retrace = shader_noise->GetUniformLocation("retrace");
685    // shader postfx
686    shader_postfx = Shader::Create(lolfx_postfx);
687    shader_postfx_texture = shader_postfx->GetUniformLocation("texture");
688    shader_postfx_texture_2d = shader_postfx->GetUniformLocation("texture_2d");
689    shader_postfx_screen_size = shader_postfx->GetUniformLocation("screen_size");
690    shader_postfx_ratio_2d = shader_postfx->GetUniformLocation("ratio_2d");
691    shader_postfx_time = shader_postfx->GetUniformLocation("time");
692    shader_postfx_deform = shader_postfx->GetUniformLocation("deform");
693    shader_postfx_ghost1 = shader_postfx->GetUniformLocation("ghost1");
694    shader_postfx_ghost2 = shader_postfx->GetUniformLocation("ghost2");
695    shader_postfx_glass = shader_postfx->GetUniformLocation("glass");
696    shader_postfx_vignetting = shader_postfx->GetUniformLocation("vignetting");
697    shader_postfx_aberration = shader_postfx->GetUniformLocation("aberration");
698    shader_postfx_moire_h = shader_postfx->GetUniformLocation("moire_h");
699    shader_postfx_moire_v = shader_postfx->GetUniformLocation("moire_v");
700    shader_postfx_scanline_h = shader_postfx->GetUniformLocation("scanline_h");
701    shader_postfx_scanline_v = shader_postfx->GetUniformLocation("scanline_v");
702    shader_postfx_corner = shader_postfx->GetUniformLocation("corner");
703    shader_postfx_sync = shader_postfx->GetUniformLocation("sync");
704    shader_postfx_beat = shader_postfx->GetUniformLocation("beat");
705    // shader mirror
706    shader_mirror = Shader::Create(lolfx_mirror);
707    shader_mirror_texture = shader_mirror->GetUniformLocation("texture");
708    shader_mirror_screen_size = shader_mirror->GetUniformLocation("screen_size");
709    shader_mirror_mirror = shader_mirror->GetUniformLocation("mirror");
710    // shader radial blur
711    shader_radial = Shader::Create(lolfx_radial);
712    shader_radial_texture = shader_radial->GetUniformLocation("texture");
713    shader_radial_screen_size = shader_radial->GetUniformLocation("screen_size");
714    shader_radial_radial = shader_radial->GetUniformLocation("radial");
715    // initialize setup
716    setup_n = calc_item_length();
717    return true;
718}
719
720int Render::CreateGLWindow()
721{
722    UpdateSize();
723    InitDraw();
724    InitVar();
725    UpdateSize();
726    return true;
727}
728
729Render::Render(caca_canvas_t *caca)
730  : m_cv_screen(caca),
731    m_cv_setup(caca_create_canvas(1, 1)),
732    m_fps_debug(0),
733    m_ready(false),
734    m_pause(false),
735    m_shader(true),
736    m_shader_glow(true),
737    m_shader_blur(true),
738    m_shader_remanence(true),
739    m_shader_copper(true),
740    m_shader_color(true),
741    m_shader_noise(true),
742    m_shader_postfx(true),
743    m_shader_mirror(true),
744    m_shader_radial(true)
745{
746    m_txt_screen = new TextRender(m_cv_screen, font_size);
747    m_txt_setup = new TextRender(m_cv_setup, font_size);
748}
749
750void Render::TickGame(float seconds)
751{
752    Entity::TickGame(seconds);
753    /* draw setup */
754    if (g_setup)
755    {
756        /* background */
757        caca_set_color_argb(m_cv_setup, setup_color.x, setup_color.y);
758        caca_fill_box(m_cv_setup, 0, 0, setup_size.x + 1, setup_size.y,' ');
759        caca_draw_line(m_cv_setup, setup_size.z - 1, 1, setup_size.z - 1, setup_size.y - 1,'|');
760        /* title */
761        caca_set_color_argb(m_cv_setup, setup_color.y, setup_color.x);
762        caca_draw_line(m_cv_setup, 0, 0, setup_size.x, 0, ' ');
763        caca_put_str(m_cv_setup, setup_size.x / 2 - 3, 0, "SETUP");
764        /* informations */
765        /*
766        int w = caca_get_canvas_width(m_cv_screen);
767        int h = caca_get_canvas_height(m_cv_screen);
768        caca_set_color_argb(m_cv_setup, setup_color.y, setup_color.x);
769        caca_printf(m_cv_setup, 1, 0, "%i*%i", w, h);
770        */
771        /* display option */
772        for (int i = 0; i < setup_h; i++)
773        {
774            int y = 1 + i;
775            int k = (setup_option_p + i) * (setup_item_n + 1);
776            if (setup_option_i != setup_option_p + i || setup_switch)
777            {
778                caca_set_color_argb(m_cv_setup, setup_color.x, setup_color.y);
779                caca_put_str(m_cv_setup, 1, y, setup_text[k]);
780            }
781            else
782            {
783                caca_set_color_argb(m_cv_setup, setup_color.y, 0xfff);//setup_color.x);
784                caca_draw_line(m_cv_setup, 0, y, setup_size.z - 2, y,' ');
785                caca_put_str(m_cv_setup, 1, y, setup_text[k]);
786            }
787        }
788        /* display item */
789        for (int i = 0; i < setup_h; i++)
790        {
791            int y = 1 + i;
792            int k = setup_option_i * (setup_item_n + 1) + 1 + setup_item_p + i;
793            if (setup_item_i != setup_item_p + i || !setup_switch)
794            {
795                caca_set_color_argb(m_cv_setup, setup_color.x, setup_color.y);
796                caca_put_str(m_cv_setup, setup_size.z + 1, y, setup_text[k]);
797            }
798            else
799            {
800                caca_set_color_argb(m_cv_setup, setup_color.y, 0xfff);//setup_color.x);
801                caca_draw_line(m_cv_setup, setup_size.z, y, setup_size.x, y,' ');
802                caca_put_str(m_cv_setup, setup_size.z + 1, y, setup_text[k]);
803            }
804        }
805        /* display variable */
806        int y = setup_size.y;
807        setup_item_key = setup_option_i * (setup_item_n + 1) + 1 + setup_item_i;
808        caca_set_color_argb(m_cv_setup, setup_color.y, setup_color.x);
809        caca_draw_line(m_cv_setup, 0, y, setup_size.x, y,' ');
810        if (setup_switch)
811        {
812            int x = 1;
813            int w = setup_size.x - 3 - 4;
814            float bar_w = w / (setup_var[setup_item_key].y - setup_var[setup_item_key].x);
815            int bar_x = bar_w * setup_var[setup_item_key].x;
816            if ((setup_var[setup_item_key].y - setup_var[setup_item_key].x) / setup_var[setup_item_key].z > 1)
817            {
818                /* Work around a bug in libcaca */
819                if (setup_size.x - 4 < caca_get_canvas_width(m_cv_setup)) caca_printf(m_cv_setup, setup_size.x - 4, y, "%4.2f", setup_var[setup_item_key].w);
820                caca_draw_line(m_cv_setup, x, y, x - bar_x + int(bar_w * setup_var[setup_item_key].y), y,'.');
821                if (setup_var[setup_item_key].w != setup_var[setup_item_key].x) caca_draw_line(m_cv_setup, x, y, x - bar_x + int(bar_w * setup_var[setup_item_key].w), y, 'x');
822            }
823            else
824            {
825                if (setup_var[setup_item_key] != vec4(0))
826                {
827                    caca_put_str(m_cv_setup, setup_size.x - 3, y, (setup_var[setup_item_key].w == setup_var[setup_item_key].y)?"YES":" NO");
828                }
829            }
830        }
831        else
832        {
833            caca_printf(m_cv_setup, 1, y, "%d/%d", setup_option_i, setup_n);
834        }
835    }
836
837}
838
839void Render::Pause()
840{
841    m_pause=!m_pause;
842}
843
844void Render::TickDraw(float seconds)
845{
846    /* keyboard manager */
847    if (Input::WasPressed(Key::F1))
848    {
849        g_setup = !g_setup;
850        if (g_setup) setup_n = calc_item_length();
851        sync_flag = true;
852        sync_angle = main_angle;
853
854        if (m_fps_debug)
855        {
856            Ticker::Unref(m_fps_debug);
857            m_fps_debug = NULL;
858        }
859
860        if (g_setup)
861        {
862            m_fps_debug = new DebugFps(2, 2);
863            Ticker::Ref(m_fps_debug);
864        }
865    }
866    if (Input::WasPressed(Key::F2))
867    {
868        m_shader_glow = !m_shader_glow;
869        m_shader_blur = !m_shader_blur;
870        m_shader_remanence = !m_shader_remanence;
871        //m_shader_copper = !m_shader_copper;
872        m_shader_color = !m_shader_color;
873        m_shader_noise = !m_shader_noise;
874        m_shader_postfx = !m_shader_postfx;
875        m_shader_mirror = !m_shader_mirror;
876        m_shader_radial = !m_shader_radial;
877    }
878   if (Input::WasPressed(Key::Tab))
879    {
880        if (g_setup)
881        {
882            setup_switch = !setup_switch;
883            setup_n = calc_item_length();
884            setup_cursor = (!setup_switch?setup_option_i:setup_item_i) - (!setup_switch?setup_option_p:setup_item_p);
885        }
886    }
887    if (Input::WasPressed(Key::Up))
888    {
889        if (g_setup)
890        {
891            if (!setup_switch)
892            {
893                if (setup_cursor > 0)
894                {
895                    setup_cursor--;
896                }
897                else
898                {
899                    if (setup_cursor == 0) setup_option_p--;
900                }
901                if (setup_option_i > 0)
902                {
903                    setup_option_i--;
904                }
905                else
906                {
907                    setup_option_i = setup_option_n - 1;
908                    setup_option_p = setup_option_n - setup_h;
909                    setup_cursor = setup_h - 1;
910                }
911                setup_item_i = 0;
912                setup_item_p = 0;
913            }
914            else
915            {
916                if (setup_cursor > 0)
917                {
918                    setup_cursor--;
919                }
920                else
921                {
922                    if (setup_cursor == 0) setup_item_p--;
923                }
924                if (setup_item_i > 0)
925                {
926                    setup_item_i--;
927                }
928                else
929                {
930                    setup_item_i = setup_n;
931                    setup_item_p = (setup_n < setup_h) ? 0 : setup_n - setup_h + 1;
932                    setup_cursor = (setup_n < setup_h) ? setup_n : setup_h - 1;
933                }
934            }
935        }
936    }
937    if (Input::WasPressed(Key::Down))
938    {
939        if (g_setup)
940        {
941            if (!setup_switch)
942            {
943                if (setup_cursor < setup_h - 1)
944                {
945                    setup_cursor++;
946                }
947                else
948                {
949                    if (setup_cursor == setup_h - 1) setup_option_p++;
950                }
951                if (setup_option_i < setup_option_n - 1)
952                {
953                    setup_option_i++;
954                }
955                else
956                {
957                    setup_option_i = 0;
958                    setup_option_p = 0;
959                    setup_cursor = 0;
960                }
961                setup_item_i = 0;
962                setup_item_p = 0;
963            }
964            else
965            {
966                if (setup_cursor < setup_h - 1)
967                {
968                    setup_cursor++;
969                }
970                else
971                {
972                    if (setup_cursor == setup_h - 1) setup_item_p++;
973                }
974                if (setup_item_i < setup_n)
975                {
976                    setup_item_i++;
977                }
978                else
979                {
980                    setup_item_i = 0;
981                    setup_item_p = 0;
982                    setup_cursor = 0;
983                }
984            }
985        }
986    }
987    if (Input::WasPressed(Key::PageUp))
988    {
989        if (g_setup)
990        {
991            if (!setup_switch)
992            {
993                if (setup_cursor > 0)
994                {
995                    setup_option_i -= setup_cursor;
996                    setup_cursor = 0;
997                }
998                else
999                {
1000                    if (setup_option_i > setup_h)
1001                    {
1002                        setup_option_i -= setup_h;
1003                        setup_option_p -= setup_h;
1004                    }
1005                else
1006                    {
1007                        setup_option_i = 0;
1008                        setup_option_p = 0;
1009                    }
1010                }
1011            setup_item_i = 0;
1012            }
1013            else
1014            {
1015                if (setup_cursor > 0)
1016                {
1017                    setup_item_i -= setup_cursor;
1018                    setup_cursor = 0;
1019                }
1020                else
1021                {
1022                    if (setup_item_i > setup_h)
1023                    {
1024                        setup_item_i -= setup_h;
1025                        setup_item_p -= setup_h;
1026                    }
1027                else
1028                    {
1029                        setup_item_i = 0;
1030                        setup_item_p = 0;
1031                    }
1032                }
1033            }
1034        }
1035    }
1036    if (Input::WasPressed(Key::PageDown))
1037    {
1038        if (g_setup)
1039        {
1040            if (!setup_switch)
1041            {
1042                if (setup_cursor < setup_h - 1)
1043                {
1044                    setup_option_i += setup_h - setup_cursor - 1;
1045                    setup_cursor = setup_h - 1;
1046                    setup_item_i = 0;
1047                }
1048                else
1049                {
1050                    if (setup_option_i < setup_option_n - setup_h - 1)
1051                    {
1052                        setup_option_i += setup_h;
1053                        setup_option_p += setup_h;
1054                    }
1055                else
1056                    {
1057                        setup_option_i = setup_option_n - 1;
1058                        setup_option_p = setup_option_n - setup_h;
1059                    }
1060                }
1061            }
1062            else
1063            {
1064                if (setup_cursor < setup_h - 1)
1065                {
1066                    setup_item_i += (setup_n < setup_h) ? setup_n - setup_cursor : setup_h - setup_cursor - 1;
1067                    setup_cursor = (setup_n < setup_h) ? setup_n : setup_h - 1;
1068                }
1069                else
1070                {
1071                    if (setup_item_i < setup_n - setup_h + 1)
1072                    {
1073                        setup_item_i += setup_h;
1074                        setup_item_p += setup_h;
1075                    }
1076                else
1077                    {
1078                        setup_item_i = setup_n;
1079                        setup_item_p = setup_n - setup_h + 1;
1080                    }
1081                }
1082            }
1083        }
1084    }
1085    if (Input::WasPressed(Key::Left))
1086    {
1087        if (g_setup && setup_switch)
1088        {
1089            setup_var[setup_item_key].w -= setup_var[setup_item_key].z;
1090            if (setup_var[setup_item_key].w < setup_var[setup_item_key].x) setup_var[setup_item_key].w = setup_var[setup_item_key].x;
1091            UpdateVar();
1092        }
1093    }
1094    if (Input::WasPressed(Key::Right))
1095    {
1096        if (g_setup && setup_switch)
1097        {
1098            setup_var[setup_item_key].w += setup_var[setup_item_key].z;
1099            if (setup_var[setup_item_key].w > setup_var[setup_item_key].y) setup_var[setup_item_key].w = setup_var[setup_item_key].y;
1100            UpdateVar();
1101        }
1102    }
1103    if (Input::WasPressed(Key::Home))
1104    {
1105        if (g_setup && setup_switch)
1106        {
1107            setup_var[setup_item_key].w = setup_var[setup_item_key].x;
1108            UpdateVar();
1109        }
1110    }
1111    if (Input::WasPressed(Key::End))
1112    {
1113        if (g_setup && setup_switch)
1114        {
1115            setup_var[setup_item_key].w = setup_var[setup_item_key].y;
1116            UpdateVar();
1117        }
1118    }
1119    if (Input::WasPressed(Key::Return))
1120    {
1121        beat_flag = true;
1122        beat_angle = main_angle;
1123        //flash_flag = true;
1124        //flash_angle = main_angle;
1125    }
1126
1127    Entity::TickDraw(seconds);
1128
1129    if (!m_ready)
1130    {
1131        CreateGLWindow();
1132        m_txt_screen->Init();
1133        m_txt_setup->Init();
1134        m_ready = true;
1135    }
1136
1137    // timer
1138    if (!m_pause)
1139    {
1140        timer += seconds;
1141        main_angle = timer * 100.0f * PID;
1142    }
1143    if (sync_flag)
1144    {
1145        angle = (main_angle - sync_angle) * sync_speed;
1146        sync_value = 1.0f - sinf(angle);
1147        if (angle > 90.0f * PID)
1148        {
1149            sync_value = 0;
1150            sync_flag = false;
1151        }
1152    }
1153    if (beat_flag)
1154    {
1155        angle = (main_angle - beat_angle) * beat_speed;
1156        beat_value = 1.0f - sinf(angle);
1157        if (angle > 90.0f * PID)
1158        {
1159            beat_value = 0;
1160            beat_flag = false;
1161        }
1162    }
1163    if (flash_flag)
1164    {
1165        angle = (main_angle - flash_angle) * flash_speed;
1166        flash_value = 1.0f - sinf(angle);
1167        if (angle > 90.0f * PID)
1168        {
1169            flash_value = 0;
1170            flash_flag = false;
1171        }
1172    }
1173    if (fade_flag)
1174    {
1175        angle = (main_angle - fade_angle) * fade_speed;
1176        fade_value = 1.0f - sinf(angle);
1177        if (angle > 90.0f * PID)
1178        {
1179            fade_value = 0;
1180            fade_flag = false;
1181        }
1182    }
1183
1184    Draw2D();
1185    Draw3D();
1186}
1187
1188void Render::Draw2D()
1189{
1190    /* Draw text in an offline buffer */
1191    m_txt_screen->Render();
1192
1193    if (g_setup)
1194        m_txt_setup->Render();
1195
1196    if (m_shader)
1197        fbo_back->Bind();
1198
1199    glViewport(0, 0, screen_size.x, screen_size.y);
1200
1201    /* Clear the back buffer */
1202    glEnable(GL_TEXTURE_2D);
1203    glEnable(GL_BLEND);
1204    glBlendFunc(GL_SRC_COLOR, GL_DST_ALPHA);
1205
1206    Video::SetClearColor(vec4(0.0f, 0.0f, 0.0f, 1.0f));
1207    Video::SetClearDepth(1.0f); // set depth buffer
1208    Video::Clear(ClearMask::Color | ClearMask::Depth);
1209
1210    m_txt_screen->Blit(border, canvas_size);
1211    if (g_setup)
1212        m_txt_setup->Blit((screen_size - setup_canvas_size) / 2, setup_canvas_size);
1213
1214    glMatrixMode(GL_PROJECTION);
1215    mat4 m = mat4::ortho(0, screen_size.x, screen_size.y, 0, -1.f, 1.f);
1216    glLoadMatrixf(&m[0][0]);
1217    glMatrixMode(GL_MODELVIEW);
1218
1219    fx_angle=main_angle-part_angle;
1220}
1221
1222void Render::Draw3D()
1223{
1224    if (!m_shader)
1225        return;
1226
1227    glDisable(GL_DEPTH_TEST);
1228    glDisable(GL_BLEND);
1229
1230    glEnableClientState(GL_VERTEX_ARRAY);
1231    glVertexPointer(4, GL_FLOAT, 0, fs_quad_vtx);
1232
1233    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
1234    glTexCoordPointer(2, GL_FLOAT, 0, fs_quad_tex);
1235
1236    if (m_shader_copper)
1237    {
1238        // shader copper
1239        fbo_tmp->Bind();
1240        shader_copper->Bind();
1241        shader_copper->SetUniform(shader_copper_texture, fbo_back->GetTexture(), 0);
1242        shader_copper->SetUniform(shader_copper_screen_size, (vec2)screen_size);
1243        shader_copper->SetUniform(shader_copper_time, fx_angle);
1244        shader_copper->SetUniform(shader_copper_copper, vec4(copper_copper.x, copper_copper.y, copper_copper.z * 16.0f, copper_copper.w * 16.0f));
1245        shader_copper->SetUniform(shader_copper_mask_color, copper_mask_color / 4.0f);
1246        TraceQuad();
1247        shader_color->Unbind();
1248        fbo_tmp->Unbind();
1249        // shader simple
1250        fbo_back->Bind();
1251        ShaderSimple(fbo_tmp, 0);
1252        fbo_back->Unbind();
1253    }
1254
1255    if (m_shader_remanence)
1256    {
1257        // shader remanence
1258        fbo_tmp->Bind();
1259        shader_remanence->Bind();
1260        shader_remanence->SetUniform(shader_remanence_source, fbo_back->GetTexture(), 0);
1261        shader_remanence->SetUniform(shader_remanence_buffer, fbo_buffer->GetTexture(), 1);
1262        shader_remanence->SetUniform(shader_remanence_mix, remanence);
1263        TraceQuad();
1264        shader_remanence->Unbind();
1265        fbo_tmp->Unbind();
1266        // shader simple
1267        fbo_back->Bind();
1268        ShaderSimple(fbo_tmp, 0);
1269        fbo_back->Unbind();
1270        // save previous fbo
1271        fbo_tmp->Bind();
1272        shader_remanence->Bind();
1273        shader_remanence->SetUniform(shader_remanence_source, fbo_screen->GetTexture(), 0);
1274        shader_remanence->SetUniform(shader_remanence_buffer, fbo_buffer->GetTexture(), 1);
1275        shader_remanence->SetUniform(shader_remanence_mix, buffer);
1276        TraceQuad();
1277        shader_remanence->Unbind();
1278        fbo_tmp->Unbind();
1279        // shader simple
1280        fbo_buffer->Bind();
1281        ShaderSimple(fbo_tmp, 0);
1282        fbo_buffer->Unbind();
1283    }
1284
1285    // shader glow
1286    if (m_shader_glow)
1287    {
1288        // shader blur horizontal
1289        fbo_blur_h->Bind();
1290        shader_blur_h->Bind();
1291        shader_blur_h->SetUniform(shader_blur_h_texture, fbo_back->GetTexture(), 0);
1292        shader_blur_h->SetUniform(shader_blur_h_radius, glow_large / screen_size.x);
1293        TraceQuad();
1294        shader_blur_h->Unbind();
1295        fbo_blur_h->Unbind();
1296        // shader blur vertical
1297        fbo_blur_v->Bind();
1298        shader_blur_v->Bind();
1299        shader_blur_v->SetUniform(shader_blur_v_texture, fbo_blur_h->GetTexture(), 0);
1300        shader_blur_v->SetUniform(shader_blur_v_radius, glow_large / screen_size.y);
1301        TraceQuad();
1302        shader_blur_v->Unbind();
1303        fbo_blur_v->Unbind();
1304        // shader blur horizontal
1305        fbo_blur_h->Bind();
1306        shader_blur_h->Bind();
1307        shader_blur_h->SetUniform(shader_blur_h_texture, fbo_blur_v->GetTexture(), 0);
1308        shader_blur_h->SetUniform(shader_blur_h_radius, glow_small / screen_size.x);
1309        TraceQuad();
1310        shader_blur_h->Unbind();
1311        fbo_blur_h->Unbind();
1312        // shader blur vertical
1313        fbo_blur_v->Bind();
1314        shader_blur_v->Bind();
1315        shader_blur_v->SetUniform(shader_blur_v_texture, fbo_blur_h->GetTexture(), 0);
1316        shader_blur_v->SetUniform(shader_blur_v_radius, glow_small / screen_size.y);
1317        TraceQuad();
1318        shader_blur_v->Unbind();
1319        fbo_blur_v->Unbind();
1320        // shader glow
1321        fbo_screen->Bind();
1322        shader_glow->Bind();
1323        shader_glow->SetUniform(shader_glow_glow, fbo_blur_v->GetTexture(), 0);
1324        shader_glow->SetUniform(shader_glow_source, fbo_back->GetTexture(), 1);
1325        shader_glow->SetUniform(shader_glow_mix, glow_mix);
1326        TraceQuad();
1327        shader_glow->Unbind();
1328        fbo_screen->Unbind();
1329    }
1330    else
1331    {
1332        // shader simple
1333        fbo_screen->Bind();
1334        ShaderSimple(fbo_back, 0);
1335        fbo_screen->Unbind();
1336    }
1337
1338    if (m_shader_color)
1339    {
1340        // shader color
1341        fbo_tmp->Bind();
1342        shader_color->Bind();
1343        shader_color->SetUniform(shader_color_texture, fbo_screen->GetTexture(), 0);
1344        shader_color->SetUniform(shader_color_screen_size, (vec2)screen_size);
1345        shader_color->SetUniform(shader_color_filter, color_filter);
1346        shader_color->SetUniform(shader_color_color, color_color);
1347        shader_color->SetUniform(shader_color_flash, flash_value);
1348        TraceQuad();
1349        shader_color->Unbind();
1350        fbo_tmp->Unbind();
1351        // shader simple
1352        fbo_screen->Bind();
1353        ShaderSimple(fbo_tmp, 0);
1354        fbo_screen->Unbind();
1355    }
1356
1357    if (m_shader_noise)
1358    {
1359        // shader noise
1360        fbo_tmp->Bind();
1361        shader_noise->Bind();
1362        shader_noise->SetUniform(shader_noise_texture, fbo_screen->GetTexture(), 0);
1363        shader_noise->SetUniform(shader_noise_screen_size, (vec2)screen_size);
1364        shader_noise->SetUniform(shader_noise_time, fx_angle);
1365        shader_noise->SetUniform(shader_noise_offset, noise_offset);
1366        shader_noise->SetUniform(shader_noise_noise, noise_noise);
1367        shader_noise->SetUniform(shader_noise_retrace, noise_retrace);
1368        TraceQuad();
1369        shader_noise->Unbind();
1370        fbo_tmp->Unbind();
1371        // shader simple
1372        fbo_screen->Bind();
1373        ShaderSimple(fbo_tmp, 0);
1374        fbo_screen->Unbind();
1375    }
1376
1377    if (m_shader_blur)
1378    {
1379        // shader blur horizontal
1380        fbo_tmp->Bind();
1381        shader_blur_h->Bind();
1382        shader_blur_h->SetUniform(shader_blur_h_texture, fbo_screen->GetTexture(), 0);
1383        shader_blur_h->SetUniform(shader_blur_h_radius, blur / screen_size.x);
1384        TraceQuad();
1385        shader_blur_h->Unbind();
1386        fbo_tmp->Unbind();
1387        // shader blur vertical
1388        fbo_screen->Bind();
1389        shader_blur_v->Bind();
1390        shader_blur_v->SetUniform(shader_blur_v_texture, fbo_tmp->GetTexture(), 0);
1391        shader_blur_v->SetUniform(shader_blur_v_radius, blur / screen_size.y);
1392        TraceQuad();
1393        shader_blur_v->Unbind();
1394        fbo_screen->Unbind();
1395    }
1396
1397    if (m_shader_postfx)
1398    {
1399        // shader postfx
1400        fbo_front->Bind();
1401        shader_postfx->Bind();
1402        shader_postfx->SetUniform(shader_postfx_texture, fbo_screen->GetTexture(), 0);
1403        shader_postfx->SetUniform(shader_postfx_screen_size, (vec2)screen_size);
1404        shader_postfx->SetUniform(shader_postfx_ratio_2d, (vec2)ratio_2d / 2);
1405        shader_postfx->SetUniform(shader_postfx_time, fx_angle);
1406        shader_postfx->SetUniform(shader_postfx_deform, postfx_deform);
1407        shader_postfx->SetUniform(shader_postfx_ghost1, vec4(postfx_ghost1.x * 0.01, postfx_ghost1.y * 0.01, postfx_ghost1.z * 0.01, postfx_ghost1.w));
1408        shader_postfx->SetUniform(shader_postfx_ghost2, vec4(postfx_ghost2.x * 0.01, postfx_ghost2.y * 0.01, postfx_ghost2.z * 0.01, postfx_ghost2.w));
1409        shader_postfx->SetUniform(shader_postfx_glass, vec4(postfx_glass.x * 0.01, postfx_glass.y * 0.01, postfx_glass.z * 0.1, postfx_glass.w));
1410        shader_postfx->SetUniform(shader_postfx_vignetting, postfx_vignetting);
1411        shader_postfx->SetUniform(shader_postfx_aberration, postfx_aberration);
1412        shader_postfx->SetUniform(shader_postfx_moire_h, postfx_moire_h);
1413        shader_postfx->SetUniform(shader_postfx_moire_v, postfx_moire_v);
1414        shader_postfx->SetUniform(shader_postfx_scanline_h, postfx_scanline_h);
1415        shader_postfx->SetUniform(shader_postfx_scanline_v, postfx_scanline_v);
1416        shader_postfx->SetUniform(shader_postfx_corner, postfx_corner);
1417        shader_postfx->SetUniform(shader_postfx_sync, (float)fabs(sync_value * cosf((main_angle - sync_angle) * 6.0f)));
1418        shader_postfx->SetUniform(shader_postfx_beat, (float)fabs(beat_value * cosf((main_angle - beat_angle) * 6.0f)));
1419        TraceQuad();
1420        shader_postfx->Unbind();
1421        fbo_front->Unbind();
1422    }
1423    else
1424    {
1425        // shader simple
1426        fbo_front->Bind();
1427        ShaderSimple(fbo_screen, 0);
1428        fbo_front->Unbind();
1429    }
1430
1431    if (m_shader_mirror)
1432    {
1433        // shader mirror
1434        fbo_tmp->Bind();
1435        shader_mirror->Bind();
1436        shader_mirror->SetUniform(shader_mirror_texture, fbo_front->GetTexture(), 0);
1437        shader_mirror->SetUniform(shader_mirror_screen_size, (vec2)screen_size);
1438        shader_mirror->SetUniform(shader_mirror_mirror, vec4(mirror.x * 0.1f, mirror.y * 0.1f, mirror.z, mirror.w));
1439        TraceQuad();
1440        shader_mirror->Unbind();
1441        fbo_tmp->Unbind();
1442        // shader simple
1443        fbo_front->Bind();
1444        ShaderSimple(fbo_tmp, 0);
1445        fbo_front->Unbind();
1446    }
1447
1448    if (m_shader_radial)
1449    {
1450        // shader radial blur
1451        fbo_tmp->Bind();
1452        shader_radial->Bind();
1453        shader_radial->SetUniform(shader_radial_texture, fbo_front->GetTexture(), 0);
1454        shader_radial->SetUniform(shader_radial_screen_size, (vec2)screen_size);
1455        shader_radial->SetUniform(shader_radial_radial, vec4(radial.x, radial.y, radial.z, radial.w * 0.1f));
1456        TraceQuad();
1457        shader_radial->Unbind();
1458        fbo_tmp->Unbind();
1459        // shader simple
1460        fbo_front->Bind();
1461        ShaderSimple(fbo_tmp, 0);
1462        fbo_front->Unbind();
1463    }
1464
1465    // shader simple
1466    ShaderSimple(fbo_front, 0);
1467
1468    glDisableClientState(GL_VERTEX_ARRAY);
1469    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
1470}
1471
1472Render::~Render()
1473{
1474    if (m_fps_debug)
1475        Ticker::Unref(m_fps_debug);
1476}
Note: See TracBrowser for help on using the repository browser.