init_render_to_texture.cpp 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. // This file is part of libigl, a simple c++ geometry processing library.
  2. //
  3. // Copyright (C) 2015 Alec Jacobson <alecjacobson@gmail.com>
  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 <cassert>
  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. using namespace std;
  20. // Delete if already exists
  21. glDeleteTextures(1,&tex_id);
  22. glDeleteFramebuffers(1,&fbo_id);
  23. if(depth_texture)
  24. {
  25. glDeleteTextures(1,&d_id);
  26. }else
  27. {
  28. glDeleteFramebuffers(1,&d_id);
  29. }
  30. // http://www.opengl.org/wiki/Framebuffer_Object_Examples#Quick_example.2C_render_to_texture_.282D.29
  31. const auto & gen_tex = [](GLuint & tex_id)
  32. {
  33. glGenTextures(1, &tex_id);
  34. glBindTexture(GL_TEXTURE_2D, tex_id);
  35. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  36. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  37. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  38. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  39. };
  40. gen_tex(tex_id);
  41. //NULL means reserve texture memory, but texels are undefined
  42. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, width, height, 0, GL_BGRA, GL_FLOAT, NULL);
  43. glBindTexture(GL_TEXTURE_2D, 0);
  44. glGenFramebuffers(1, &fbo_id);
  45. glBindFramebuffer(GL_FRAMEBUFFER, fbo_id);
  46. //Attach 2D texture to this FBO
  47. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex_id, 0);
  48. if(depth_texture)
  49. {
  50. // Generate a depth texture
  51. gen_tex(d_id);
  52. glTexImage2D(
  53. GL_TEXTURE_2D,
  54. 0,
  55. GL_DEPTH_COMPONENT32,
  56. width,
  57. height,
  58. 0,
  59. GL_DEPTH_COMPONENT,
  60. GL_FLOAT,
  61. NULL);
  62. glFramebufferTexture2D(
  63. GL_FRAMEBUFFER,GL_DEPTH_ATTACHMENT,GL_TEXTURE_2D,d_id,0);
  64. }else
  65. {
  66. // Attach a depth buffer
  67. glGenRenderbuffers(1, &d_id);
  68. glBindRenderbuffer(GL_RENDERBUFFER, d_id);
  69. glRenderbufferStorage(GL_RENDERBUFFER,GL_DEPTH_COMPONENT24,width,height);
  70. glFramebufferRenderbuffer(
  71. GL_FRAMEBUFFER,GL_DEPTH_ATTACHMENT,GL_RENDERBUFFER,d_id);
  72. }
  73. //Does the GPU support current FBO configuration?
  74. GLenum status;
  75. status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
  76. assert(status == GL_FRAMEBUFFER_COMPLETE);
  77. // Unbind to clean up
  78. if(!depth_texture)
  79. {
  80. glBindRenderbuffer(GL_RENDERBUFFER, 0);
  81. }
  82. glBindFramebuffer(GL_FRAMEBUFFER, 0);
  83. }
  84. IGL_INLINE void igl::opengl::init_render_to_texture(
  85. const size_t width,
  86. const size_t height,
  87. GLuint & tex_id,
  88. GLuint & fbo_id,
  89. GLuint & dfbo_id)
  90. {
  91. return init_render_to_texture(width,height,false,tex_id,fbo_id,dfbo_id);
  92. }