X-Git-Url: https://harrygodden.com/git/?p=fishladder.git;a=blobdiff_plain;f=render.h;fp=render.h;h=b451611dd6b61d67fa2daaca01f7f08cbf92f835;hp=0000000000000000000000000000000000000000;hb=4caef139af0996dfb541b7c0b1b1ab31864840ee;hpb=0376d40412c8a4ca4762edad190b07c745ee897e diff --git a/render.h b/render.h new file mode 100644 index 0000000..b451611 --- /dev/null +++ b/render.h @@ -0,0 +1,177 @@ +static void init_mesh( struct mesh *m, float const *tris, u32 length ){ + m->elements = length/3; + glGenVertexArrays( 1, &m->vao ); + glGenBuffers( 1, &m->vbo ); + + glBindVertexArray( m->vao ); + glBindBuffer( GL_ARRAY_BUFFER, m->vbo ); + glBufferData( GL_ARRAY_BUFFER, length*sizeof(float), tris, GL_STATIC_DRAW ); + + glVertexAttribPointer( 0, 2, GL_FLOAT, GL_FALSE, 2*sizeof(float), (void*)0 ); + glEnableVertexAttribArray( 0 ); + + VG_CHECK_GL(); +} + +static void free_mesh( struct mesh *m ){ + glDeleteVertexArrays( 1, &m->vao ); + glDeleteBuffers( 1, &m->vbo ); +} + +static void draw_mesh( int const start, int const count ){ + glDrawArrays( GL_TRIANGLES, start*3, count*3 ); +} + +static void use_mesh( struct mesh *m ){ + glBindVertexArray( m->vao ); +} + +#define TRANSFORM_TRI_2D( S, OX, OY, X1, Y1, X2, Y2, X3, Y3 ) \ + X1*S+OX, Y1*S+OY, X2*S+OX, Y2*S+OY, X3*S+OX, Y3*S+OY + +static void render_init(void){ + // Combined quad, long quad / empty circle / filled circle mesh + float combined_mesh[6*6 + 32*6*3] = { + 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, + 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, + + 0.0f, 0.0f, 0.0f, 0.2f, 1.0f, 0.2f, + 0.0f, 0.0f, 1.0f, 0.2f, 1.0f, 0.0f, + + TRANSFORM_TRI_2D( 0.15f,0.05f,0.4f, 0.0f, 1.0f, 1.0f, 2.0f, 1.0f, 0.0f ), + TRANSFORM_TRI_2D( 0.15f,0.80f,0.4f, 0.0f, 0.0f, 0.0f, 2.0f, 1.0f, 1.0f ) + }; + + float *circle_mesh = combined_mesh + 6*6; + int const res = 32; + for( int i=0; i < res; i ++ ){ + v2f v0 = { sinf( ((float)i/(float)res)*VG_TAUf ), + cosf( ((float)i/(float)res)*VG_TAUf ) }; + v2f v1 = { sinf( ((float)(i+1)/(float)res)*VG_TAUf ), + cosf( ((float)(i+1)/(float)res)*VG_TAUf ) }; + + circle_mesh[ i*6+0 ] = 0.0f; + circle_mesh[ i*6+1 ] = 0.0f; + + v2_copy( v0, circle_mesh + 32*6 + i*12 ); + v2_muls( v0, 0.8f, circle_mesh + 32*6 + i*12+2 ); + v2_copy( v1, circle_mesh + 32*6 + i*12+4 ); + + v2_copy( v1, circle_mesh + 32*6 + i*12+6 ); + v2_muls( v1, 0.8f, circle_mesh + 32*6 + i*12+8 ); + v2_muls( v0, 0.8f, circle_mesh + 32*6 + i*12+10 ); + + v2_copy( v0, circle_mesh + i*6+4 ); + v2_copy( v1, circle_mesh + i*6+2 ); + v2_copy( v0, circle_mesh+i*6+4 ); + v2_copy( v1, circle_mesh+i*6+2 ); + } + init_mesh( &world.shapes, combined_mesh, vg_list_size( combined_mesh ) ); + + // Create wire mesh + int const num_segments = 64; + struct mesh_wire *mw = &world.wire; + + v2f wire_points[ num_segments * 2 ]; + u16 wire_indices[ 6*(num_segments-1) ]; + + for( int i = 0; i < num_segments; i ++ ){ + float l = (float)i / (float)(num_segments-1); + + v2_copy( (v2f){ l, -0.5f }, wire_points[i*2+0] ); + v2_copy( (v2f){ l, 0.5f }, wire_points[i*2+1] ); + + if( i < num_segments-1 ){ + wire_indices[ i*6+0 ] = i*2 + 0; + wire_indices[ i*6+1 ] = i*2 + 1; + wire_indices[ i*6+2 ] = i*2 + 3; + wire_indices[ i*6+3 ] = i*2 + 0; + wire_indices[ i*6+4 ] = i*2 + 3; + wire_indices[ i*6+5 ] = i*2 + 2; + } + } + + glGenVertexArrays( 1, &mw->vao ); + glGenBuffers( 1, &mw->vbo ); + glGenBuffers( 1, &mw->ebo ); + glBindVertexArray( mw->vao ); + + glBindBuffer( GL_ARRAY_BUFFER, mw->vbo ); + + glBufferData( GL_ARRAY_BUFFER, sizeof( wire_points ), + wire_points, GL_STATIC_DRAW ); + glBindVertexArray( mw->vao ); + + glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, mw->ebo ); + glBufferData( GL_ELEMENT_ARRAY_BUFFER, sizeof( wire_indices ), + wire_indices, GL_STATIC_DRAW ); + + // XY + glVertexAttribPointer( 0, 2, GL_FLOAT, GL_FALSE, 2*sizeof(float), (void*)0 ); + glEnableVertexAttribArray( 0 ); + + VG_CHECK_GL(); + mw->em = vg_list_size( wire_indices ); + + // Create info data texture + glGenTextures( 1, &world.background_data ); + glBindTexture( GL_TEXTURE_2D, world.background_data ); + glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, 64, 64, 0, GL_RGBA, + GL_UNSIGNED_BYTE, NULL ); + vg_tex2d_nearest(); + + // Create random smaples texture + u8 *data = malloc(512*512*2); + for( int i = 0; i < 512*512*2; i ++ ) + data[ i ] = rand()/(RAND_MAX/255); + + glGenTextures( 1, &world.random_samples ); + glBindTexture( GL_TEXTURE_2D, world.random_samples ); + glTexImage2D( GL_TEXTURE_2D, 0, GL_RG, 512, 512, 0, GL_RG, + GL_UNSIGNED_BYTE, data ); + vg_tex2d_nearest(); + vg_tex2d_repeat(); + free( data ); + + resource_load_main(); + + // Init world text + //ui_init_context( &world.st.world_text, 15000 ); + + // Restore gamestate + career_local_data_init(); + career_load(); + + /* Create framebuffers */ + glGenFramebuffers( 1, &world.st.framebuffer ); + glBindFramebuffer( GL_FRAMEBUFFER, world.st.framebuffer ); + + glGenTextures( 1, &world.st.colourbuffer ); + glBindTexture( GL_TEXTURE_2D, world.st.colourbuffer ); + glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, vg_window_x, vg_window_y, + 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); + + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, + world.st.colourbuffer, 0); + + /* Bloom framebuffer (quater res) */ + glGenFramebuffers( 2, world.st.bloomframebuffer ); + glGenTextures( 2, world.st.bloomcolourbuffer ); + + for( int i=0; i<2; i++ ){ + glBindFramebuffer( GL_FRAMEBUFFER, world.st.bloomframebuffer[i] ); + + glBindTexture( GL_TEXTURE_2D, world.st.bloomcolourbuffer[i] ); + glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, + vg_window_x/EFFECT_BUFFER_RATIO, vg_window_y/EFFECT_BUFFER_RATIO, + 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); + vg_tex2d_clamp(); + + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, + GL_TEXTURE_2D, world.st.bloomcolourbuffer[i], 0); + } +}