No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

framebuffer.cpp 5.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. /* The MIT License
  2. *
  3. * Copyright (c) 2010 OTClient, https://github.com/edubart/otclient
  4. *
  5. * Permission is hereby granted, free of charge, to any person obtaining a copy
  6. * of this software and associated documentation files (the "Software"), to deal
  7. * in the Software without restriction, including without limitation the rights
  8. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. * copies of the Software, and to permit persons to whom the Software is
  10. * furnished to do so, subject to the following conditions:
  11. *
  12. * The above copyright notice and this permission notice shall be included in
  13. * all copies or substantial portions of the Software.
  14. *
  15. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  21. * THE SOFTWARE.
  22. */
  23. #include "framebuffer.h"
  24. #include "platform.h"
  25. #include "graphics.h"
  26. PFNGLGENFRAMEBUFFERSPROC oglGenFramebuffers = 0;
  27. PFNGLBINDFRAMEBUFFERPROC oglBindFramebuffer = 0;
  28. PFNGLFRAMEBUFFERTEXTURE2DPROC oglFramebufferTexture2D = 0;
  29. PFNGLDELETEFRAMEBUFFERSPROC oglDeleteFramebuffers = 0;
  30. PFNGLCHECKFRAMEBUFFERSTATUSPROC oglCheckFramebufferStatus = 0;
  31. FrameBuffer::FrameBuffer(int width, int height)
  32. {
  33. m_fbo = 0;
  34. m_width = width;
  35. m_height = height;
  36. // create FBO texture
  37. glGenTextures(1, &m_fboTexture);
  38. glBindTexture(GL_TEXTURE_2D, m_fboTexture);
  39. glTexImage2D(GL_TEXTURE_2D, 0, 4, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
  40. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  41. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  42. // we want bilinear filtering (for a smooth framebuffer)
  43. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  44. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  45. // use FBO ext only if supported
  46. if(g_graphics.isExtensionSupported("ARB_framebuffer_object")) {
  47. m_fallbackOldImp = false;
  48. if(!oglGenFramebuffers) {
  49. oglGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC)Platform::getExtensionProcAddress("glGenFramebuffers");
  50. oglBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC)Platform::getExtensionProcAddress("glBindFramebuffer");
  51. oglFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC)Platform::getExtensionProcAddress("glFramebufferTexture2D");
  52. oglDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC)Platform::getExtensionProcAddress("glDeleteFramebuffers");
  53. oglCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC)Platform::getExtensionProcAddress("glCheckFramebufferStatus");
  54. }
  55. // generate FBO
  56. oglGenFramebuffers(1, &m_fbo);
  57. oglBindFramebuffer(GL_FRAMEBUFFER_EXT, m_fbo);
  58. // attach 2D texture to this FBO
  59. oglFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, m_fboTexture, 0);
  60. GLenum status = oglCheckFramebufferStatus(GL_FRAMEBUFFER_EXT);
  61. switch(status) {
  62. case GL_FRAMEBUFFER_COMPLETE_EXT:
  63. //ok
  64. break;
  65. default: // fallback to old implementation
  66. m_fallbackOldImp = true;
  67. break;
  68. }
  69. } else {
  70. // otherwise fallback to copy texture from screen implementation
  71. m_fallbackOldImp = true;
  72. }
  73. }
  74. FrameBuffer::~FrameBuffer()
  75. {
  76. glDeleteTextures(1, &m_fboTexture);
  77. if(m_fbo)
  78. oglDeleteFramebuffers(1, &m_fbo);
  79. }
  80. void FrameBuffer::bind()
  81. {
  82. if(!m_fallbackOldImp) {
  83. // bind framebuffer
  84. oglBindFramebuffer(GL_FRAMEBUFFER_EXT, m_fbo);
  85. }
  86. // setup framebuffer viewport
  87. glViewport(0, 0, m_width, m_height);
  88. glMatrixMode(GL_PROJECTION);
  89. glLoadIdentity();
  90. gluOrtho2D(0.0f, m_width, 0, m_height);
  91. // back to model view
  92. glMatrixMode(GL_MODELVIEW);
  93. glLoadIdentity();
  94. // clear framebuffer
  95. glClearColor(0.0, 0.0, 0.0, 0.0);
  96. glClear(GL_COLOR_BUFFER_BIT);
  97. }
  98. void FrameBuffer::unbind()
  99. {
  100. if(!m_fallbackOldImp) {
  101. // bind back buffer again
  102. oglBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
  103. glDrawBuffer(GL_BACK);
  104. glReadBuffer(GL_BACK);
  105. // restore graphics viewport
  106. g_graphics.restoreViewport();
  107. } else {
  108. // copy screen to texture
  109. glBindTexture(GL_TEXTURE_2D, m_fboTexture);
  110. glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, m_width, m_height);
  111. // restore graphics viewport
  112. g_graphics.restoreViewport();
  113. // clear screen
  114. glClearColor(0.0, 0.0, 0.0, 1.0);
  115. glClear(GL_COLOR_BUFFER_BIT);
  116. }
  117. }
  118. void FrameBuffer::draw(int x, int y, int width, int height)
  119. {
  120. glBindTexture(GL_TEXTURE_2D, m_fboTexture);
  121. glBegin(GL_QUADS);
  122. glTexCoord2i(0, 0); glVertex2i(x, y);
  123. glTexCoord2i(0, 1); glVertex2i(x, y+height);
  124. glTexCoord2i(1, 1); glVertex2i(x+width, y+height);
  125. glTexCoord2i(1, 0); glVertex2i(x+width, y);
  126. glEnd();
  127. }