From e17f14db7213fd27c4fa864ca57e6c2b4dbd79ec Mon Sep 17 00:00:00 2001 From: Ludovic Pouzenc Date: Mon, 2 Sep 2019 21:33:14 +0200 Subject: First try for GL drawing. Scene 00 cannot render after scene01_init. --- src/main.c | 22 +-------- src/main.h | 2 + src/scene01.c | 153 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- src/scene01.h | 2 +- 4 files changed, 154 insertions(+), 25 deletions(-) diff --git a/src/main.c b/src/main.c index a73bf44..3f18052 100644 --- a/src/main.c +++ b/src/main.c @@ -77,28 +77,10 @@ int main(void) if ( ge.sdl_target == NULL ) return 9; ge.raw_target = malloc(256*256*4); if ( ge.raw_target == NULL ) return 10; - ge.gl_ctx = SDL_GL_CreateContext(ge.sdl_win); - if ( ge.gl_ctx == NULL ) return 11; - // Initialize OpenGL - glShadeModel(GL_SMOOTH); - glClearDepth(1.0f); - glEnable(GL_DEPTH_TEST); - glDepthFunc(GL_LEQUAL); - glClearColor(0.0f, 0.0f, 0.0f, 0.0f); - glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); - - glDisable(GL_TEXTURE_2D); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - glEnable(GL_CULL_FACE); - glCullFace(GL_FRONT); - glViewport(0, 0, (GLsizei)256, (GLsizei)256); - glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(45.0f, 1.0f, 0.1f, 100.0f); // 1.0f==ratio - glMatrixMode(GL_MODELVIEW); glLoadIdentity(); + ge.gl_ctx = SDL_GL_CreateContext(ge.sdl_win); + if ( ge.gl_ctx == NULL ) return 11; // Main libcaca loop for caca window (OpenGL could be used in sceneN_next()) ge.framecount=0; diff --git a/src/main.h b/src/main.h index b2b0a6e..1ff41ec 100644 --- a/src/main.h +++ b/src/main.h @@ -1,6 +1,8 @@ #ifndef MAIN_H_INCLUDED #define MAIN_H_INCLUDED +#define GL_GLEXT_PROTOTYPES + #include #include #include diff --git a/src/scene01.c b/src/scene01.c index 2b3e9f5..80cbae2 100644 --- a/src/scene01.c +++ b/src/scene01.c @@ -19,11 +19,140 @@ */ #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(graphical_env_t *ge, scene01_env_t *se) { + int width = 256, height = 256; + GLuint vs, fs, program; + + 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 ) + { + fprintf( stderr, "vertex shader compilation failed\n" ); + return 1; + } + + length = strlen( fragment_shader ); + glShaderSource( fs, 1, ( const GLchar ** )&fragment_shader, &length ); + glCompileShader( fs ); + + glGetShaderiv( fs, GL_COMPILE_STATUS, &status ); + if( status == GL_FALSE ) + { + fprintf( stderr, "fragment shader compilation failed\n" ); + return 1; + } + + 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 ); + glClearColor( 0.5, 0.5, 0.0, 0.0 ); + glViewport( 0, 0, width, height ); + + 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, width, 0, + 0, 0, 1, 1, width, height, + + 1, 0, 0, 1, 0, 0, + 0, 0, 1, 1, width, height, + 1, 1, 1, 1, 0, height + }; + + 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)width, (float)height, 0.0f, 0.0f, 100.0f ); + glUniformMatrix4fv( glGetUniformLocation( program, "u_projection_matrix" ), 1, GL_FALSE, projection_matrix ); return 0; } void scene01_free(graphical_env_t *ge, scene01_env_t *se) { + //FIXME scene00 cannot be rendered coorectly after scene01_init done once } int scene01_next(graphical_env_t *ge, scene01_env_t *se) { @@ -31,13 +160,29 @@ int scene01_next(graphical_env_t *ge, scene01_env_t *se) { caca_canvas_t *cv = ge->cv; int w = ge->w, h = ge->h; Uint32 frame = ge->sc_framecount; + SDL_Renderer *r = ge->sdl_rndr; + // Locals + int res; + + // Render all the stuff on target texture + //SDL_SetRenderTarget(r, ge->sdl_target); + + glClear( GL_COLOR_BUFFER_BIT ); + glBindVertexArray( se->vao ); + glDrawArrays( GL_TRIANGLES, 0, 6 ); + SDL_GL_SwapWindow( ge->sdl_win ); - //XXX remove me - ((Uint32 *)ge->raw_target)[frame%(256*256)]=frame<<((frame%3)*8); + // Copy the SDL screen to SDL debug window (and display it, not mandatory) + //SDL_SetRenderTarget(r, NULL); + //SDL_RenderCopy(r, ge->sdl_target, NULL, NULL); + //SDL_RenderPresent(r); + + // Download the rendered texture from videocard to main memory + res = SDL_RenderReadPixels(r, NULL, 0, ge->raw_target, 256*4); - caca_clear_canvas(cv); + // "convert" the raw pixel stream to ASCII art on caca canevas caca_set_dither_gamma(ge->d, (100-frame%100)/100.0); - caca_dither_bitmap(cv, 0, 0, w, h, ge->d, ge->raw_target); + if ( res == 0 ) caca_dither_bitmap(cv, 0, 0, w, h, ge->d, ge->raw_target); caca_set_color_ansi(cv, CACA_WHITE, CACA_BLACK); caca_put_str(cv, (w-17)/2, h/2, "This is a message"); diff --git a/src/scene01.h b/src/scene01.h index 1f22de7..ecad8df 100644 --- a/src/scene01.h +++ b/src/scene01.h @@ -3,7 +3,7 @@ #include "main.h" typedef struct { - + GLuint vao; } scene01_env_t; int scene01_init(graphical_env_t *ge, scene01_env_t *se); -- cgit v1.2.3