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

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

moved blur after glow, tweaked a lot of parameters

File size: 19.1 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_blurh;
35extern char const *lolfx_blurv;
36extern char const *lolfx_remanency;
37extern char const *lolfx_glow;
38extern char const *lolfx_postfx;
39extern char const *lolfx_radial;
40extern char const *lolfx_simple;
41
42#define PID M_PI/180.0f    // pi ratio
43#define CR 1.0f/256.0f     // color ratio
44
45/*
46 * Various variables
47 */
48
49int active = true;         // window active flag
50float nearplane = 0.1f;    // nearplane
51float farplane = 1000.0f;  // farplane
52int polygon_fillmode = GL_FILL; // fill mode
53bool key_state = 0;        // key state
54/* window variable */
55ivec2 screen_size;         // screen size
56vec3 screen_color = CR * vec3(32, 32, 32); // screen color
57/* object variable */
58float main_angle = 0.0f;   // main angle
59float part_angle = 0.0f;   // part angle
60float fx_angle;            // current angle
61/* fs_quad variable */
62float 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};
63float fs_quad_tex[] = {0, 1.0f, 0, 0, 1.0f, 0, 1.0f, 1.0f};
64/* flash variable */
65bool flash_flag = false;   // flag
66float flash_angle = 0;     // angle
67float flash_value = 0;     // value
68float flash_speed = 1.5f;  // speed
69/* fade variable */
70bool fade_flag = false;    // flag
71float fade_angle = 0;      // angle
72float fade_value = 0;      // value
73float fade_speed = 0.2f;   // speed
74/* sync variable */
75bool sync_flag = false;    // flagsh
76float sync_angle = 0;      // angle
77float sync_value = 1.0f;   // value
78float sync_speed = 1.0f;   // speed
79/* beat variable */
80bool beat_flag = false;    // flag
81float beat_angle = 0;      // angle
82float beat_value = 0;      // value
83float beat_speed = 2.0f;   // speed
84/* window variable */
85ivec2 border;              // border width
86/* text variable */
87ivec2 ratio_2d(2,4);       // 2d ratio
88ivec2 map_size(256,256);   // texture map size
89ivec2 font_size(8,8);      // font size
90ivec2 canvas_char(0,0);    // canvas char number
91ivec2 canvas_size(0,0);    // caca size
92/* common variable */
93float value, angle, radius, scale, speed;
94/* shader variable */
95vec2 buffer(0.75f,0.25f);       // [new frame mix,old frame mix]
96vec2 remanency(0.25f,0.75f);    // remanency [source mix,buffer mix]
97vec2 blur(0.25f,0.5f);          // glow radius [normal,deform]
98vec2 glow_mix(0.5f,0.5f);       // glow mix [glow mix,source mix]
99vec2 glow_large(2.0f,2.0f);     // large glow radius [normal,deform]
100vec2 glow_small(1.0f,1.0f);     // small glow radius [normal,deform]
101//vec3 radial(2.0f,0.8f,0);     // radial [mix,strength,color mode]
102//---------------------------------[IDEAS] http://www.youtube.com/watch?v=d1qEP2vMe-I
103float postfx_deform = 0.625f;   // deformation ratio
104vec3 postfx_filter(0.875f,1.0f,0.75f);// color filter [red,green,blue]
105vec3 postfx_retrace(0.025f,2.0f,4.0f);// retrace [color,length,speed]
106vec2 postfx_offset(3.0f,3.0f);  // random line [horizontal,vertical]
107float postfx_noise = 0.125f;    // noise
108float postfx_aberration = 3.0f; // chromatic aberration
109bool postfx_moire = true;       // moire
110vec4 postfx_moire_h(0.75f,-0.25f,1.0f,2.0f);
111vec4 postfx_moire_v(0.75f,-0.25f,0.0f,1.0f);
112bool postfx_scanline = true;    // scanline
113vec4 postfx_scanline_h(0.75f,-0.25f,2.0f,0.0f);// vertical scanline [base,variable,repeat]
114vec4 postfx_scanline_v(0.75f, 0.25f,0.0f,2.0f);// horizontal scanline [base,variable,repeat]
115
116Shader *shader_simple;
117Shader *shader_blur_h, *shader_blur_v;
118Shader *shader_remanency, *shader_glow, *shader_radial, *shader_postfx;
119// shader variables
120ShaderUniform shader_simple_texture;
121ShaderUniform shader_blur_h_texture,
122              shader_blur_h_radius,
123              shader_blur_v_texture,
124              shader_blur_v_radius;
125ShaderUniform shader_remanency_source,
126              shader_remanency_buffer,
127              shader_remanency_mix;
128ShaderUniform shader_glow_glow,
129              shader_glow_source,
130              shader_glow_mix;
131ShaderUniform shader_radial_texture,
132              shader_radial_screen_size,
133              shader_radial_time,
134              shader_radial_value1,
135              shader_radial_value2,
136              shader_radial_color;
137ShaderUniform shader_postfx_texture,
138              shader_postfx_texture_2d,
139              shader_postfx_screen_size,
140              shader_postfx_time,
141              shader_postfx_deform,
142              shader_postfx_filter,
143              shader_postfx_retrace,
144              shader_postfx_offset,
145              shader_postfx_noise,
146              shader_postfx_aberration,
147              shader_postfx_moire,
148              shader_postfx_moire_h,
149              shader_postfx_moire_v,
150              shader_postfx_scanline,
151              shader_postfx_scanline_h,
152              shader_postfx_scanline_v,
153              shader_postfx_flash,
154              shader_postfx_sync;
155
156FrameBuffer *fbo_back, *fbo_front, *fbo_buffer;
157FrameBuffer *fbo_blur_h, *fbo_blur_v, *fbo_ping, *fbo_pong;
158
159TextRender *text_render;
160
161void fs_quad()
162{
163    glLoadIdentity();
164    glDrawArrays(GL_QUADS, 0, 4);
165}
166
167void draw_shader_simple(FrameBuffer *fbo_output, int n)
168{
169    shader_simple->Bind();
170    shader_simple->SetTexture(shader_simple_texture, fbo_output->GetTexture(), n);
171    fs_quad();
172    shader_simple->Unbind();
173}
174
175void rectangle(int x, int y, int w, int h)
176{
177    glLoadIdentity();
178    glBegin(GL_QUADS);
179        glVertex2i(x+w, y  );
180        glVertex2i(x  , y  );
181        glVertex2i(x  , y+h);
182        glVertex2i(x+w, y+h);
183    glEnd();
184}
185
186int Render::InitDraw(void)
187{
188    glDepthMask(GL_TRUE);     // do not write z-buffer
189    glEnable(GL_CULL_FACE);   // disable cull face
190    glCullFace(GL_BACK);      // don't draw front face
191
192    /* Initialise framebuffer objects */
193    fbo_back = new FrameBuffer(screen_size);
194    fbo_front = new FrameBuffer(screen_size);
195    fbo_buffer = new FrameBuffer(screen_size);
196    fbo_blur_h = new FrameBuffer(screen_size);
197    fbo_blur_v = new FrameBuffer(screen_size);
198    fbo_ping = new FrameBuffer(screen_size);
199    fbo_pong = new FrameBuffer(screen_size);
200    // shader simple
201    shader_simple = Shader::Create(lolfx_simple);
202    shader_simple_texture = shader_simple->GetUniformLocation("texture");
203    // shader blur horizontal
204    shader_blur_h = Shader::Create(lolfx_blurh);
205    shader_blur_h_texture = shader_blur_h->GetUniformLocation("texture");
206    shader_blur_h_radius = shader_blur_h->GetUniformLocation("radius");
207    // shader blur vertical
208    shader_blur_v = Shader::Create(lolfx_blurv);
209    shader_blur_v_texture = shader_blur_v->GetUniformLocation("texture");
210    shader_blur_v_radius = shader_blur_v->GetUniformLocation("radius");
211    // shader remanency
212    shader_remanency = Shader::Create(lolfx_remanency);
213    shader_remanency_source = shader_remanency->GetUniformLocation("source");
214    shader_remanency_buffer = shader_remanency->GetUniformLocation("buffer");
215    shader_remanency_mix = shader_remanency->GetUniformLocation("mix");
216    // shader glow
217    shader_glow = Shader::Create(lolfx_glow);
218    shader_glow_glow = shader_glow->GetUniformLocation("glow");
219    shader_glow_source = shader_glow->GetUniformLocation("source");
220    shader_glow_mix = shader_glow->GetUniformLocation("mix");
221    // shader radial
222    shader_radial = Shader::Create(lolfx_radial);
223    shader_radial_texture = shader_radial->GetUniformLocation("texture");
224    shader_radial_screen_size = shader_radial->GetUniformLocation("screen_size");
225    shader_radial_time = shader_radial->GetUniformLocation("time");
226    shader_radial_value1 = shader_radial->GetUniformLocation("value1");
227    shader_radial_value2 = shader_radial->GetUniformLocation("value2");
228    shader_radial_color = shader_radial->GetUniformLocation("color");
229    // shader postfx
230    shader_postfx = Shader::Create(lolfx_postfx);
231    shader_postfx_texture = shader_postfx->GetUniformLocation("texture");
232    shader_postfx_texture_2d = shader_postfx->GetUniformLocation("texture_2d");
233    shader_postfx_screen_size = shader_postfx->GetUniformLocation("screen_size");
234    shader_postfx_time = shader_postfx->GetUniformLocation("time");
235    shader_postfx_deform = shader_postfx->GetUniformLocation("deform");
236    shader_postfx_filter = shader_postfx->GetUniformLocation("filter");
237    shader_postfx_retrace = shader_postfx->GetUniformLocation("retrace");
238    shader_postfx_offset = shader_postfx->GetUniformLocation("offset");
239    shader_postfx_noise = shader_postfx->GetUniformLocation("noise");
240    shader_postfx_aberration = shader_postfx->GetUniformLocation("aberration");
241    shader_postfx_moire = shader_postfx->GetUniformLocation("moire");
242    shader_postfx_moire_h = shader_postfx->GetUniformLocation("moire_h");
243    shader_postfx_moire_v = shader_postfx->GetUniformLocation("moire_v");
244    shader_postfx_scanline = shader_postfx->GetUniformLocation("scanline");
245    shader_postfx_scanline_h = shader_postfx->GetUniformLocation("scanline_h");
246    shader_postfx_scanline_v = shader_postfx->GetUniformLocation("scanline_v");
247    shader_postfx_flash = shader_postfx->GetUniformLocation("flash");
248    shader_postfx_sync = shader_postfx->GetUniformLocation("sync");
249
250    return true;
251}
252
253int Render::CreateGLWindow()
254{
255    screen_size = Video::GetSize();
256    border = 18 * ratio_2d;
257    border.y = border.x; // enabled to get same border everywhere
258    canvas_char = (screen_size - border * 2) / (font_size * ratio_2d);
259    canvas_size = canvas_char * font_size * ratio_2d;
260
261    border = (screen_size - canvas_size) / 2;
262
263    caca_set_canvas_size(m_caca, canvas_char.x, canvas_char.y);
264
265    InitDraw();
266    return true;
267}
268
269Render::Render(caca_canvas_t *caca)
270  : m_caca(caca),
271    m_ready(false),
272    m_pause(false),
273    m_polygon(true),
274    m_shader(true),
275    m_shader_remanency(true),
276    m_shader_glow(true),
277    m_shader_blur(true),
278    m_shader_fx(true),
279    m_shader_postfx(true),
280    m_border(false)
281{
282    text_render = new TextRender(m_caca, font_size);
283}
284
285void Render::TickGame(float seconds)
286{
287    Entity::TickGame(seconds);
288}
289
290void Render::Pause()
291{
292    m_pause=!m_pause;
293}
294
295void Render::TickDraw(float seconds)
296{
297    /* keyboard manager */
298    if (Input::GetButtonState(27/*SDLK_ESCAPE*/))
299        Ticker::Shutdown();
300    //if (Input::GetButtonState(282/*SDLK_F1*/))
301    //    LEAULE();
302    if (Input::GetButtonState(283/*SDLK_F2*/))
303        {
304        m_polygon=!m_polygon;
305        polygon_fillmode=(m_polygon)?GL_FILL:GL_LINE;
306        glPolygonMode(GL_FRONT,polygon_fillmode);
307        }
308    if (Input::GetButtonState(284/*SDLK_F3*/)&&key_state!=284)
309        {
310        m_shader=!m_shader;
311        key_state=284;
312        }
313    if (Input::GetButtonState(285/*SDLK_F4*/))
314        m_shader_postfx=!m_shader_postfx;
315    if (Input::GetButtonState(286/*SDLK_F5*/))
316        Pause();
317
318    Entity::TickDraw(seconds);
319
320    if (!m_ready)
321    {
322        CreateGLWindow();
323        text_render->Init();
324        m_ready = true;
325    }
326
327    // timer
328    if (!m_pause)
329        main_angle += seconds * 100.0f * PID;
330    if (sync_flag)
331    {
332        angle=(main_angle-sync_angle)*sync_speed;
333        sync_value=1.0f-sinf(angle);
334        if (angle>90.0f*PID)
335        {
336            sync_value=0;
337            sync_flag=false;
338        }
339    }
340    if (beat_flag)
341    {
342        angle=(main_angle-beat_angle)*beat_speed;
343        beat_value=1.0f-sinf(angle);
344        if (angle>90.0f*PID)
345        {
346            beat_value=0;
347            beat_flag=false;
348        }
349    }
350    if (flash_flag)
351    {
352        angle=(main_angle-flash_angle)*flash_speed;
353        flash_value=1.0f-sinf(angle);
354        if (angle>90.0f*PID)
355        {
356            flash_value=0;
357            flash_flag=false;
358        }
359    }
360    if (fade_flag)
361    {
362        angle=(main_angle-fade_angle)*fade_speed;
363        fade_value=1.0f-sinf(angle);
364        if (angle>90.0f*PID)
365        {
366            fade_value=0;
367            fade_flag=false;
368        }
369    }
370
371    Draw2D();
372    Draw3D();
373}
374
375void Render::Draw2D()
376{
377    /* Draw text in an offline buffer */
378    text_render->Render();
379
380    if (m_shader)
381    {
382        fbo_back->Bind();
383    }
384
385    glViewport(0, 0, screen_size.x, screen_size.y);
386
387    /* Clear the back buffer */
388    glEnable(GL_BLEND);
389    glBlendFunc(GL_SRC_COLOR,GL_DST_ALPHA);
390    glClearColor(screen_color.r, screen_color.g, screen_color.b, 1.0f);
391    glClearDepth(1.0f); // set depth buffer
392    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
393
394    text_render->Blit(border, canvas_size);
395
396    //if (m_polygon) glEnable(GL_LINE_SMOOTH); else glDisable(GL_LINE_SMOOTH);
397    glLineWidth((m_polygon)?2.0f:1.0f);
398    fx_angle=main_angle-part_angle;
399    if (m_polygon)
400        glEnable(GL_TEXTURE_2D);
401
402    glMatrixMode(GL_PROJECTION);
403    mat4 m = mat4::ortho(0, screen_size.x, screen_size.y, 0, -1.f, 1.f);
404    glLoadMatrixf(&m[0][0]);
405    glMatrixMode(GL_MODELVIEW);
406    // draw border
407    if (m_border)
408    {
409        glDisable(GL_TEXTURE_2D);
410        glDisable(GL_BLEND);
411        glColor3f(1.0f, 1.0f, 1.0f);
412        rectangle(border.x - ratio_2d.x, border.y - ratio_2d.y, canvas_size.x + ratio_2d.x * 2, ratio_2d.y);
413        rectangle(border.x - ratio_2d.x, border.y, ratio_2d.x, canvas_size.y);
414        rectangle(border.x + canvas_size.x, border.y, ratio_2d.x, canvas_size.y);
415        rectangle(border.x - ratio_2d.x, border.y + canvas_size.y, canvas_size.x + ratio_2d.x * 2, ratio_2d.y);
416        glEnable(GL_BLEND);
417    }
418}
419
420void Render::Draw3D()
421{
422    if (!m_shader)
423        return;
424
425    glDisable(GL_DEPTH_TEST);
426    glDisable(GL_BLEND);
427
428    glEnableClientState(GL_VERTEX_ARRAY);
429    glVertexPointer(4, GL_FLOAT, 0, fs_quad_vtx);
430
431    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
432    glTexCoordPointer(2, GL_FLOAT, 0, fs_quad_tex);
433
434    if (m_shader_remanency)
435    {
436        // shader remanency
437        fbo_ping->Bind();
438        shader_remanency->Bind();
439        shader_remanency->SetTexture(shader_remanency_source, fbo_back->GetTexture(), 0);
440        shader_remanency->SetTexture(shader_remanency_buffer, fbo_buffer->GetTexture(), 1);
441        shader_remanency->SetUniform(shader_remanency_mix, remanency);
442        fs_quad();
443        shader_remanency->Unbind();
444        fbo_ping->Unbind();
445        // shader simple
446        fbo_back->Bind();
447        draw_shader_simple(fbo_ping, 0);
448        fbo_back->Unbind();
449        // save previous fbo
450        fbo_ping->Bind();
451        shader_remanency->Bind();
452        shader_remanency->SetTexture(shader_remanency_source, fbo_front->GetTexture(), 0);
453        shader_remanency->SetTexture(shader_remanency_buffer, fbo_buffer->GetTexture(), 1);
454        shader_remanency->SetUniform(shader_remanency_mix, buffer);
455        fs_quad();
456        shader_remanency->Unbind();
457        fbo_ping->Unbind();
458        // shader simple
459        fbo_buffer->Bind();
460        draw_shader_simple(fbo_ping, 0);
461        fbo_buffer->Unbind();
462    }
463
464    // shader glow
465    if (m_shader_fx && m_shader_glow)
466    {
467        // shader blur horizontal
468        fbo_blur_h->Bind();
469        shader_blur_h->Bind();
470        shader_blur_h->SetTexture(shader_blur_h_texture, fbo_back->GetTexture(), 0);
471        shader_blur_h->SetUniform(shader_blur_h_radius, glow_large / screen_size.x);
472        fs_quad();
473        shader_blur_h->Unbind();
474        fbo_blur_h->Unbind();
475        // shader blur vertical
476        fbo_blur_v->Bind();
477        shader_blur_v->Bind();
478        shader_blur_v->SetTexture(shader_blur_v_texture, fbo_blur_h->GetTexture(), 0);
479        shader_blur_v->SetUniform(shader_blur_v_radius, glow_large / screen_size.y);
480        fs_quad();
481        shader_blur_v->Unbind();
482        fbo_blur_v->Unbind();
483        // shader blur horizontal
484        fbo_blur_h->Bind();
485        shader_blur_h->Bind();
486        shader_blur_h->SetTexture(shader_blur_h_texture, fbo_blur_v->GetTexture(), 0);
487        shader_blur_h->SetUniform(shader_blur_h_radius, glow_small / screen_size.x);
488        fs_quad();
489        shader_blur_h->Unbind();
490        fbo_blur_h->Unbind();
491        // shader blur vertical
492        fbo_blur_v->Bind();
493        shader_blur_v->Bind();
494        shader_blur_v->SetTexture(shader_blur_v_texture, fbo_blur_h->GetTexture(), 0);
495        shader_blur_v->SetUniform(shader_blur_v_radius, glow_small / screen_size.y);
496        fs_quad();
497        shader_blur_v->Unbind();
498        fbo_blur_v->Unbind();
499        // shader glow
500        fbo_front->Bind();
501        shader_glow->Bind();
502        shader_glow->SetTexture(shader_glow_glow, fbo_blur_v->GetTexture(), 0);
503        shader_glow->SetTexture(shader_glow_source, fbo_back->GetTexture(), 1);
504        shader_glow->SetUniform(shader_glow_mix, glow_mix);
505        fs_quad();
506        shader_glow->Unbind();
507        fbo_front->Unbind();
508    }
509    else
510    {
511        // shader simple
512        fbo_front->Bind();
513        draw_shader_simple(fbo_back, 0);
514        fbo_front->Unbind();
515    }
516
517    if (m_shader_fx && m_shader_blur)
518    {
519        // shader blur horizontal
520        fbo_ping->Bind();
521        shader_blur_h->Bind();
522        shader_blur_h->SetTexture(shader_blur_h_texture, fbo_front->GetTexture(), 0);
523        shader_blur_h->SetUniform(shader_blur_h_radius, blur / screen_size.x);
524        fs_quad();
525        shader_blur_h->Unbind();
526        fbo_ping->Unbind();
527        // shader blur vertical
528        fbo_front->Bind();
529        shader_blur_v->Bind();
530        shader_blur_v->SetTexture(shader_blur_v_texture, fbo_ping->GetTexture(), 0);
531        shader_blur_v->SetUniform(shader_blur_v_radius, blur / screen_size.y);
532        fs_quad();
533        shader_blur_v->Unbind();
534        fbo_front->Unbind();
535    }
536
537    if (m_shader_postfx)
538    {
539        // shader postfx
540        shader_postfx->Bind();
541        shader_postfx->SetTexture(shader_postfx_texture, fbo_front->GetTexture(), 0);
542        shader_postfx->SetUniform(shader_postfx_screen_size, (vec2)screen_size);
543        shader_postfx->SetUniform(shader_postfx_time, fx_angle);
544        shader_postfx->SetUniform(shader_postfx_deform, postfx_deform);
545        shader_postfx->SetUniform(shader_postfx_filter, postfx_filter);
546        shader_postfx->SetUniform(shader_postfx_retrace, postfx_retrace);
547        shader_postfx->SetUniform(shader_postfx_offset, postfx_offset);
548        shader_postfx->SetUniform(shader_postfx_noise, postfx_noise);
549        shader_postfx->SetUniform(shader_postfx_aberration, postfx_aberration);
550        shader_postfx->SetUniform(shader_postfx_moire, postfx_moire);
551        shader_postfx->SetUniform(shader_postfx_moire_h, postfx_moire_h);
552        shader_postfx->SetUniform(shader_postfx_moire_v, postfx_moire_v);
553        shader_postfx->SetUniform(shader_postfx_scanline, postfx_scanline);
554        shader_postfx->SetUniform(shader_postfx_scanline_h, postfx_scanline_h);
555        shader_postfx->SetUniform(shader_postfx_scanline_v, postfx_scanline_v);
556        shader_postfx->SetUniform(shader_postfx_flash, flash_value);
557        shader_postfx->SetUniform(shader_postfx_sync, (float)fabs(beat_value*cosf((main_angle-beat_angle)*8.0f)));
558        fs_quad();
559        shader_postfx->Unbind();
560    }
561    else
562    {
563        // shader simple
564        draw_shader_simple(fbo_front, 0);
565    }
566
567    glDisableClientState(GL_VERTEX_ARRAY);
568    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
569}
570
571Render::~Render()
572{
573}
Note: See TracBrowser for help on using the repository browser.