12628ca4bfd991c74da464f514dfbfedeeefe5f8
1 // Copyright (C) 2021 Harry Godden (hgn) - All Rights Reserved
6 SHADER_DEFINE( colour_shader
,
9 "layout (location=0) in vec3 a_co;"
15 " vec4 vert_pos = uPv * uMdl * vec4( a_co, 1.0 );"
16 " gl_Position = vert_pos;"
21 "uniform vec4 uColour;"
25 " FragColor = uColour;"
28 UNIFORMS({ "uPv", "uMdl", "uColour" })
35 int main( int argc
, char *argv
[] )
37 vg_init( argc
, argv
, "FishLadder" );
40 #define CELL_FLAG_INPUT 0x1
41 #define CELL_FLAG_OUTPUT 0x2
42 #define CELL_FLAG_IO (CELL_FLAG_INPUT|CELL_FLAG_OUTPUT)
43 #define CELL_FLAG_WALL 0x4
44 #define CELL_FLAG_HOVER 0x8
45 #define CELL_FLAG_ITER 0x10
46 #define CELL_FLAG_CANAL 0x20
62 struct cell
*selected
;
83 static void map_free(void)
85 for( int i
= 0; i
< arrlen( map
.io
); i
++ )
87 arrfree( map
.cells
[ map
.io
[i
] ].conditions
);
98 static struct cell
*map_tile_at( int pos
[2] )
100 if( pos
[0] >= 0 && pos
[0] < map
.x
&& pos
[1] >= 0 && pos
[1] < map
.y
)
101 return map
.cells
+ pos
[1]*map
.x
+ pos
[0];
105 static int map_load( const char *str
)
114 if( str
[map
.x
] == ';' )
116 else if( !str
[map
.x
] )
118 vg_error( "Unexpected EOF when parsing level!\n" );
123 struct cell
*row
= arraddnptr( map
.cells
, map
.x
);
125 int reg_start
= 0, reg_end
= 0;
141 if( reg_start
< reg_end
)
143 if( *c
>= 'a' && *c
<= 'z' )
145 arrpush( map
.cells
[ map
.io
[ reg_start
] ].conditions
, *c
);
149 if( *c
== ',' || *c
== '\n' )
158 vg_error( "Unkown attrib '%c' (row: %u)\n", *c
, map
.y
);
165 vg_error( "Over-assigned values (row: %u)\n", map
.y
);
173 if( reg_start
!= reg_end
)
175 vg_error( "Not enough values assigned (row: %u, %u of %u)\n", map
.y
, reg_start
, reg_end
);
181 vg_error( "Map row underflow (row: %u, %u<%u)\n", map
.y
, cx
, map
.x
);
185 row
= arraddnptr( map
.cells
, map
.x
);
188 reg_end
= reg_start
= arrlen( map
.io
);
194 vg_error( "Map row overflow (row: %u, %u>%u)\n", map
.y
, cx
, map
.x
);
198 row
[ cx
].conditions
= NULL
;
200 // Parse the various cell types
201 if( *c
== '+' || *c
== '-' )
203 arrpush( map
.io
, cx
+ map
.y
*map
.x
);
204 row
[ cx
++ ].flags
= *c
== '+'? CELL_FLAG_INPUT
: CELL_FLAG_OUTPUT
;
209 row
[ cx
++ ].flags
= CELL_FLAG_WALL
;
213 row
[ cx
++ ].flags
= 0x00;
220 // Origin top left corner
221 map
.origin
[0] = -((float)map
.x
) * 0.5f
;
222 map
.origin
[2] = -((float)map
.y
) * 0.5f
;
224 vg_success( "Map loaded! (%u:%u)\n", map
.x
, map
.y
);
231 float ratio
= (float)vg_window_y
/ (float)vg_window_x
;
232 float const size
= 7.5f
;
233 glm_ortho( -size
, size
, -size
*ratio
, size
*ratio
, 0.1f
, 100.f
, m_projection
);
235 glm_mat4_identity( m_view
);
236 glm_translate_z( m_view
, -10.f
);
237 glm_rotate_x( m_view
, 1.0f
, m_view
);
239 glm_mat4_mul( m_projection
, m_view
, vg_pv
);
246 vec4 vp
= { 0.f
, 0.f
, vg_window_x
, vg_window_y
};
247 glm_mat4_inv( vg_pv
, pv_inverse
);
248 glm_unprojecti( (vec3
){ vg_mouse_x
, vg_window_y
-vg_mouse_y
, -1.f
}, pv_inverse
, vp
, ray_dir
);
249 glm_unprojecti( (vec3
){ vg_mouse_x
, vg_window_y
-vg_mouse_y
, 0.f
}, pv_inverse
, vp
, ray_origin
);
250 glm_vec3_sub( ray_dir
, ray_origin
, ray_dir
);
252 // Get floor tile intersection
253 float ray_t
= -ray_origin
[1] / ray_dir
[1];
256 glm_vec3_copy( ray_origin
, tile_pos
);
257 glm_vec3_muladds( ray_dir
, ray_t
, tile_pos
);
258 glm_vec3_sub( tile_pos
, map
.origin
, tile_pos
);
260 int tile_x
= floorf( tile_pos
[0] );
261 int tile_y
= floorf( tile_pos
[2] );
263 map
.selected
= map_tile_at( (int [2]){tile_x
, tile_y
} );
265 vg_line2( (vec3
){0.f
,0.f
,0.f
}, (vec3
){0.f
,3.f
,0.f
}, 0xff0000ff, 0xff00ff00 );
273 glViewport( 0,0, vg_window_x
, vg_window_y
);
275 glEnable( GL_DEPTH_TEST
);
276 glClearColor( 0.94f
, 0.94f
, 0.94f
, 1.0f
);
277 glClear( GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
);
279 glBindVertexArray( tile_vao
);
281 SHADER_USE( colour_shader
);
282 glUniformMatrix4fv( SHADER_UNIFORM( colour_shader
, "uPv" ), 1, GL_FALSE
, (float *)vg_pv
);
284 for( int y
= 0; y
< map
.y
; y
++ )
286 for( int x
= 0; x
< map
.x
; x
++ )
288 glm_mat4_identity( m_mdl
);
289 glm_translate( m_mdl
,
291 map
.origin
[0] + (float)x
+ 0.5f
,
293 map
.origin
[2] + (float)y
+ 0.5f
296 glUniformMatrix4fv( SHADER_UNIFORM( colour_shader
, "uMdl" ), 1, GL_FALSE
, (float *)m_mdl
);
298 struct cell
*cell
= &map
.cells
[ y
*map
.x
+x
];
300 if( map
.selected
!= cell
)
302 if( cell
->flags
& CELL_FLAG_INPUT
)
303 glUniform4f( SHADER_UNIFORM( colour_shader
, "uColour" ), 0.9f
, 0.5f
, 0.5f
, 1.0f
);
304 else if( cell
->flags
& CELL_FLAG_OUTPUT
)
305 glUniform4f( SHADER_UNIFORM( colour_shader
, "uColour" ), 0.5f
, 0.9f
, 0.5f
, 1.0f
);
306 else if( cell
->flags
& CELL_FLAG_WALL
)
307 glUniform4f( SHADER_UNIFORM( colour_shader
, "uColour" ), 0.1f
, 0.1f
, 0.1f
, 1.0f
);
309 glUniform4f( SHADER_UNIFORM( colour_shader
, "uColour" ), 0.7f
, 0.7f
, 0.7f
, 1.0f
);
313 float flash
= sinf( vg_time
*2.5f
) * 0.25f
+ 0.75f
;
314 glUniform4f( SHADER_UNIFORM( colour_shader
, "uColour" ), flash
,flash
,flash
, 1.0f
);
317 glDrawArrays( GL_TRIANGLES
, 0, 6 );
324 SHADER_INIT( colour_shader
);
326 glGenVertexArrays( 1, &tile_vao
);
327 glGenBuffers( 1, &tile_vbo
);
339 glBindVertexArray( tile_vao
);
340 glBindBuffer( GL_ARRAY_BUFFER
, tile_vbo
);
349 glVertexAttribPointer( 0, 3, GL_FLOAT
, GL_FALSE
, 3 * sizeof(float), (void*)0 );
350 glEnableVertexAttribArray( 0 );