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

Last change on this file since 1623 was 1623, checked in by rez, 10 years ago

updated window frame, borders and cacanvas size

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