//#define VG_STEAM
#include "vg/vg.h"
+#define CELL_SHEET_X 256
+#define CELL_SHEET_Y 256
+
SHADER_DEFINE( colour_shader,
// VERTEX
UNIFORMS({ "uPv", "uMdl", "uColour" })
)
-/*
SHADER_DEFINE( tilemap_shader,
// VERTEX
- "layout (location=0) in vec2 a_co;"
+ "layout (location=0) in vec2 a_co;" // XY
+ "layout (location=1) in vec2 a_offset;" // XY offset
+ "layout (location=2) in vec4 a_data;" // atlas-uv, amt, other
"uniform mat4 uPv;"
- "uniform vec4 uTextureInfo;" // Cell dx,dy 1.0/mx, 1.0/my
- "uniform "
+ "uniform vec2 uOrigin;"
""
- "uniform vec2 uPosition;"
- "uniform int uCellIndex;"
- ""
- "out vec2 s_uv;"
+ "out vec2 aCoords;"
""
"void main()"
"{"
- " gl_Position = uPv * vec4( uPosition.x + a_co.x, 0.0, uPosition.y + a_co.y, 0.0 );"
- " s_uv = vec2( mod( uCellIndex,"
+ "vec2 world_coord = a_co+a_offset+uOrigin;"
+ "gl_Position = uPv * vec4( world_coord.x, 0.0, world_coord.y, 1.0 );"
+ "aCoords = (a_co*0.98+0.01 + a_data.xy) * 0.125;"
+ "}",
+
+ // FRAGMENT
+ "uniform sampler2D uTexTiles;"
+
+ "in vec2 aCoords;"
+ "out vec4 FragColor;"
+
+ "void main()"
+ "{"
+ "vec4 glyph = texture( uTexTiles, aCoords );"
+ "FragColor = vec4( glyph.xyz, 1.0 );"
"}"
-*/
+ ,
+ UNIFORMS({ "uPv", "uTexTiles", "uOrigin" })
+)
mat4 m_projection;
mat4 m_view;
GLuint tile_texture;
GLuint flow_texture;
+
+ GLuint tiles_vao;
+ GLuint tiles_vbo;
}
map;
return tile;
}
+static void map_update_visual(void)
+{
+ u8 celldata[ 4096 ];
+
+ for( int i = 0; i < map.x*map.y; i ++ )
+ {
+ celldata[i*4+0] = i & 0x7;
+ celldata[i*4+1] = (i & ~0x7) >> 3;
+ }
+
+ glBindBuffer( GL_ARRAY_BUFFER, map.tiles_vbo );
+ glBufferSubData( GL_ARRAY_BUFFER, 16*sizeof(float) + 1024*2*sizeof(float), map.x*map.y*4, celldata );
+}
+
static int map_load( const char *str )
{
map_free();
map.origin[0] = -((float)map.x) * 0.5f;
map.origin[2] = -((float)map.y) * 0.5f;
+ float *offset_array = (float *)malloc( map.x*map.y*2*sizeof(float) );
+
+ for( int y = 0; y < map.y; y ++ )
+ {
+ for( int x = 0; x < map.x; x ++ )
+ {
+ float *coord = offset_array + (y*map.x+x)*2;
+ coord[0] = x;
+ coord[1] = y;
+ }
+ }
+
+ glBindBuffer( GL_ARRAY_BUFFER, map.tiles_vbo );
+ glBufferSubData( GL_ARRAY_BUFFER, 16*sizeof(float), map.x*map.y*2*sizeof(float), offset_array );
+
+ free( offset_array );
vg_success( "Map loaded! (%u:%u)\n", map.x, map.y );
return 1;
}
// Update camera
float ratio = (float)vg_window_y / (float)vg_window_x;
float const size = 7.5f;
- glm_ortho( -size, size, -size*ratio, size*ratio, 0.1f, 100.f, m_projection );
+ glm_ortho( -size, size, -size*ratio, size*ratio, 0.01f, 150.f, m_projection );
glm_mat4_identity( m_view );
glm_translate_z( m_view, -10.f );
- glm_rotate_x( m_view, 1.0f, m_view );
+ glm_rotate_x( m_view, 1.5708f, m_view );
glm_mat4_mul( m_projection, m_view, vg_pv );
{
glViewport( 0,0, vg_window_x, vg_window_y );
- glEnable( GL_DEPTH_TEST );
+ //glEnable( GL_DEPTH_TEST );
glClearColor( 0.94f, 0.94f, 0.94f, 1.0f );
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
+ /*
glBindVertexArray( tile_vao );
SHADER_USE( colour_shader );
glm_mat4_identity( m_mdl );
glm_translate( m_mdl,
(vec3){
- map.origin[0] + (float)x + 0.5f,
+ map.origin[0] + (float)x,
0.f,
- map.origin[2] + (float)y + 0.5f
+ map.origin[2] + (float)y
}
);
glUniformMatrix4fv( SHADER_UNIFORM( colour_shader, "uMdl" ), 1, GL_FALSE, (float *)m_mdl );
glDrawArrays( GL_TRIANGLES, 0, 6 );
}
}
+ */
+
+ glBindVertexArray( map.tiles_vao );
+
+ map_update_visual();
+
+ SHADER_USE( tilemap_shader );
+ glUniformMatrix4fv( SHADER_UNIFORM( tilemap_shader, "uPv" ), 1, GL_FALSE, (float *)vg_pv );
+
+ glUniform1i( SHADER_UNIFORM( tilemap_shader, "uTexTiles" ), 0 );
+ glActiveTexture( GL_TEXTURE0 );
+ glBindTexture( GL_TEXTURE_2D, map.tile_texture );
+
+ glUniform2f( SHADER_UNIFORM( tilemap_shader, "uOrigin" ), map.origin[0], map.origin[2] );
+
+ glDrawArraysInstanced( GL_TRIANGLES, 0, 6, map.x*map.y );
}
-void vg_start(void)
+void vg_register(void)
{
SHADER_INIT( colour_shader );
-
+ SHADER_INIT( tilemap_shader );
+}
+
+void vg_start(void)
+{
glGenVertexArrays( 1, &tile_vao );
glGenBuffers( 1, &tile_vbo );
float quad_mesh[] =
{
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, 1.0f, 1.0f, 1.0f, 0.0f,
+
+ // Padding
+ 0.0f, 0.0f, 0.0f, 0.0f
};
glBindVertexArray( tile_vao );
VG_CHECK_GL();
+ // Create map buffers
+ glGenVertexArrays( 1, &map.tiles_vao );
+ glGenBuffers( 1, &map.tiles_vbo );
+
+ glBindVertexArray( map.tiles_vao );
+ glBindBuffer( GL_ARRAY_BUFFER, map.tiles_vbo );
+ glBufferData( GL_ARRAY_BUFFER,
+ sizeof( quad_mesh ) +
+ sizeof( float )*2 * 1024 +
+ sizeof( u8 )*4 * 1024,
+ NULL,
+ GL_DYNAMIC_DRAW
+ );
+
+ glBufferSubData( GL_ARRAY_BUFFER, 0, sizeof( quad_mesh ), quad_mesh );
+
+ // Base quad
+ glVertexAttribPointer( 0, 2, GL_FLOAT, GL_FALSE, 2*sizeof(float), (void*)0 );
+ glEnableVertexAttribArray( 0 );
+
+ // Offset, data arrays (instancing)
+ glVertexAttribPointer( 1, 2, GL_FLOAT, GL_FALSE, 2*sizeof(float), (void*)(sizeof(quad_mesh)) );
+ glEnableVertexAttribArray( 1 );
+ glVertexAttribDivisor( 1, 1 );
+
+ glVertexAttribPointer( 2, 4, GL_UNSIGNED_BYTE, GL_FALSE, 4, (void*)(sizeof(quad_mesh)+sizeof(float)*2*1024) );
+ glEnableVertexAttribArray( 2 );
+ glVertexAttribDivisor( 2, 1 );
+
map.tile_texture = vg_tex2d_rgba( "textures/rivertiles_flowm.tga" );
- map.flow_texture = vg_tex2d_rgba( "textures/rivertiles_ripple.tga" );
+ vg_tex2d_nearest();
+ vg_tex2d_repeat();
+
+ map.flow_texture = vg_tex2d_rgba( "textures/rivertiles_ripple.tga" );
+
map_load
(
{
map_free();
+ glDeleteVertexArrays( 1, &tile_vao );
+ glDeleteVertexArrays( 1, &map.tiles_vao );
+
+ glDeleteBuffers( 1, &tile_vbo );
+ glDeleteBuffers( 1, &map.tiles_vbo );
+
glDeleteTextures( 1, &map.tile_texture );
glDeleteTextures( 1, &map.flow_texture );
}