init_render_to_texture.cpp 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. // This file is part of libigl, a simple c++ geometry processing library.
  2. //
  3. // Copyright (C) 2015 Alec Jacobson <[email protected]>
  4. //
  5. // This Source Code Form is subject to the terms of the Mozilla Public License
  6. // v. 2.0. If a copy of the MPL was not distributed with this file, You can
  7. // obtain one at http://mozilla.org/MPL/2.0/.
  8. #include "init_render_to_texture.h"
  9. #include "gl.h"
  10. #include "../IGL_ASSERT.h"
  11. IGL_INLINE void igl::opengl::init_render_to_texture(
  12. const size_t width,
  13. const size_t height,
  14. const bool depth_texture,
  15. GLuint & tex_id,
  16. GLuint & fbo_id,
  17. GLuint & d_id)
  18. {
  19. // http://www.opengl.org/wiki/Framebuffer_Object_Examples#Quick_example.2C_render_to_texture_.282D.29
  20. const auto & gen_tex = [](GLuint & tex_id)
  21. {
  22. glGenTextures(1, &tex_id);
  23. glBindTexture(GL_TEXTURE_2D, tex_id);
  24. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  25. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  26. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  27. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  28. };
  29. gen_tex(tex_id);
  30. //NULL means reserve texture memory, but texels are undefined
  31. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, width, height, 0, GL_BGRA, GL_FLOAT, NULL);
  32. glBindTexture(GL_TEXTURE_2D, 0);
  33. glGenFramebuffers(1, &fbo_id);
  34. glBindFramebuffer(GL_FRAMEBUFFER, fbo_id);
  35. //Attach 2D texture to this FBO
  36. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex_id, 0);
  37. if(depth_texture)
  38. {
  39. // Generate a depth texture
  40. gen_tex(d_id);
  41. glTexImage2D(
  42. GL_TEXTURE_2D,
  43. 0,
  44. GL_DEPTH_COMPONENT32,
  45. width,
  46. height,
  47. 0,
  48. GL_DEPTH_COMPONENT,
  49. GL_FLOAT,
  50. NULL);
  51. glFramebufferTexture2D(
  52. GL_FRAMEBUFFER,GL_DEPTH_ATTACHMENT,GL_TEXTURE_2D,d_id,0);
  53. }else
  54. {
  55. // Attach a depth buffer
  56. glGenRenderbuffers(1, &d_id);
  57. glBindRenderbuffer(GL_RENDERBUFFER, d_id);
  58. glRenderbufferStorage(GL_RENDERBUFFER,GL_DEPTH_COMPONENT24,width,height);
  59. glFramebufferRenderbuffer(
  60. GL_FRAMEBUFFER,GL_DEPTH_ATTACHMENT,GL_RENDERBUFFER,d_id);
  61. }
  62. //Does the GPU support current FBO configuration?
  63. GLenum status;
  64. status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
  65. IGL_ASSERT(status == GL_FRAMEBUFFER_COMPLETE);
  66. // Unbind to clean up
  67. if(!depth_texture)
  68. {
  69. glBindRenderbuffer(GL_RENDERBUFFER, 0);
  70. }
  71. glBindFramebuffer(GL_FRAMEBUFFER, 0);
  72. }
  73. IGL_INLINE void igl::opengl::init_render_to_texture(
  74. const size_t width,
  75. const size_t height,
  76. GLuint & tex_id,
  77. GLuint & fbo_id,
  78. GLuint & dfbo_id)
  79. {
  80. return init_render_to_texture(width,height,false,tex_id,fbo_id,dfbo_id);
  81. }