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

Last change on this file since 1627 was 1626, checked in by sam, 11 years ago

neercs: always initialise shaders at launch time, so we don’t have to do
it later. AGAIN.

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