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" })
36 int main( int argc
, char *argv
[] )
38 vg_init( argc
, argv
, "FishLadder" );
41 #define CELL_FLAG_INPUT 0x1
42 #define CELL_FLAG_OUTPUT 0x2
43 #define CELL_FLAG_IO (CELL_FLAG_INPUT|CELL_FLAG_OUTPUT)
44 #define CELL_FLAG_WALL 0x4
61 static void map_free(void)
63 for( int i
= 0; i
< arrlen( map
.io
); i
++ )
65 arrfree( map
.cells
[ map
.io
[i
] ].conditions
);
76 static int map_load( const char *str
)
85 if( str
[map
.x
] == ';' )
87 else if( !str
[map
.x
] )
89 vg_error( "Unexpected EOF when parsing level!\n" );
94 struct cell
*row
= arraddnptr( map
.cells
, map
.x
);
96 int reg_start
= 0, reg_end
= 0;
112 if( reg_start
< reg_end
)
114 if( *c
>= 'a' && *c
<= 'z' )
116 arrpush( map
.cells
[ map
.io
[ reg_start
] ].conditions
, *c
);
120 if( *c
== ',' || *c
== '\n' )
129 vg_error( "Unkown attrib '%c' (row: %u)\n", *c
, map
.y
);
136 vg_error( "Over-assigned values (row: %u)\n", map
.y
);
144 if( reg_start
!= reg_end
)
146 vg_error( "Not enough values assigned (row: %u, %u of %u)\n", map
.y
, reg_start
, reg_end
);
152 vg_error( "Map row underflow (row: %u, %u<%u)\n", map
.y
, cx
, map
.x
);
156 row
= arraddnptr( map
.cells
, map
.x
);
159 reg_end
= reg_start
= arrlen( map
.io
);
165 vg_error( "Map row overflow (row: %u, %u>%u)\n", map
.y
, cx
, map
.x
);
169 row
[ cx
].conditions
= NULL
;
171 // Parse the various cell types
172 if( *c
== '+' || *c
== '-' )
174 arrpush( map
.io
, cx
+ map
.y
*map
.x
);
175 row
[ cx
++ ].flags
= *c
== '+'? CELL_FLAG_INPUT
: CELL_FLAG_OUTPUT
;
180 row
[ cx
++ ].flags
= CELL_FLAG_WALL
;
184 row
[ cx
++ ].flags
= 0x00;
191 vg_success( "Map loaded! (%u:%u)\n", map
.x
, map
.y
);
198 float ratio
= (float)vg_window_y
/ (float)vg_window_x
;
199 float const size
= 7.5f
;
200 glm_ortho( -size
, size
, -size
*ratio
, size
*ratio
, 0.1f
, 100.f
, m_projection
);
202 glm_mat4_identity( m_view
);
203 glm_translate_z( m_view
, -10.f
);
204 glm_rotate_x( m_view
, -1.0f
, m_view
);
206 glm_mat4_mul( m_projection
, m_view
, m_pv
);
213 vec4 vp
= { 0.f
, 0.f
, vg_window_x
, vg_window_y
};
214 glm_mat4_inv( m_pv
, pv_inverse
);
215 glm_unprojecti( (vec3
){ vg_mouse_x
, vg_window_y
-vg_mouse_y
, -1.f
}, pv_inverse
, vp
, ray_dir
);
216 glm_unprojecti( (vec3
){ vg_mouse_x
, vg_window_y
-vg_mouse_y
, 0.f
}, pv_inverse
, vp
, ray_origin
);
217 glm_vec3_sub( ray_dir
, ray_origin
, ray_dir
);
219 // Get floor tile intersection
220 float ray_t
= -ray_origin
[1] / ray_dir
[1];
223 glm_vec3_copy( ray_origin
, tile_pos
);
224 glm_vec3_muladds( ray_dir
, ray_t
, tile_pos
);
226 tile_pos
[0] = floorf( tile_pos
[0] + 0.5f
);
227 tile_pos
[2] = floorf( tile_pos
[2] + 0.5f
);
229 glm_mat4_identity( m_mdl
);
230 glm_translate( m_mdl
, tile_pos
);
238 glViewport( 0,0, vg_window_x
, vg_window_y
);
240 glEnable( GL_DEPTH_TEST
);
241 glClearColor( 0.94f
, 0.94f
, 0.94f
, 1.0f
);
242 glClear( GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
);
244 SHADER_USE( colour_shader
);
245 glUniformMatrix4fv( SHADER_UNIFORM( colour_shader
, "uPv" ), 1, GL_FALSE
, (float *)m_pv
);
246 glUniform4f( SHADER_UNIFORM( colour_shader
, "uColour" ), 0.5f
, 0.5f
, 0.5f
, 1.0f
);
248 glUniformMatrix4fv( SHADER_UNIFORM( colour_shader
, "uMdl" ), 1, GL_FALSE
, (float *)m_mdl
);
250 glBindVertexArray( tile_vao
);
251 glDrawArrays( GL_TRIANGLES
, 0, 6 );
256 SHADER_INIT( colour_shader
);
258 glGenVertexArrays( 1, &tile_vao
);
259 glGenBuffers( 1, &tile_vbo
);
271 glBindVertexArray( tile_vao
);
272 glBindBuffer( GL_ARRAY_BUFFER
, tile_vbo
);
281 glVertexAttribPointer( 0, 3, GL_FLOAT
, GL_FALSE
, 3 * sizeof(float), (void*)0 );
282 glEnableVertexAttribArray( 0 );