framebuffer.cpp 4.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. #include "framebuffer.hpp"
  2. slop::Framebuffer::Framebuffer( int w, int h ) {
  3. glGenFramebuffers( 1, &fbuffer );
  4. glBindFramebuffer( GL_FRAMEBUFFER, fbuffer );
  5. glGenTextures(1, &image);
  6. glBindTexture(GL_TEXTURE_2D, image);
  7. glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
  8. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  9. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  10. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  11. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  12. glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, image, 0);
  13. glBindFramebuffer(GL_FRAMEBUFFER, 0);
  14. // generate our vertex and uv buffers
  15. std::vector<glm::vec2> verts;
  16. std::vector<glm::vec2> uvs;
  17. verts.push_back( glm::vec2(1,1) );
  18. uvs.push_back( glm::vec2( 1, 1 ) );
  19. verts.push_back( glm::vec2(-1,-1) );
  20. uvs.push_back( glm::vec2( 0, 0 ) );
  21. verts.push_back( glm::vec2(-1,1) );
  22. uvs.push_back( glm::vec2( 0, 1 ) );
  23. verts.push_back( glm::vec2(-1,-1) );
  24. uvs.push_back( glm::vec2( 0, 0 ) );
  25. verts.push_back( glm::vec2(1,1) );
  26. uvs.push_back( glm::vec2( 1, 1 ) );
  27. verts.push_back( glm::vec2(1,-1) );
  28. uvs.push_back( glm::vec2( 1, 0 ) );
  29. glGenBuffers( 2, buffers );
  30. glBindBuffer( GL_ARRAY_BUFFER, buffers[0] );
  31. glBufferData( GL_ARRAY_BUFFER, verts.size() * sizeof( glm::vec2 ), &verts[0], GL_STATIC_DRAW );
  32. glBindBuffer( GL_ARRAY_BUFFER, buffers[1] );
  33. glBufferData( GL_ARRAY_BUFFER, uvs.size() * sizeof( glm::vec2 ), &uvs[0], GL_STATIC_DRAW );
  34. vertCount = verts.size();
  35. generatedDesktopImage = false;
  36. }
  37. void slop::Framebuffer::setShader( slop::Shader* shader ) {
  38. this->shader = shader;
  39. if ( shader->hasParameter( "desktop" ) && !generatedDesktopImage ) {
  40. // Try to keep the image from being changed under our feet.
  41. XGrabServer(x11->display);
  42. XImage* image = XGetImage( x11->display, x11->root, 0, 0, WidthOfScreen( x11->screen ), HeightOfScreen( x11->screen ), 0xffffffff, ZPixmap );
  43. XUngrabServer(x11->display);
  44. glEnable(GL_TEXTURE_2D);
  45. glGenTextures(1, &desktopImage);
  46. glBindTexture(GL_TEXTURE_2D, desktopImage);
  47. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  48. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  49. //glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  50. glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, WidthOfScreen( x11->screen ), HeightOfScreen( x11->screen ), 0, GL_BGRA, GL_UNSIGNED_BYTE, (void*)(&(image->data[0])));
  51. XDestroyImage( image );
  52. generatedDesktopImage = true;
  53. }
  54. }
  55. slop::Framebuffer::~Framebuffer() {
  56. glDeleteTextures(1, &image);
  57. glDeleteFramebuffers(1,&fbuffer);
  58. glDeleteBuffers(2,buffers);
  59. delete shader;
  60. }
  61. void slop::Framebuffer::resize( int w, int h ) {
  62. // Regenerate the image
  63. glDeleteTextures(1, &image);
  64. glBindTexture(GL_TEXTURE_2D, image);
  65. glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
  66. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  67. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  68. // Re-bind it to the framebuffer
  69. glBindFramebuffer( GL_FRAMEBUFFER, fbuffer );
  70. glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, image, 0);
  71. glBindFramebuffer(GL_FRAMEBUFFER, 0);
  72. }
  73. void slop::Framebuffer::bind() {
  74. glBindFramebuffer( GL_FRAMEBUFFER, fbuffer );
  75. }
  76. void slop::Framebuffer::unbind() {
  77. glBindFramebuffer( GL_FRAMEBUFFER, 0 );
  78. }
  79. void slop::Framebuffer::draw(glm::vec2 mouse, float time, glm::vec4 color){
  80. shader->bind();
  81. shader->setParameter( "texture", 0 );
  82. shader->setAttribute( "position", buffers[0], 2 );
  83. shader->setAttribute( "uv", buffers[1], 2 );
  84. if ( shader->hasParameter( "mouse" ) ) {
  85. shader->setParameter( "mouse", mouse );
  86. }
  87. if ( shader->hasParameter( "color" ) ) {
  88. shader->setParameter( "color", color );
  89. }
  90. if ( shader->hasParameter( "screenSize" ) ) {
  91. shader->setParameter( "screenSize", glm::vec2( WidthOfScreen( x11->screen ), HeightOfScreen( x11->screen ) ));
  92. }
  93. if ( shader->hasParameter( "time" ) ) {
  94. shader->setParameter( "time", time );
  95. }
  96. glActiveTexture(GL_TEXTURE0);
  97. glBindTexture( GL_TEXTURE_2D, image );
  98. if ( shader->hasParameter( "desktop" ) ) {
  99. shader->setParameter( "desktop", 1 );
  100. glActiveTexture(GL_TEXTURE0 + 1);
  101. glBindTexture( GL_TEXTURE_2D, desktopImage );
  102. }
  103. glEnable( GL_TEXTURE_2D );
  104. glDrawArrays( GL_TRIANGLES, 0, vertCount );
  105. glDisable( GL_TEXTURE_2D );
  106. shader->unbind();
  107. }