/* * demoscene-eo, an ASCII art demoscene written as a gift for Emmanuel Otton retirement * Copyright (C) 2019 XXXXXX XXXXXXX * * This file is part of demoscene-eo. * * demoscene-eo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * demoscene-eo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with demoscene-eo. If not, see */ #include "scene01.h" // Mostly inspired by CC0 https://gist.github.com/koute/7391344 typedef float t_mat4x4[16]; static inline void mat4x4_ortho(t_mat4x4 out, float left, float right, float bottom, float top, float znear, float zfar) { #define T(a, b) (a * 4 + b) out[T(0,0)] = 2.0f / (right - left); out[T(0,1)] = 0.0f; out[T(0,2)] = 0.0f; out[T(0,3)] = 0.0f; out[T(1,1)] = 2.0f / (top - bottom); out[T(1,0)] = 0.0f; out[T(1,2)] = 0.0f; out[T(1,3)] = 0.0f; out[T(2,2)] = -2.0f / (zfar - znear); out[T(2,0)] = 0.0f; out[T(2,1)] = 0.0f; out[T(2,3)] = 0.0f; out[T(3,0)] = -(right + left) / (right - left); out[T(3,1)] = -(top + bottom) / (top - bottom); out[T(3,2)] = -(zfar + znear) / (zfar - znear); out[T(3,3)] = 1.0f; #undef T } static const char * vertex_shader = "#version 130\n" "in vec2 i_position;\n" "in vec4 i_color;\n" "out vec4 v_color;\n" "uniform mat4 u_projection_matrix;\n" "void main() {\n" " v_color = i_color;\n" " gl_Position = u_projection_matrix * vec4(i_position, 0.0, 1.0);\n" "}\n"; static const char * fragment_shader = "#version 130\n" "in vec4 v_color;\n" "out vec4 o_color;\n" "void main() {\n" " o_color = v_color;\n" "}\n"; typedef enum t_attrib_id { attrib_position, attrib_color } t_attrib_id; int scene01_init_gl(graphical_env_t *ge, scene01_env_t *se) { GLuint vs, fs, program; TRACE("call"); vs = glCreateShader(GL_VERTEX_SHADER); fs = glCreateShader(GL_FRAGMENT_SHADER); int length = strlen(vertex_shader); glShaderSource(vs, 1, (const GLchar **)&vertex_shader, &length); glCompileShader(vs); GLint status; glGetShaderiv(vs, GL_COMPILE_STATUS, &status); if(status == GL_FALSE) return 40; length = strlen(fragment_shader); glShaderSource(fs, 1, (const GLchar **)&fragment_shader, &length); glCompileShader(fs); glGetShaderiv(fs, GL_COMPILE_STATUS, &status); if(status == GL_FALSE) return 41; program = glCreateProgram(); glAttachShader(program, vs); glAttachShader(program, fs); glBindAttribLocation(program, attrib_position, "i_position"); glBindAttribLocation(program, attrib_color, "i_color"); glLinkProgram(program); glUseProgram(program); glDisable(GL_DEPTH_TEST); glClearColor(0.5, 0.0, 0.0, 0.0); glViewport(0, 0, FBUF_W, FBUF_H); GLuint vbo; glGenVertexArrays(1, &(se->vao)); glGenBuffers(1, &vbo); glBindVertexArray(se->vao); glBindBuffer(GL_ARRAY_BUFFER, vbo); glEnableVertexAttribArray(attrib_position); glEnableVertexAttribArray(attrib_color); glVertexAttribPointer(attrib_color, 4, GL_FLOAT, GL_FALSE, sizeof(float)*6, 0); glVertexAttribPointer(attrib_position, 2, GL_FLOAT, GL_FALSE, sizeof(float)*6, (void *)(4*sizeof(float))); const GLfloat g_vertex_buffer_data[] = { /* R, G, B, A, X, Y */ 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, FBUF_W, 0, 0, 0, 1, 1, FBUF_W, FBUF_H, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, FBUF_W, FBUF_H, 1, 1, 1, 1, 0, FBUF_H }; glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW); t_mat4x4 projection_matrix; mat4x4_ortho(projection_matrix, 0.0f, (float)FBUF_W, (float)FBUF_H, 0.0f, 0.0f, 100.0f); glUniformMatrix4fv(glGetUniformLocation(program, "u_projection_matrix"), 1, GL_FALSE, projection_matrix); return 0; } int scene01_init_sdl(graphical_env_t *ge, scene01_env_t *se) { TRACE("call"); return 0; } int scene01_init_caca(graphical_env_t *ge, scene01_env_t *se) { TRACE("call"); return 0; } void scene01_free_gl(graphical_env_t *ge, scene01_env_t *se) { TRACE("call"); //TODO } void scene01_free_sdl(graphical_env_t *ge, scene01_env_t *se) { TRACE("call"); } void scene01_free_caca(graphical_env_t *ge, scene01_env_t *se) { TRACE("call"); } int scene01_next_gl(graphical_env_t *ge, scene01_env_t *se) { SDL_Renderer *r = ge->gl_rndr; TRACE_CALL_ONCE; // https://gist.github.com/Twinklebear/8265888 // https://forums.libsdl.org/viewtopic.php?p=51634 glClear(GL_COLOR_BUFFER_BIT); glBindVertexArray(se->vao); glDrawArrays(GL_TRIANGLES, 0, 6); // [...] //SDL_GL_SwapWindow(ge->gl_win); // Download the rendered texture from videocard to main memory SDL_RenderReadPixels(r, NULL, 0, ge->raw_target, FBUF_W*4); return 0; } int scene01_next_sdl(graphical_env_t *ge, scene01_env_t *se) { TRACE_CALL_ONCE; return 0; } int scene01_next_caca(graphical_env_t *ge, scene01_env_t *se) { // Shorthands caca_canvas_t *cv = ge->cv; int w = ge->w, h = ge->h; Uint32 frame = ge->sc_framecount; TRACE_CALL_ONCE; // "convert" the raw pixel stream from SDL to ASCII art on caca canevas caca_set_dither_gamma(ge->d, 1.0); caca_dither_bitmap(cv, 0, 0, w, h, ge->d, ge->raw_target); // Add things on top of caca canvas caca_set_color_ansi(cv, CACA_WHITE, CACA_BLACK); caca_put_str(cv, (w-17)/2, h/2, "This is a message"); if (frame >= 300) { return 1; } return 0; }