main.c 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. #include <gs.h>
  2. /*
  3. Simple Texture -
  4. The purpose of this example is to demonstrate how to load textures from file and construct a GPU texture resource to use
  5. for your application.
  6. There is also code to demonstrate how to construct a camera and manipulate it as well. Look for "Camera Update" section,
  7. in the'app_update' function.
  8. */
  9. // Globals
  10. _global gs_resource( gs_vertex_buffer ) g_vbo = {0};
  11. _global gs_resource( gs_index_buffer ) g_ibo = {0};
  12. _global gs_resource( gs_command_buffer ) g_cb = {0};
  13. _global gs_resource( gs_shader ) g_shader = {0};
  14. _global gs_resource( gs_uniform ) u_model = {0};
  15. _global gs_resource( gs_uniform ) u_view = {0};
  16. _global gs_resource( gs_uniform ) u_proj = {0};
  17. _global gs_resource( gs_uniform ) u_tex = {0};
  18. _global gs_resource( gs_texture ) g_tex = {0};
  19. _global gs_camera g_camera = {0};
  20. const char* v_src = "\n"
  21. "#version 330 core\n"
  22. "layout(location = 0) in vec2 a_pos;\n"
  23. "layout(location = 1) in vec2 a_uv;\n"
  24. "uniform mat4 u_model;\n"
  25. "uniform mat4 u_view;\n"
  26. "uniform mat4 u_proj;\n"
  27. "out vec2 uv;\n"
  28. "void main()\n"
  29. "{\n"
  30. " gl_Position = u_proj * u_view * u_model * vec4(a_pos, 0.0, 1.0);\n"
  31. " uv = a_uv;\n"
  32. "}";
  33. const char* f_src = "\n"
  34. "#version 330 core\n"
  35. "uniform sampler2D u_tex;"
  36. "in vec2 uv;\n"
  37. "out vec4 frag_color;\n"
  38. "void main()\n"
  39. "{\n"
  40. " frag_color = texture(u_tex, uv);\n"
  41. "}";
  42. // Forward Decls.
  43. gs_result app_init(); // Use to init your application
  44. gs_result app_update(); // Use to update your application
  45. gs_result app_shutdown(); // Use to shutdown your appliaction
  46. int main( int argc, char** argv )
  47. {
  48. gs_application_desc app = {0};
  49. app.window_title = "Simple Texture";
  50. app.window_width = 800;
  51. app.window_height = 600;
  52. app.init = &app_init;
  53. app.update = &app_update;
  54. app.shutdown = &app_shutdown;
  55. // Construct internal instance of our engine
  56. gs_engine* engine = gs_engine_construct( app );
  57. // Run the internal engine loop until completion
  58. gs_result res = engine->run();
  59. // Check result of engine after exiting loop
  60. if ( res != gs_result_success )
  61. {
  62. gs_println( "Error: Engine did not successfully finish running." );
  63. return -1;
  64. }
  65. gs_println( "Gunslinger exited successfully." );
  66. return 0;
  67. }
  68. // Here, we'll initialize all of our application data, which in this case is our graphics resources
  69. gs_result app_init()
  70. {
  71. // Cache instance of graphics/platform apis from engine
  72. gs_graphics_i* gfx = gs_engine_instance()->ctx.graphics;
  73. gs_platform_i* platform = gs_engine_instance()->ctx.platform;
  74. // Construct command buffer ( the command buffer is used to allow for immediate drawing at any point in our program )
  75. g_cb = gfx->construct_command_buffer();
  76. // Construct shader from our source above
  77. g_shader = gfx->construct_shader( v_src, f_src );
  78. // Construct uniform for shader
  79. u_view = gfx->construct_uniform( g_shader, "u_view", gs_uniform_type_mat4 );
  80. u_model = gfx->construct_uniform( g_shader, "u_model", gs_uniform_type_mat4 );
  81. u_proj = gfx->construct_uniform( g_shader, "u_proj", gs_uniform_type_mat4 );
  82. u_tex = gfx->construct_uniform( g_shader, "u_tex", gs_uniform_type_sampler2d );
  83. // Vertex data layout for our mesh
  84. gs_vertex_attribute_type layout[] = {
  85. gs_vertex_attribute_float2, // Position
  86. gs_vertex_attribute_float2 // UV
  87. };
  88. // Count of our vertex attribute array
  89. u32 layout_count = sizeof( layout ) / sizeof( gs_vertex_attribute_type );
  90. // Vertex data for quad
  91. f32 v_data[] =
  92. {
  93. // Positions UVs
  94. -0.5f, -0.5f, 0.0f, 0.0f, // Top Left
  95. 0.5f, -0.5f, 1.0f, 0.0f, // Top Right
  96. -0.5f, 0.5f, 0.0f, 1.0f, // Bottom Left
  97. 0.5f, 0.5f, 1.0f, 1.0f // Bottom Right
  98. };
  99. u32 i_data[] = {
  100. 0, 3, 2, // First Triangle
  101. 0, 1, 3 // Second Triangle
  102. };
  103. // Construct vertex and index buffers
  104. g_vbo = gfx->construct_vertex_buffer( layout, layout_count, v_data, sizeof(v_data) );
  105. g_ibo = gfx->construct_index_buffer( i_data, sizeof(i_data) );
  106. // This is a descriptor for our texture. It includes various metrics, such as the width, height, texture format,
  107. // and holds the actual uncompressed texture data for the texture. After using it for loading a raw texture
  108. // from file, it's the responsibility of the user to free the data.
  109. gs_texture_parameter_desc desc = gs_texture_parameter_desc_default();
  110. // Get appropriate file path for our texture (depending on where the app is running from)
  111. const char* tfp = platform->file_exists("./assets/gs.png") ? "./assets/gs.png" : "./../assets/gs.png";
  112. gs_assert(platform->file_exists(tfp)); // We'll assert if the file doesn't exist
  113. // Load texture from file and pass into description format
  114. desc.data = gfx->load_texture_data_from_file( tfp, true, desc.texture_format, (s32*)&desc.width,
  115. (s32*)&desc.height, (s32*)&desc.num_comps );
  116. // Assert that our texture data is valid (it should be)
  117. gs_assert(desc.data != NULL);
  118. // Now we can pass this descriptor to our graphics api to construct our GPU texture
  119. g_tex = gfx->construct_texture( desc );
  120. // We can now safely release the memory for our descriptor
  121. gs_free( desc.data );
  122. desc.data = NULL;
  123. // Construct camera parameters
  124. g_camera.transform = gs_vqs_default();
  125. g_camera.transform.position = (gs_vec3){0.f, 0.f, -1.f};
  126. g_camera.fov = 60.f;
  127. g_camera.near_plane = 0.1f;
  128. g_camera.far_plane = 1000.f;
  129. g_camera.ortho_scale = 2.f;
  130. g_camera.proj_type = gs_projection_type_orthographic;
  131. return gs_result_success;
  132. }
  133. gs_result app_update()
  134. {
  135. // Grab global instance of engine
  136. gs_engine* engine = gs_engine_instance();
  137. // Platform api
  138. gs_platform_i* platform = engine->ctx.platform;
  139. // If we press the escape key, exit the application
  140. if ( platform->key_pressed( gs_keycode_esc ) )
  141. {
  142. return gs_result_success;
  143. }
  144. const f32 dt = platform->time.delta;
  145. const f32 t = platform->elapsed_time();
  146. /*=================
  147. // Camera controls
  148. ==================*/
  149. if ( platform->key_down( gs_keycode_q ) ) {
  150. g_camera.ortho_scale += 0.1f;
  151. }
  152. if ( platform->key_down( gs_keycode_e ) ) {
  153. g_camera.ortho_scale -= 0.1f;
  154. }
  155. if (platform->key_down(gs_keycode_a)) {
  156. g_camera.transform.position.x -= 0.1f;
  157. }
  158. if (platform->key_down(gs_keycode_d)) {
  159. g_camera.transform.position.x += 0.1f;
  160. }
  161. if (platform->key_down(gs_keycode_w)) {
  162. g_camera.transform.position.y += 0.1f;
  163. }
  164. if (platform->key_down(gs_keycode_s)) {
  165. g_camera.transform.position.y -= 0.1f;
  166. }
  167. /*===============
  168. // Render scene
  169. ================*/
  170. // Graphics api instance
  171. gs_graphics_i* gfx = engine->ctx.graphics;
  172. // Main window size
  173. gs_vec2 ws = platform->window_size( platform->main_window() );
  174. gs_vec2 fbs = platform->frame_buffer_size( platform->main_window() );
  175. // Set clear color and clear screen
  176. f32 clear_color[4] = { 0.2f, 0.2f, 0.2f, 1.f };
  177. gfx->set_view_clear( g_cb, clear_color );
  178. gfx->set_view_port( g_cb, fbs.x, fbs.y );
  179. gfx->set_depth_enabled( g_cb, false );
  180. gfx->set_blend_mode( g_cb, gs_blend_mode_src_alpha, gs_blend_mode_one_minus_src_alpha );
  181. // Bind shader
  182. gfx->bind_shader( g_cb, g_shader );
  183. // Create model/view/projection matrices from camera
  184. gs_mat4 view_mtx = gs_camera_get_view( &g_camera );
  185. gs_mat4 proj_mtx = gs_camera_get_projection( &g_camera, ws.x, ws.y );
  186. gs_mat4 model_mtx = gs_mat4_scale((gs_vec3){1.f, 1.f, 1.f});
  187. // Bind matrix uniforms
  188. gfx->bind_uniform( g_cb, u_proj, &proj_mtx );
  189. gfx->bind_uniform( g_cb, u_view, &view_mtx );
  190. gfx->bind_uniform( g_cb, u_model, &model_mtx );
  191. // Bind texture slot
  192. gfx->bind_texture( g_cb, u_tex, g_tex, 0 );
  193. // Bind vertex buffer
  194. gfx->bind_vertex_buffer( g_cb, g_vbo );
  195. // Bind index buffer
  196. gfx->bind_index_buffer( g_cb, g_ibo );
  197. // Draw
  198. gfx->draw_indexed( g_cb, 6, 0 );
  199. // Submit command buffer for rendering
  200. gfx->submit_command_buffer( g_cb );
  201. return gs_result_in_progress;
  202. }
  203. gs_result app_shutdown()
  204. {
  205. gs_println( "Goodbye, Gunslinger." );
  206. return gs_result_success;
  207. }