/src/_4_advanced_opengl/_10_1_instancing_quads.rs

https://github.com/bwasty/learn-opengl-rs · Rust · 147 lines · 99 code · 22 blank · 26 comment · 3 complexity · b5946d66a611fd9c1b1c775228c5175c MD5 · raw file

  1. #![allow(non_upper_case_globals)]
  2. #![allow(non_snake_case)]
  3. use std::ptr;
  4. use std::mem;
  5. use std::os::raw::c_void;
  6. extern crate glfw;
  7. use self::glfw::Context;
  8. extern crate gl;
  9. use self::gl::types::*;
  10. use cgmath::{Vector2};
  11. extern crate num;
  12. use self::num::range_step;
  13. use shader::Shader;
  14. // settings
  15. const SCR_WIDTH: u32 = 1280;
  16. const SCR_HEIGHT: u32 = 720;
  17. pub fn main_4_10_1() {
  18. // glfw: initialize and configure
  19. // ------------------------------
  20. let mut glfw = glfw::init(glfw::FAIL_ON_ERRORS).unwrap();
  21. glfw.window_hint(glfw::WindowHint::ContextVersion(3, 3));
  22. glfw.window_hint(glfw::WindowHint::OpenGlProfile(glfw::OpenGlProfileHint::Core));
  23. #[cfg(target_os = "macos")]
  24. glfw.window_hint(glfw::WindowHint::OpenGlForwardCompat(true));
  25. // glfw window creation
  26. // --------------------
  27. let (mut window, _events) = glfw.create_window(SCR_WIDTH, SCR_HEIGHT, "LearnOpenGL", glfw::WindowMode::Windowed)
  28. .expect("Failed to create GLFW window");
  29. window.make_current();
  30. window.set_framebuffer_size_polling(true);
  31. // gl: load all OpenGL function pointers
  32. // ---------------------------------------
  33. gl::load_with(|symbol| window.get_proc_address(symbol) as *const _);
  34. let (shader, quadVAO, quadVBO) = unsafe {
  35. // configure global opengl state
  36. // -----------------------------
  37. gl::Enable(gl::DEPTH_TEST);
  38. // build and compile shaders
  39. // -------------------------
  40. let shader = Shader::new(
  41. "src/_4_advanced_opengl/shaders/10.1.instancing.vs",
  42. "src/_4_advanced_opengl/shaders/10.1.instancing.fs",
  43. );
  44. // generate a list of 100 quad locations/translation-vectors
  45. // ---------------------------------------------------------
  46. let mut translations = vec![];
  47. let offset = 0.1;
  48. for y in range_step(-10, 10, 2) {
  49. for x in range_step(-10, 10, 2) {
  50. translations.push(
  51. Vector2 {
  52. x: x as i32 as f32 / 10.0 + offset,
  53. y: y as i32 as f32 / 10.0 + offset
  54. }
  55. )
  56. }
  57. }
  58. let mut instanceVBO = 0;
  59. gl::GenBuffers(1, &mut instanceVBO);
  60. gl::BindBuffer(gl::ARRAY_BUFFER, instanceVBO);
  61. gl::BufferData(
  62. gl::ARRAY_BUFFER,
  63. mem::size_of::<Vector2<f32>>() as isize * 100 ,
  64. &translations[0] as *const Vector2<f32> as *const c_void,
  65. gl::STATIC_DRAW);
  66. gl::BindBuffer(gl::ARRAY_BUFFER, 0);
  67. // set up vertex data (and buffer(s)) and configure vertex attributes
  68. // ------------------------------------------------------------------
  69. let quadVertices: [f32; 30] = [
  70. // positions // colors
  71. -0.05, 0.05, 1.0, 0.0, 0.0,
  72. 0.05, -0.05, 0.0, 1.0, 0.0,
  73. -0.05, -0.05, 0.0, 0.0, 1.0,
  74. -0.05, 0.05, 1.0, 0.0, 0.0,
  75. 0.05, -0.05, 0.0, 1.0, 0.0,
  76. 0.05, 0.05, 0.0, 1.0, 1.0
  77. ];
  78. let (mut quadVAO, mut quadVBO) = (0, 0);
  79. gl::GenVertexArrays(1, &mut quadVAO);
  80. gl::GenBuffers(1, &mut quadVBO);
  81. gl::BindVertexArray(quadVAO);
  82. gl::BindBuffer(gl::ARRAY_BUFFER, quadVBO);
  83. gl::BufferData(gl::ARRAY_BUFFER,
  84. (quadVertices.len() * mem::size_of::<GLfloat>()) as GLsizeiptr,
  85. &quadVertices[0] as *const f32 as *const c_void,
  86. gl::STATIC_DRAW);
  87. gl::EnableVertexAttribArray(0);
  88. let stride = 5 * mem::size_of::<GLfloat>() as GLsizei;
  89. gl::VertexAttribPointer(0, 2, gl::FLOAT, gl::FALSE, stride, ptr::null());
  90. gl::EnableVertexAttribArray(1);
  91. gl::VertexAttribPointer(1, 3, gl::FLOAT, gl::FALSE, stride, (2 * mem::size_of::<GLfloat>()) as *const c_void);
  92. // also set instance data
  93. gl::EnableVertexAttribArray(2);
  94. gl::BindBuffer(gl::ARRAY_BUFFER, instanceVBO); // this attribute comes from a different vertex buffer
  95. gl::VertexAttribPointer(2, 2, gl::FLOAT, gl::FALSE, (2 * mem::size_of::<GLfloat>()) as i32, ptr::null());
  96. gl::BindBuffer(gl::ARRAY_BUFFER, 0);
  97. gl::VertexAttribDivisor(2, 1); // tell OpenGL this is an instanced vertex attribute.
  98. (shader, quadVAO, quadVBO)
  99. };
  100. // render loop
  101. // -----------
  102. while !window.should_close() {
  103. // render
  104. // ------
  105. unsafe {
  106. gl::ClearColor(0.1, 0.1, 0.1, 1.0);
  107. gl::Clear(gl::COLOR_BUFFER_BIT | gl::DEPTH_BUFFER_BIT);
  108. // draw 100 instanced quads
  109. shader.useProgram();
  110. gl::BindVertexArray(quadVAO);
  111. gl::DrawArraysInstanced(gl::TRIANGLES, 0, 6, 100); // 100 triangles of 6 vertices each
  112. gl::BindVertexArray(0);
  113. }
  114. // glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.)
  115. // -------------------------------------------------------------------------------
  116. window.swap_buffers();
  117. glfw.poll_events();
  118. }
  119. // optional: de-allocate all resources once they've outlived their purpose:
  120. // ------------------------------------------------------------------------
  121. unsafe {
  122. gl::DeleteVertexArrays(1, &quadVAO);
  123. gl::DeleteBuffers(1, &quadVBO);
  124. }
  125. }