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

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

neercs: clamp canvas size to ensure we never get to zero.

File size: 38.3 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
27using namespace std;
28using namespace lol;
29
30#include "../neercs.h"
31#include "render.h"
32#include "text-render.h"
33
34extern char const *lolfx_simple;
35extern char const *lolfx_blurh;
36extern char const *lolfx_blurv;
37extern char const *lolfx_glow;
38extern char const *lolfx_remanency;
39extern char const *lolfx_copper;
40extern char const *lolfx_color;
41extern char const *lolfx_noise;
42extern char const *lolfx_postfx;
43
44#define PID M_PI/180.0f    // pi ratio
45#define CR 1.0f/256.0f     // color ratio
46
47/*
48 * Various variables
49 */
50
51int active = true;         // window active flag
52float nearplane = 0.1f;    // nearplane
53float farplane = 1000.0f;  // farplane
54int polygon_fillmode = GL_FILL; // fill mode
55/* timer variable */
56float timer = 0;           // timer
57/* window variable */
58ivec2 screen_size;         // screen size
59vec3 screen_color = CR * vec3(32, 32, 32); // screen color
60/* object variable */
61float main_angle = 0.0f;   // main angle
62float part_angle = 0.0f;   // part angle
63float fx_angle;            // current angle
64/* fs_quad variable */
65float 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};
66float fs_quad_tex[] = {0, 1.0f, 0, 0, 1.0f, 0, 1.0f, 1.0f};
67/* flash variable */
68bool flash_flag = false;   // flag
69float flash_angle = 0;     // angle
70float flash_value = 0;     // value
71float flash_speed = 2.0f;  // speed
72/* fade variable */
73bool fade_flag = false;    // flag
74float fade_angle = 0;      // angle
75float fade_value = 0;      // value
76float fade_speed = 0.2f;   // speed
77/* sync variable */
78bool sync_flag = false;    // flagsh
79float sync_angle = 0;      // angle
80float sync_value = 0;      // value
81float sync_speed = 1.0f;   // speed
82/* beat variable */
83bool beat_flag = false;    // flag
84float beat_angle = 0;      // angle
85float beat_value = 0;      // value
86float beat_speed = 2.0f;   // speed
87/* common variable */
88float value, angle, radius, scale, speed;
89/* shader variable */
90vec2 buffer(0.7f,0.3f);         // [new frame mix,old frame mix]
91vec2 remanency(0.5f,0.5f);      // remanency [source mix,buffer mix]
92vec2 glow_mix(0.6f,0.4f);       // glow mix [source mix,glow mix]
93vec2 glow_large(2.0f,2.0f);     // large glow radius [center,corner]
94vec2 glow_small(1.0f,1.0f);     // small glow radius [center,corner]
95vec2 blur(0.5f,0.5f);           // blur radius [center,corner]
96vec4 copper(0.125,0.125,32,64); // copper [base,variable,repeat x,repeat y]
97vec3 color_filter(0.9f,0.9f,1.0f);    // color filter [red,green,blue]
98vec3 color_color(1.2f,1.1f,0.25f);    // color modifier [brightness,contrast,grayscale]
99vec2 noise_offset(2.0f,2.0f);         // random line [horizontal,vertical]
100float noise_noise = 0.25f;            // noise
101vec3 noise_retrace(1.0f,1.0f,0.5f);   // retrace [strength,length,speed]
102vec2 postfx_deform(0.7f,0.54f);       // deformation [ratio,zoom]
103float postfx_vignetting = -0.5f;      // vignetting strength
104float postfx_aberration = 3.0f;       // chromatic aberration
105vec4 postfx_ghost1(0.01f,0.0f,0.1f,-0.25f);     // ghost picture 1 [position x,position y,position z,strength]
106vec4 postfx_ghost2(0.02f,0.0f,0.1f,0.25f);      // ghost picture 2 [position x,position y,position z,strength]
107vec4 postfx_moire_h(0.75f,-0.25f,0.0f,1.0f);    // vertical moire [base,variable,repeat x,repeat y]
108vec4 postfx_moire_v(0.75f,-0.25f,1.0f,1.5f);    // horizontal moire [base,variable,repeat x,repeat y]
109vec4 postfx_scanline_h(0.75f, 0.25f,0.0f,2.0f); // vertical scanline [base,variable,repeat x,repeat y]
110vec4 postfx_scanline_v(0.75f,-0.25f,2.0f,0.0f); // horizontal scanline [base,variable,repeat x,repeat y]
111vec2 postfx_corner(0.75f,0.95f);      // corner [radius,blur]
112/* text variable */
113ivec2 ratio_2d(2,4);            // 2d ratio
114ivec2 map_size(256,256);        // texture map size
115ivec2 font_size(8,8);           // font size
116ivec2 canvas_char(0,0);         // canvas char number
117ivec2 canvas_size(0,0);         // caca size
118/* window variable */
119ivec2 border = vec2(3,1) * ratio_2d * font_size; // border width
120/* setup variable */
121bool setup_switch = false;      // switch [option/item]
122int setup_n = 0;                // item/option number
123int setup_h = 6;                // height
124int setup_cursor = 0;           // cursor position
125int setup_option_i = 0;         // selected option
126int setup_option_n = 10;        // option number
127int setup_option_p = 0;         // option position
128int setup_item_i = 0;           // selected item
129int setup_item_n = 8;           // item number
130int setup_item_p = 0;           // item position
131int setup_item_key = 0;         // item array key
132ivec2 setup_p(1,1);             // position [x,y]
133ivec3 setup_size(30,7,12);      // size [w,h,split]
134ivec2 setup_color(0x678,0x234); // color [foreground,background]
135char const *setup_text[] = {
136    "main",
137        "2d ratio w",
138        "2d ratio h",
139        "border w",
140        "border h",
141        "",
142        "",
143        "",
144        "",
145    "remanency",
146        "enable",
147        "buffer new frame",
148        "buffer old frame",
149        "source mix",
150        "buffer mix",
151        "",
152        "",
153        "",
154    "glow",
155        "enable",
156        "source mix",
157        "glow mix",
158        "large center",
159        "large corner",
160        "small center",
161        "small corner",
162        "",
163    "blur",
164        "enable",
165        "blur center",
166        "blur corner",
167        "",
168        "",
169        "",
170        "",
171        "",
172    "screen",
173        "enable",
174        "deform ratio",
175        "zoom base",
176        "corner radius",
177        "corner blur",
178        "vignetting",
179        "",
180        "",
181    "color",
182        "filter red",
183        "filter green",
184        "filter blue",
185        "brightness",
186        "contrast",
187        "grayscale",
188        "aberration",
189        "",
190    "noise",
191        "enable",
192        "offset h",
193        "offset v",
194        "noise",
195        "retrace strength",
196        "retrace length",
197        "retrace speed",
198        "",
199    "ghost",
200        "back x",
201        "back y",
202        "back z",
203        "back strength",
204        "front x",
205        "front y",
206        "front z",
207        "front strength",
208    "moire",
209        "h base",
210        "h variable",
211        "h repeat x",
212        "h repeat y",
213        "v base",
214        "v variable",
215        "v repeat x",
216        "v repeat y",
217    "scanline",
218        "h base",
219        "h variable",
220        "h repeat x",
221        "h repeat y",
222        "v base",
223        "v variable",
224        "v repeat x",
225        "v repeat y"
226    };
227
228vec4 setup_var[]={ // setup variable [start,end,step,value]
229    vec4(0), /* main */
230        vec4( 1,  8, 1, ratio_2d.x),
231        vec4( 1,  8, 1, ratio_2d.y),
232        vec4( 0, 64, 1, border.x / ratio_2d.x / font_size.x),
233        vec4( 0, 64, 1, border.y / ratio_2d.y / font_size.y),
234        vec4(0),
235        vec4(0),
236        vec4(0),
237        vec4(0),
238    vec4(0), /* remanency */
239        vec4(0, 1, 1, 1),
240        vec4(0.0f, 1.0f, 0.1f, buffer.x),
241        vec4(0.0f, 1.0f, 0.1f, buffer.y),
242        vec4(0.0f, 1.0f, 0.1f, remanency.x),
243        vec4(0.0f, 1.0f, 0.1f, remanency.y),
244        vec4(0),
245        vec4(0),
246        vec4(0),
247    vec4(0), /* glow */
248        vec4(0, 1, 1, 1),
249        vec4(0.0f, 1.0f, 0.1f, glow_mix.x),
250        vec4(0.0f, 1.0f, 0.1f, glow_mix.y),
251        vec4(0.0f, 4.0f, 0.1f, glow_large.x),
252        vec4(0.0f, 4.0f, 0.1f, glow_large.y),
253        vec4(0.0f, 2.0f, 0.1f, glow_small.x),
254        vec4(0.0f, 2.0f, 0.1f, glow_small.y),
255        vec4(0),
256    vec4(0), /* blur */
257        vec4(0, 1, 1, 1),
258        vec4(0.0f, 2.0f, 0.05f, blur.x),
259        vec4(0.0f, 2.0f, 0.05f, blur.y),
260        vec4(0),
261        vec4(0),
262        vec4(0),
263        vec4(0),
264        vec4(0),
265    vec4(0), /* screen */
266        vec4( 0, 1, 1, 1),
267        vec4( 0.0f, 1.0f, 0.05f, postfx_deform.x),
268        vec4( 0.5f, 0.7f, 0.01f, postfx_deform.y),
269        vec4( 0.0f, 1.0f, 0.05f, postfx_corner.x),
270        vec4( 0.0f, 1.0f, 0.05f, postfx_corner.y),
271        vec4(-1.0f, 1.0f, 0.10f, postfx_vignetting),
272        vec4(0),
273        vec4(0),
274    vec4(0), /* color */
275        vec4(0.0f, 1.0f, 0.05f, color_filter.x),
276        vec4(0.0f, 1.0f, 0.05f, color_filter.y),
277        vec4(0.0f, 1.0f, 0.05f, color_filter.z),
278        vec4(0.0f, 2.0f, 0.05f, color_color.x),
279        vec4(0.0f, 2.0f, 0.05f, color_color.y),
280        vec4(0.0f, 1.0f, 0.05f, color_color.z),
281        vec4(0.0f, 8.0f, 0.50f, postfx_aberration),
282        vec4(0),
283    vec4(0), /* noise */
284        vec4( 0, 1, 1, 1),
285        vec4(0.0f, 4.0f, 0.50f, noise_offset.x),
286        vec4(0.0f, 4.0f, 0.50f, noise_offset.y),
287        vec4(0.0f, 0.5f, 0.05f, noise_noise),
288        vec4(0.0f, 4.0f, 0.25f, noise_retrace.x),
289        vec4(0.0f, 8.0f, 0.50f, noise_retrace.y),
290        vec4(0.0f, 4.0f, 0.25f, noise_retrace.z),
291        vec4(0),
292    vec4(0), /* ghost */
293        vec4(-0.5f, 0.5f, 0.01f, postfx_ghost1.x),
294        vec4(-0.5f, 0.5f, 0.01f, postfx_ghost1.y),
295        vec4(-2.0f, 2.0f, 0.10f, postfx_ghost1.z),
296        vec4(-1.0f, 1.0f, 0.05f, postfx_ghost1.w),
297        vec4(-0.5f, 0.5f, 0.01f, postfx_ghost2.x),
298        vec4(-0.5f, 0.5f, 0.01f, postfx_ghost2.y),
299        vec4(-2.0f, 2.0f, 0.10f, postfx_ghost2.z),
300        vec4(-1.0f, 1.0f, 0.05f, postfx_ghost2.w),
301    vec4(0), /* moire */
302        vec4( 0.5f, 1.0f, 0.05f, postfx_moire_h.x),
303        vec4(-0.5f, 0.5f, 0.05f, postfx_moire_h.y),
304        vec4( 0.0f, 4.0f, 0.50f, postfx_moire_h.z),
305        vec4( 0.0f, 4.0f, 0.50f, postfx_moire_h.w),
306        vec4( 0.5f, 1.0f, 0.05f, postfx_moire_v.x),
307        vec4(-0.5f, 0.5f, 0.05f, postfx_moire_v.y),
308        vec4( 0.0f, 4.0f, 0.50f, postfx_moire_v.z),
309        vec4( 0.0f, 4.0f, 0.50f, postfx_moire_v.w),
310    vec4(0), /* scanline */
311        vec4( 0.5f, 1.0f, 0.05f, postfx_scanline_h.x),
312        vec4(-0.5f, 0.5f, 0.05f, postfx_scanline_h.y),
313        vec4( 0.0f, 4.0f, 0.50f, postfx_scanline_h.z),
314        vec4( 0.0f, 4.0f, 0.50f, postfx_scanline_h.w),
315        vec4( 0.5f, 1.0f, 0.05f, postfx_scanline_v.x),
316        vec4(-0.5f, 0.5f, 0.05f, postfx_scanline_v.y),
317        vec4( 0.0f, 4.0f, 0.50f, postfx_scanline_v.z),
318        vec4( 0.0f, 4.0f, 0.50f, postfx_scanline_v.w),
319    vec4(0)
320    };
321
322void Render::UpdateVar()
323{
324    int k = 1; /* main */
325    ratio_2d = vec2(setup_var[k].w, setup_var[k + 1].w); k += 2;
326    border = vec2(setup_var[k].w, setup_var[k + 1].w) * ratio_2d * font_size; k += 2;
327    k += 5; /* remanency */
328    m_shader_remanency = (setup_var[k].w == 1) ? true : false; k++;
329    buffer = vec2(setup_var[k].w, setup_var[k + 1].w); k += 2;
330    remanency = vec2(setup_var[k].w, setup_var[k + 1].w); k += 2;
331    k += 4; /* glow */
332    m_shader_glow = (setup_var[k].w == 1) ? true : false; k++;
333    glow_mix = vec2(setup_var[k].w, setup_var[k + 1].w); k += 2;
334    glow_large = vec2(setup_var[k].w, setup_var[k + 1].w); k += 2;
335    glow_small = vec2(setup_var[k].w, setup_var[k + 1].w); k += 2;
336    k += 2; /* blur */
337    m_shader_blur = (setup_var[k].w == 1) ? true : false; k++;
338    blur = vec2(setup_var[k].w, setup_var[k + 1].w); k += 2;
339    k += 6; /* screen */
340    m_shader_postfx = (setup_var[k].w == 1) ? true : false; k++;
341    postfx_deform = vec2(setup_var[k].w, setup_var[k + 1].w); k += 2;
342    postfx_corner = vec2(setup_var[k].w, setup_var[k + 1].w); k += 2;
343    postfx_vignetting = setup_var[k].w; k++;
344    k += 3; /* color */
345    color_filter = vec3(setup_var[k].w, setup_var[k + 1].w, setup_var[k + 2].w); k += 3;
346    color_color = vec3(setup_var[k].w, setup_var[k + 1].w, setup_var[k + 2].w); k += 3;
347    postfx_aberration = setup_var[k].w; k++;
348    k += 2; /* noise */
349    m_shader_noise = (setup_var[k].w == 1) ? true : false; k++;
350    noise_offset = vec2(setup_var[k].w, setup_var[k + 1].w); k += 2;
351    noise_noise = setup_var[k].w; k++;
352    noise_retrace = vec3(setup_var[k].w, setup_var[k + 1].w, setup_var[k + 2].w); k += 3;
353    k += 2; /* ghost */
354    postfx_ghost1 = vec4(setup_var[k].w, setup_var[k + 1].w, setup_var[k + 2].w, setup_var[k + 3].w); k += 4;
355    postfx_ghost2 = vec4(setup_var[k].w, setup_var[k + 1].w, setup_var[k + 2].w, setup_var[k + 3].w); k += 4;
356    k += 1; /* moire */
357    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;
358    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;
359    k += 1; /* scanline */
360    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;
361    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;
362
363    UpdateSize();
364}
365
366void Render::UpdateSize()
367{
368    screen_size = Video::GetSize();
369    //border.y = border.x; // enabled to get same border everywhere
370    canvas_char = (screen_size - border * 2) / (font_size * ratio_2d);
371    canvas_char = max(canvas_char, ivec2(1, 1));
372    canvas_size = canvas_char * font_size * ratio_2d;
373
374    border = (screen_size - canvas_size) / 2;
375
376    caca_set_canvas_size(m_caca, canvas_char.x, canvas_char.y);
377
378    setup_p = (canvas_char - setup_size.xy) / 2;
379}
380
381int calc_item_length()
382{
383    int n = !setup_switch ? setup_option_n : setup_item_n;
384    for (int i = 0; i < n; i++)
385    {
386        int k = !setup_switch ? (i * (setup_item_n + 1)) : (setup_option_i * (setup_item_n + 1) + 1 + i);
387        if (setup_text[k][0] == '\0') return i - 1;
388    }
389    return n - 1;
390}
391
392Shader *shader_simple;
393Shader *shader_blur_h, *shader_blur_v, *shader_glow;
394Shader *shader_remanency, *shader_copper, *shader_color;
395Shader *shader_noise, *shader_postfx;
396// shader variables
397ShaderUniform shader_simple_texture;
398ShaderUniform shader_blur_h_texture,
399              shader_blur_h_radius,
400              shader_blur_v_texture,
401              shader_blur_v_radius;
402ShaderUniform shader_glow_glow,
403              shader_glow_source,
404              shader_glow_mix;
405ShaderUniform shader_remanency_source,
406              shader_remanency_buffer,
407              shader_remanency_mix;
408ShaderUniform shader_copper_texture,
409              shader_copper_screen_size,
410              shader_copper_time,
411              shader_copper_copper;
412ShaderUniform shader_color_texture,
413              shader_color_screen_size,
414              shader_color_filter,
415              shader_color_color,
416              shader_color_flash;
417ShaderUniform shader_noise_texture,
418              shader_noise_screen_size,
419              shader_noise_time,
420              shader_noise_offset,
421              shader_noise_noise,
422              shader_noise_retrace;
423ShaderUniform shader_postfx_texture,
424              shader_postfx_texture_2d,
425              shader_postfx_screen_size,
426              shader_postfx_time,
427              shader_postfx_deform,
428              shader_postfx_ghost1,
429              shader_postfx_ghost2,
430              shader_postfx_vignetting,
431              shader_postfx_aberration,
432              shader_postfx_moire_h,
433              shader_postfx_moire_v,
434              shader_postfx_scanline_h,
435              shader_postfx_scanline_v,
436              shader_postfx_corner,
437              shader_postfx_sync;
438
439FrameBuffer *fbo_back, *fbo_front, *fbo_buffer;
440FrameBuffer *fbo_blur_h, *fbo_blur_v, *fbo_tmp;
441
442TextRender *text_render;
443
444void Render::TraceQuad()
445{
446    glLoadIdentity();
447    glDrawArrays(GL_QUADS, 0, 4);
448}
449
450void Render::ShaderSimple(FrameBuffer *fbo_output, int n)
451{
452    shader_simple->Bind();
453    shader_simple->SetUniform(shader_simple_texture, fbo_output->GetTexture(), n);
454    TraceQuad();
455    shader_simple->Unbind();
456}
457
458int Render::InitDraw(void)
459{
460    glDepthMask(GL_TRUE);     // do not write z-buffer
461    glEnable(GL_CULL_FACE);   // disable cull face
462    glCullFace(GL_BACK);      // don't draw front face
463
464    /* Initialise framebuffer objects */
465    fbo_back = new FrameBuffer(screen_size);
466    fbo_front = new FrameBuffer(screen_size);
467    fbo_buffer = new FrameBuffer(screen_size);
468    fbo_blur_h = new FrameBuffer(screen_size);
469    fbo_blur_v = new FrameBuffer(screen_size);
470    fbo_tmp = new FrameBuffer(screen_size);
471    // shader simple
472    shader_simple = Shader::Create(lolfx_simple);
473    shader_simple_texture = shader_simple->GetUniformLocation("texture");
474    // shader glow
475    shader_glow = Shader::Create(lolfx_glow);
476    shader_glow_glow = shader_glow->GetUniformLocation("glow");
477    shader_glow_source = shader_glow->GetUniformLocation("source");
478    shader_glow_mix = shader_glow->GetUniformLocation("mix");
479    // shader blur horizontal
480    shader_blur_h = Shader::Create(lolfx_blurh);
481    shader_blur_h_texture = shader_blur_h->GetUniformLocation("texture");
482    shader_blur_h_radius = shader_blur_h->GetUniformLocation("radius");
483    // shader blur vertical
484    shader_blur_v = Shader::Create(lolfx_blurv);
485    shader_blur_v_texture = shader_blur_v->GetUniformLocation("texture");
486    shader_blur_v_radius = shader_blur_v->GetUniformLocation("radius");
487    // shader remanency
488    shader_remanency = Shader::Create(lolfx_remanency);
489    shader_remanency_source = shader_remanency->GetUniformLocation("source");
490    shader_remanency_buffer = shader_remanency->GetUniformLocation("buffer");
491    shader_remanency_mix = shader_remanency->GetUniformLocation("mix");
492    // shader copper
493    shader_copper = Shader::Create(lolfx_copper);
494    shader_copper_texture = shader_copper->GetUniformLocation("texture");
495    shader_copper_screen_size = shader_copper->GetUniformLocation("screen_size");
496    shader_copper_time = shader_copper->GetUniformLocation("time");
497    shader_copper_copper = shader_copper->GetUniformLocation("copper");
498    // shader color
499    shader_color = Shader::Create(lolfx_color);
500    shader_color_texture = shader_color->GetUniformLocation("texture");
501    shader_color_screen_size = shader_color->GetUniformLocation("screen_size");
502    shader_color_filter = shader_color->GetUniformLocation("filter");
503    shader_color_color = shader_color->GetUniformLocation("color");
504    shader_color_flash = shader_color->GetUniformLocation("flash");
505    // shader noise
506    shader_noise = Shader::Create(lolfx_noise);
507    shader_noise_texture = shader_noise->GetUniformLocation("texture");
508    shader_noise_screen_size = shader_noise->GetUniformLocation("screen_size");
509    shader_noise_time = shader_noise->GetUniformLocation("time");
510    shader_noise_offset = shader_noise->GetUniformLocation("offset");
511    shader_noise_noise = shader_noise->GetUniformLocation("noise");
512    shader_noise_retrace = shader_noise->GetUniformLocation("retrace");
513    // shader postfx
514    shader_postfx = Shader::Create(lolfx_postfx);
515    shader_postfx_texture = shader_postfx->GetUniformLocation("texture");
516    shader_postfx_texture_2d = shader_postfx->GetUniformLocation("texture_2d");
517    shader_postfx_screen_size = shader_postfx->GetUniformLocation("screen_size");
518    shader_postfx_time = shader_postfx->GetUniformLocation("time");
519    shader_postfx_deform = shader_postfx->GetUniformLocation("deform");
520    shader_postfx_ghost1 = shader_postfx->GetUniformLocation("ghost1");
521    shader_postfx_ghost2 = shader_postfx->GetUniformLocation("ghost2");
522    shader_postfx_vignetting = shader_postfx->GetUniformLocation("vignetting");
523    shader_postfx_aberration = shader_postfx->GetUniformLocation("aberration");
524    shader_postfx_moire_h = shader_postfx->GetUniformLocation("moire_h");
525    shader_postfx_moire_v = shader_postfx->GetUniformLocation("moire_v");
526    shader_postfx_scanline_h = shader_postfx->GetUniformLocation("scanline_h");
527    shader_postfx_scanline_v = shader_postfx->GetUniformLocation("scanline_v");
528    shader_postfx_corner = shader_postfx->GetUniformLocation("corner");
529    shader_postfx_sync = shader_postfx->GetUniformLocation("sync");
530
531    return true;
532}
533
534int Render::CreateGLWindow()
535{
536    UpdateSize();
537    InitDraw();
538    return true;
539}
540
541Render::Render(caca_canvas_t *caca)
542  : m_caca(caca),
543    m_ready(false),
544    m_pause(false),
545    m_polygon(true),
546    m_setup(true),
547    m_shader(true),
548    m_shader_glow(true),
549    m_shader_blur(true),
550    m_shader_remanency(true),
551    m_shader_copper(true),
552    m_shader_color(true),
553    m_shader_noise(true),
554    m_shader_postfx(true)
555{
556    text_render = new TextRender(m_caca, font_size);
557}
558
559void Render::TickGame(float seconds)
560{
561    Entity::TickGame(seconds);
562}
563
564void Render::Pause()
565{
566    m_pause=!m_pause;
567}
568
569void Render::TickDraw(float seconds)
570{
571    /* keyboard manager */
572    if (Input::WasReleased(Key::Escape))
573    {
574        Ticker::Shutdown();
575    }
576    if (Input::WasPressed(Key::F1))
577    {
578        m_setup = !m_setup;
579        if (m_setup) setup_n = calc_item_length();
580        sync_flag = true;
581        sync_angle = main_angle;
582    }
583    if (Input::WasPressed(Key::F2))
584    {
585        m_polygon = !m_polygon;
586        polygon_fillmode = (m_polygon)?GL_FILL:GL_LINE;
587        glPolygonMode(GL_FRONT, polygon_fillmode);
588    }
589   if (Input::WasPressed(Key::Tab))
590    {
591        if (m_setup)
592        {
593            setup_switch = !setup_switch;
594            setup_n = calc_item_length();
595            setup_cursor = (!setup_switch?setup_option_i:setup_item_i) - (!setup_switch?setup_option_p:setup_item_p);
596        }
597    }
598    if (Input::WasPressed(Key::Up))
599    {
600        if (m_setup)
601        {
602            if (!setup_switch)
603            {
604                if (setup_cursor > 0)
605                {
606                    setup_cursor--;
607                }
608                else
609                {
610                    if ((setup_option_p > 0) && setup_cursor == 0) setup_option_p--;
611                }
612                if (setup_option_i > 0)
613                {
614                    setup_option_i--;
615                }
616                else
617                {
618                    setup_option_i = setup_option_n - 1;
619                    setup_option_p = setup_option_n - setup_h;
620                    setup_cursor = setup_h - 1;
621                }
622                setup_item_i = 0;
623            }
624            else
625            {
626                setup_item_i--;
627                if (setup_item_i < 0) setup_item_i = setup_n;
628            }
629        }
630    }
631    if (Input::WasPressed(Key::Down))
632    {
633        if (m_setup)
634        {
635            if (!setup_switch)
636            {
637                if (setup_cursor < setup_h - 1)
638                {
639                    setup_cursor++;
640                }
641                else
642                {
643                    if ((setup_option_p + setup_h < setup_option_n) && setup_cursor == setup_h - 1) setup_option_p++;
644                }
645                if (setup_option_i < setup_option_n - 1)
646                {
647                    setup_option_i++;
648                }
649                else
650                {
651                    setup_option_i = 0;
652                    setup_option_p = 0;
653                    setup_cursor = 0;
654                }
655                setup_item_i = 0;
656            }
657            else
658            {
659                if (setup_cursor < setup_h - 1)
660                {
661                    setup_cursor++;
662                }
663                else
664                {
665                    if ((setup_item_p + setup_h < setup_n) && setup_cursor == setup_h - 1) setup_item_p++;
666                }
667                if (setup_item_i < setup_n)
668                {
669                    setup_item_i++;
670                }
671                else
672                {
673                    setup_item_i = 0;
674                    setup_item_p = 0;
675                    setup_cursor = 0;
676                }
677            }
678        }
679    }
680    if (Input::WasPressed(Key::PageUp))
681    {
682        if (m_setup)
683        {
684            if (!setup_switch)
685            {
686                setup_option_i -= setup_cursor;
687                setup_cursor = 0;
688                setup_item_i = 0;
689            }
690            else
691            {
692                setup_item_i -= setup_cursor;
693                setup_cursor = 0;
694            }
695        }
696    }
697    if (Input::WasPressed(Key::PageDown))
698    {
699        if (m_setup)
700        {
701            if (!setup_switch)
702            {
703                setup_option_i += setup_h - setup_cursor - 1;
704                setup_cursor = setup_h - 1;
705                setup_item_i = 0;
706            }
707            else
708            {
709                setup_item_i += setup_n - setup_cursor - 1;
710                setup_cursor = setup_h - 1;
711            }
712        }
713    }
714    if (Input::WasPressed(Key::Left))
715    {
716        if (m_setup && setup_switch)
717        {
718            setup_var[setup_item_key].w -= setup_var[setup_item_key].z;
719            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;
720            UpdateVar();
721        }
722    }
723    if (Input::WasPressed(Key::Right))
724    {
725        if (m_setup && setup_switch)
726        {
727            setup_var[setup_item_key].w += setup_var[setup_item_key].z;
728            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;
729            UpdateVar();
730        }
731    }
732    if (Input::WasPressed(Key::Home))
733    {
734        if (m_setup && setup_switch)
735        {
736            setup_var[setup_item_key].w = setup_var[setup_item_key].x;
737            UpdateVar();
738        }
739    }
740    if (Input::WasPressed(Key::End))
741    {
742        if (m_setup && setup_switch)
743        {
744            setup_var[setup_item_key].w = setup_var[setup_item_key].y;
745            UpdateVar();
746        }
747    }
748    if (Input::WasPressed(Key::Return))
749    {
750        flash_flag = true;
751        flash_angle = main_angle;
752    }
753
754    Entity::TickDraw(seconds);
755
756    if (!m_ready)
757    {
758        CreateGLWindow();
759        text_render->Init();
760        m_ready = true;
761    }
762
763    // timer
764    if (!m_pause)
765    {
766        timer += seconds;
767        main_angle = timer * 100.0f * PID;
768    }
769    if (sync_flag)
770    {
771        angle = (main_angle - sync_angle) * sync_speed;
772        sync_value = 1.0f - sinf(angle);
773        if (angle > 90.0f * PID)
774        {
775            sync_value = 0;
776            sync_flag = false;
777        }
778    }
779    if (beat_flag)
780    {
781        angle = (main_angle - beat_angle) * beat_speed;
782        beat_value = 1.0f - sinf(angle);
783        if (angle > 90.0f * PID)
784        {
785            beat_value = 0;
786            beat_flag = false;
787        }
788    }
789    if (flash_flag)
790    {
791        angle = (main_angle - flash_angle) * flash_speed;
792        flash_value = 1.0f - sinf(angle);
793        if (angle > 90.0f * PID)
794        {
795            flash_value = 0;
796            flash_flag = false;
797        }
798    }
799    if (fade_flag)
800    {
801        angle = (main_angle - fade_angle) * fade_speed;
802        fade_value = 1.0f - sinf(angle);
803        if (angle > 90.0f * PID)
804        {
805            fade_value = 0;
806            fade_flag = false;
807        }
808    }
809    /* draw setup */
810    if (m_setup)
811    {
812        /* background */
813        caca_set_color_argb(m_caca, setup_color.x, setup_color.y);
814        caca_fill_box(m_caca, setup_p.x, setup_p.y, setup_size.x + 1, setup_size.y,' ');
815        caca_draw_line(m_caca, setup_p.x + setup_size.z - 1, setup_p.y + 1, setup_p.x + setup_size.z - 1, setup_p.y + setup_size.y - 1,'|');
816        /* title */
817        caca_set_color_argb(m_caca, setup_color.y, setup_color.x);
818        caca_draw_line(m_caca, setup_p.x, setup_p.y, setup_p.x + setup_size.x, setup_p.y,' ');
819        caca_put_str(m_caca, setup_p.x + setup_size.x / 2 - 3, setup_p.y, "SETUP");
820        /* display option */
821        for (int i = 0; i < setup_h; i++)
822        {
823            int y = setup_p.y + 1 + i;
824            int k = (setup_option_p + i) * (setup_item_n + 1);
825            if (setup_option_i != setup_option_p + i || setup_switch)
826            {
827                caca_set_color_argb(m_caca, setup_color.x, setup_color.y);
828                caca_put_str(m_caca, setup_p.x + 1, y, setup_text[k]);
829            }
830            else
831            {
832                caca_set_color_argb(m_caca, setup_color.y, setup_color.x);
833                caca_draw_line(m_caca, setup_p.x, y, setup_p.x + setup_size.z - 2, y,' ');
834                caca_put_str(m_caca, setup_p.x + 1, y, setup_text[k]);
835            }
836        }
837        /* display item */
838        for (int i = 0; i < setup_h; i++)
839        {
840            int y = setup_p.y + 1 + i;
841            int k = setup_option_i * (setup_item_n + 1) + 1 + setup_item_p + i;
842            if (setup_item_i != setup_item_p + i || !setup_switch)
843            {
844                caca_set_color_argb(m_caca, setup_color.x, setup_color.y);
845                caca_put_str(m_caca, setup_p.x + setup_size.z + 1, y, setup_text[k]);
846            }
847            else
848            {
849                caca_set_color_argb(m_caca, setup_color.y, setup_color.x);
850                caca_draw_line(m_caca, setup_p.x + setup_size.z, y, setup_p.x + setup_size.x, y,' ');
851                caca_put_str(m_caca, setup_p.x + setup_size.z + 1, y, setup_text[k]);
852            }
853        }
854        /* display variable */
855        int y = setup_p.y + setup_size.y;
856        setup_item_key = setup_option_i * (setup_item_n + 1) + 1 + setup_item_i;
857        caca_set_color_argb(m_caca, setup_color.y, setup_color.x);
858        caca_draw_line(m_caca, setup_p.x, y, setup_p.x + setup_size.x, y,' ');
859        if (setup_switch)
860        {
861            int x = setup_p.x + 1;
862            int w = setup_size.x - 3 - 4;
863            int bar_w = w / (setup_var[setup_item_key].y - setup_var[setup_item_key].x);
864            int bar_x = bar_w * setup_var[setup_item_key].x;
865            if ((setup_var[setup_item_key].y - setup_var[setup_item_key].x) / setup_var[setup_item_key].z > 1)
866            {
867                caca_printf(m_caca, setup_p.x + setup_size.x - 4, y, "%4.2f", setup_var[setup_item_key].w);
868                caca_draw_line(m_caca, x, y, x - bar_x + bar_w * setup_var[setup_item_key].y, y,'.');
869                if (setup_var[setup_item_key].w != setup_var[setup_item_key].x) caca_draw_line(m_caca, x, y, x - bar_x + bar_w * setup_var[setup_item_key].w, y,'x');
870            }
871            else
872            {
873                if (setup_var[setup_item_key] != vec4(0))
874                {
875                    caca_put_str(m_caca, setup_p.x + setup_size.x - 3, y, (setup_var[setup_item_key].w == setup_var[setup_item_key].y)?"YES":" NO");
876                }
877            }
878        }
879    /* informations */
880    int w = caca_get_canvas_width(m_caca);
881    int h = caca_get_canvas_height(m_caca);
882    caca_set_color_argb(m_caca, 0xfff, 0x000);
883    caca_printf(m_caca, 0, 0, "%i*%i", w, h);
884    }
885
886    Draw2D();
887    Draw3D();
888
889}
890
891void Render::Draw2D()
892{
893    /* Draw text in an offline buffer */
894    text_render->Render();
895
896    if (m_shader)
897        fbo_back->Bind();
898
899    glViewport(0, 0, screen_size.x, screen_size.y);
900
901    /* Clear the back buffer */
902    glEnable(GL_BLEND);
903    glBlendFunc(GL_SRC_COLOR, GL_DST_ALPHA);
904
905    Video::SetClearColor(vec4(screen_color, 1.f));
906    Video::SetClearDepth(1.0f); // set depth buffer
907    Video::Clear(ClearMask::Color | ClearMask::Depth);
908
909    text_render->Blit(border, canvas_size);
910
911    //if (m_polygon) glEnable(GL_LINE_SMOOTH); else glDisable(GL_LINE_SMOOTH);
912    glLineWidth((m_polygon)?2.0f:1.0f);
913    fx_angle=main_angle-part_angle;
914    if (m_polygon)
915        glEnable(GL_TEXTURE_2D);
916
917    glMatrixMode(GL_PROJECTION);
918    mat4 m = mat4::ortho(0, screen_size.x, screen_size.y, 0, -1.f, 1.f);
919    glLoadMatrixf(&m[0][0]);
920    glMatrixMode(GL_MODELVIEW);
921}
922
923void Render::Draw3D()
924{
925    if (!m_shader)
926        return;
927
928    glDisable(GL_DEPTH_TEST);
929    glDisable(GL_BLEND);
930
931    glEnableClientState(GL_VERTEX_ARRAY);
932    glVertexPointer(4, GL_FLOAT, 0, fs_quad_vtx);
933
934    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
935    glTexCoordPointer(2, GL_FLOAT, 0, fs_quad_tex);
936
937    if (m_shader_copper)
938    {
939        // shader copper
940        fbo_tmp->Bind();
941        shader_copper->Bind();
942        shader_copper->SetUniform(shader_copper_texture, fbo_back->GetTexture(), 0);
943        shader_copper->SetUniform(shader_copper_screen_size, (vec2)screen_size);
944        shader_copper->SetUniform(shader_copper_time, fx_angle);
945        shader_copper->SetUniform(shader_copper_copper, copper);
946        TraceQuad();
947        shader_color->Unbind();
948        fbo_tmp->Unbind();
949        // shader simple
950        fbo_back->Bind();
951        ShaderSimple(fbo_tmp, 0);
952        fbo_back->Unbind();
953    }
954
955    if (m_shader_remanency)
956    {
957        // shader remanency
958        fbo_tmp->Bind();
959        shader_remanency->Bind();
960        shader_remanency->SetUniform(shader_remanency_source, fbo_back->GetTexture(), 0);
961        shader_remanency->SetUniform(shader_remanency_buffer, fbo_buffer->GetTexture(), 1);
962        shader_remanency->SetUniform(shader_remanency_mix, remanency);
963        TraceQuad();
964        shader_remanency->Unbind();
965        fbo_tmp->Unbind();
966        // shader simple
967        fbo_back->Bind();
968        ShaderSimple(fbo_tmp, 0);
969        fbo_back->Unbind();
970        // save previous fbo
971        fbo_tmp->Bind();
972        shader_remanency->Bind();
973        shader_remanency->SetUniform(shader_remanency_source, fbo_front->GetTexture(), 0);
974        shader_remanency->SetUniform(shader_remanency_buffer, fbo_buffer->GetTexture(), 1);
975        shader_remanency->SetUniform(shader_remanency_mix, buffer);
976        TraceQuad();
977        shader_remanency->Unbind();
978        fbo_tmp->Unbind();
979        // shader simple
980        fbo_buffer->Bind();
981        ShaderSimple(fbo_tmp, 0);
982        fbo_buffer->Unbind();
983    }
984
985    // shader glow
986    if (m_shader_glow)
987    {
988        // shader blur horizontal
989        fbo_blur_h->Bind();
990        shader_blur_h->Bind();
991        shader_blur_h->SetUniform(shader_blur_h_texture, fbo_back->GetTexture(), 0);
992        shader_blur_h->SetUniform(shader_blur_h_radius, glow_large / screen_size.x);
993        TraceQuad();
994        shader_blur_h->Unbind();
995        fbo_blur_h->Unbind();
996        // shader blur vertical
997        fbo_blur_v->Bind();
998        shader_blur_v->Bind();
999        shader_blur_v->SetUniform(shader_blur_v_texture, fbo_blur_h->GetTexture(), 0);
1000        shader_blur_v->SetUniform(shader_blur_v_radius, glow_large / screen_size.y);
1001        TraceQuad();
1002        shader_blur_v->Unbind();
1003        fbo_blur_v->Unbind();
1004        // shader blur horizontal
1005        fbo_blur_h->Bind();
1006        shader_blur_h->Bind();
1007        shader_blur_h->SetUniform(shader_blur_h_texture, fbo_blur_v->GetTexture(), 0);
1008        shader_blur_h->SetUniform(shader_blur_h_radius, glow_small / screen_size.x);
1009        TraceQuad();
1010        shader_blur_h->Unbind();
1011        fbo_blur_h->Unbind();
1012        // shader blur vertical
1013        fbo_blur_v->Bind();
1014        shader_blur_v->Bind();
1015        shader_blur_v->SetUniform(shader_blur_v_texture, fbo_blur_h->GetTexture(), 0);
1016        shader_blur_v->SetUniform(shader_blur_v_radius, glow_small / screen_size.y);
1017        TraceQuad();
1018        shader_blur_v->Unbind();
1019        fbo_blur_v->Unbind();
1020        // shader glow
1021        fbo_front->Bind();
1022        shader_glow->Bind();
1023        shader_glow->SetUniform(shader_glow_glow, fbo_blur_v->GetTexture(), 0);
1024        shader_glow->SetUniform(shader_glow_source, fbo_back->GetTexture(), 1);
1025        shader_glow->SetUniform(shader_glow_mix, glow_mix);
1026        TraceQuad();
1027        shader_glow->Unbind();
1028        fbo_front->Unbind();
1029    }
1030    else
1031    {
1032        // shader simple
1033        fbo_front->Bind();
1034        ShaderSimple(fbo_back, 0);
1035        fbo_front->Unbind();
1036    }
1037
1038    if (m_shader_color)
1039    {
1040        // shader color
1041        fbo_tmp->Bind();
1042        shader_color->Bind();
1043        shader_color->SetUniform(shader_color_texture, fbo_front->GetTexture(), 0);
1044        shader_color->SetUniform(shader_color_screen_size, (vec2)screen_size);
1045        shader_color->SetUniform(shader_color_filter, color_filter);
1046        shader_color->SetUniform(shader_color_color, color_color);
1047        shader_color->SetUniform(shader_color_flash, flash_value);
1048        TraceQuad();
1049        shader_color->Unbind();
1050        fbo_tmp->Unbind();
1051        // shader simple
1052        fbo_front->Bind();
1053        ShaderSimple(fbo_tmp, 0);
1054        fbo_front->Unbind();
1055    }
1056
1057    if (m_shader_noise)
1058    {
1059        // shader noise
1060        fbo_tmp->Bind();
1061        shader_noise->Bind();
1062        shader_noise->SetUniform(shader_noise_texture, fbo_front->GetTexture(), 0);
1063        shader_noise->SetUniform(shader_noise_screen_size, (vec2)screen_size);
1064        shader_noise->SetUniform(shader_noise_time, fx_angle);
1065        shader_noise->SetUniform(shader_noise_offset, noise_offset);
1066        shader_noise->SetUniform(shader_noise_noise, noise_noise);
1067        shader_noise->SetUniform(shader_noise_retrace, noise_retrace);
1068        TraceQuad();
1069        shader_noise->Unbind();
1070        fbo_tmp->Unbind();
1071        // shader simple
1072        fbo_front->Bind();
1073        ShaderSimple(fbo_tmp, 0);
1074        fbo_front->Unbind();
1075    }
1076
1077    if (m_shader_blur)
1078    {
1079        // shader blur horizontal
1080        fbo_tmp->Bind();
1081        shader_blur_h->Bind();
1082        shader_blur_h->SetUniform(shader_blur_h_texture, fbo_front->GetTexture(), 0);
1083        shader_blur_h->SetUniform(shader_blur_h_radius, blur / screen_size.x);
1084        TraceQuad();
1085        shader_blur_h->Unbind();
1086        fbo_tmp->Unbind();
1087        // shader blur vertical
1088        fbo_front->Bind();
1089        shader_blur_v->Bind();
1090        shader_blur_v->SetUniform(shader_blur_v_texture, fbo_tmp->GetTexture(), 0);
1091        shader_blur_v->SetUniform(shader_blur_v_radius, blur / screen_size.y);
1092        TraceQuad();
1093        shader_blur_v->Unbind();
1094        fbo_front->Unbind();
1095    }
1096
1097    if (m_shader_postfx)
1098    {
1099        // shader postfx
1100        shader_postfx->Bind();
1101        shader_postfx->SetUniform(shader_postfx_texture, fbo_front->GetTexture(), 0);
1102        shader_postfx->SetUniform(shader_postfx_screen_size, (vec2)screen_size);
1103        shader_postfx->SetUniform(shader_postfx_time, fx_angle);
1104        shader_postfx->SetUniform(shader_postfx_deform, postfx_deform);
1105        shader_postfx->SetUniform(shader_postfx_ghost1, postfx_ghost1);
1106        shader_postfx->SetUniform(shader_postfx_ghost2, postfx_ghost2);
1107        shader_postfx->SetUniform(shader_postfx_vignetting, postfx_vignetting);
1108        shader_postfx->SetUniform(shader_postfx_aberration, postfx_aberration);
1109        shader_postfx->SetUniform(shader_postfx_moire_h, postfx_moire_h);
1110        shader_postfx->SetUniform(shader_postfx_moire_v, postfx_moire_v);
1111        shader_postfx->SetUniform(shader_postfx_scanline_h, postfx_scanline_h);
1112        shader_postfx->SetUniform(shader_postfx_scanline_v, postfx_scanline_v);
1113        shader_postfx->SetUniform(shader_postfx_corner, postfx_corner);
1114        shader_postfx->SetUniform(shader_postfx_sync, (float)fabs(sync_value*cosf((main_angle-sync_angle)*6.0f)));
1115        TraceQuad();
1116        shader_postfx->Unbind();
1117    }
1118    else
1119    {
1120        // shader simple
1121        ShaderSimple(fbo_front, 0);
1122    }
1123
1124    glDisableClientState(GL_VERTEX_ARRAY);
1125    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
1126}
1127
1128Render::~Render()
1129{
1130}
Note: See TracBrowser for help on using the repository browser.