framebuffer.cpp 19KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444
  1. #include "framebuffer.hpp"
  2. slop::Framebuffer::Framebuffer() {
  3. m_shader = new slop::Shader( "simple", resource->getRealPath( "simple.vert" ), resource->getRealPath( "simple.frag" ) );
  4. generatedBuffers = false;
  5. m_width = 0;
  6. m_height = 0;
  7. m_flags = (slop::Framebuffer::buffers)0;
  8. m_depth = 0;
  9. m_stencil = 0;
  10. m_frame = 0;
  11. m_buffers[0] = 0;
  12. m_buffers[1] = 0;
  13. m_texture = 0;
  14. }
  15. void slop::Framebuffer::setShader( std::string shader ) {
  16. delete m_shader;
  17. m_shader = new slop::Shader( shader, resource->getRealPath( shader + ".vert" ), resource->getRealPath( shader + ".frag" ) );
  18. }
  19. slop::Framebuffer::Framebuffer( unsigned int width, unsigned int height, unsigned char flags, std::string shader ) {
  20. m_shader = new slop::Shader( shader, resource->getRealPath( shader + ".vert" ), resource->getRealPath( shader + ".frag" ) );
  21. generatedBuffers = false;
  22. m_width = width;
  23. m_height = height;
  24. m_flags = flags;
  25. if ( m_flags & stencil && m_flags & depth ) {
  26. fprintf( stderr, "Most hardware doesn't support using a FBO with a depth and stencil attached! Condensing them to one render buffer..." );
  27. }
  28. if ( GLEW_VERSION_3_0 ) {
  29. glGenFramebuffers( 1, &m_frame );
  30. glBindFramebuffer( GL_FRAMEBUFFER, m_frame );
  31. if ( m_flags & color ) {
  32. glGenTextures( 1, &m_texture );
  33. glBindTexture( GL_TEXTURE_2D, m_texture );
  34. glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, m_width, m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0 );
  35. glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
  36. glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
  37. glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_texture, 0 );
  38. }
  39. if ( m_flags & depth && !( m_flags & stencil ) ) {
  40. glGenRenderbuffers( 1, &m_depth );
  41. glBindRenderbuffer( GL_RENDERBUFFER, m_depth );
  42. glRenderbufferStorage( GL_RENDERBUFFER, GL_DEPTH_COMPONENT, m_width, m_height );
  43. glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_depth );
  44. }
  45. //This is the only way I could get a proper stencil buffer, by making a GL_DEPTH_STENCIL attachment to both points.
  46. if ( m_flags & stencil ) {
  47. glGenRenderbuffers( 1, &m_stencil );
  48. glBindRenderbuffer( GL_RENDERBUFFER, m_stencil );
  49. glRenderbufferStorage( GL_RENDERBUFFER, GL_DEPTH_STENCIL, m_width, m_height );
  50. glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_stencil );
  51. glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_stencil );
  52. }
  53. check();
  54. //Make sure we unbind when we're done.
  55. glBindFramebuffer( GL_FRAMEBUFFER, 0 );
  56. } else if ( GLEW_EXT_framebuffer_object ) {
  57. glGenFramebuffersEXT( 1, &m_frame );
  58. glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, m_frame );
  59. if ( m_flags & color ) {
  60. glGenTextures( 1, &m_texture );
  61. glBindTexture( GL_TEXTURE_2D, m_texture );
  62. glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, m_width, m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0 );
  63. glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
  64. glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
  65. glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, m_texture, 0 );
  66. }
  67. if ( m_flags & depth && !( m_flags & stencil ) ) {
  68. glGenRenderbuffersEXT( 1, &m_depth );
  69. glBindRenderbufferEXT( GL_RENDERBUFFER_EXT, m_depth );
  70. glRenderbufferStorageEXT( GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, m_width, m_height );
  71. glFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_depth );
  72. }
  73. //This is the only way I could get a proper stencil buffer, by making a GL_DEPTH_STENCIL attachment to both points.
  74. if ( m_flags & stencil ) {
  75. glGenRenderbuffersEXT( 1, &m_stencil );
  76. glBindRenderbufferEXT( GL_RENDERBUFFER_EXT, m_stencil );
  77. glRenderbufferStorageEXT( GL_RENDERBUFFER_EXT, GL_DEPTH_STENCIL_EXT, m_width, m_height );
  78. glFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_stencil );
  79. glFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_stencil );
  80. }
  81. check();
  82. //Make sure we unbind when we're done.
  83. glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 );
  84. } else {
  85. throw std::runtime_error( "Error: Failed to create framebuffer! You need OpenGL 3.0 or the GL_EXT_framebuffer_object extension!" );
  86. }
  87. }
  88. slop::Framebuffer::~Framebuffer() {
  89. if ( GLEW_VERSION_3_0 ) {
  90. glDeleteFramebuffers( 1, &m_frame );
  91. if ( m_flags & color ) {
  92. glDeleteTextures( 1, &m_texture );
  93. }
  94. if ( m_flags & depth && !( m_flags & stencil ) ) {
  95. glDeleteRenderbuffers( 1, &m_depth );
  96. }
  97. if ( m_flags & stencil ) {
  98. glDeleteRenderbuffers( 1, &m_stencil );
  99. }
  100. } else if ( GLEW_EXT_framebuffer_object ) {
  101. glDeleteFramebuffersEXT( 1, &m_frame );
  102. if ( m_flags & color ) {
  103. glDeleteTextures( 1, &m_texture );
  104. }
  105. if ( m_flags & depth && !( m_flags & stencil ) ) {
  106. glDeleteRenderbuffersEXT( 1, &m_depth );
  107. }
  108. if ( m_flags & stencil ) {
  109. glDeleteRenderbuffersEXT( 1, &m_stencil );
  110. }
  111. }
  112. if ( generatedBuffers ) {
  113. glDeleteBuffers( 2, m_buffers );
  114. }
  115. delete m_shader;
  116. }
  117. void slop::Framebuffer::bind() {
  118. if ( GLEW_VERSION_3_0 ) {
  119. glBindFramebuffer( GL_FRAMEBUFFER, m_frame );
  120. } else if ( GLEW_EXT_framebuffer_object ) {
  121. glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, m_frame );
  122. }
  123. }
  124. void slop::Framebuffer::unbind() {
  125. if ( GLEW_VERSION_3_0 ) {
  126. glBindFramebuffer( GL_FRAMEBUFFER, 0 );
  127. } else if ( GLEW_EXT_framebuffer_object ) {
  128. glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 );
  129. }
  130. }
  131. void slop::Framebuffer::createFromTexture( unsigned int texture, std::string shader ) {
  132. // First make sure we're empty.
  133. if ( GLEW_VERSION_3_0 ) {
  134. glDeleteFramebuffers( 1, &m_frame );
  135. if ( m_flags & color ) {
  136. glDeleteTextures( 1, &m_texture );
  137. }
  138. if ( m_flags & depth && !( m_flags & stencil ) ) {
  139. glDeleteRenderbuffers( 1, &m_depth );
  140. }
  141. if ( m_flags & stencil ) {
  142. glDeleteRenderbuffers( 1, &m_stencil );
  143. }
  144. } else if ( GLEW_EXT_framebuffer_object ) {
  145. glDeleteFramebuffersEXT( 1, &m_frame );
  146. if ( m_flags & color ) {
  147. glDeleteTextures( 1, &m_texture );
  148. }
  149. if ( m_flags & depth && !( m_flags & stencil ) ) {
  150. glDeleteRenderbuffersEXT( 1, &m_depth );
  151. }
  152. if ( m_flags & stencil ) {
  153. glDeleteRenderbuffersEXT( 1, &m_stencil );
  154. }
  155. }
  156. delete m_shader;
  157. m_shader = new slop::Shader( shader, resource->getRealPath( shader + ".vert" ), resource->getRealPath( shader + ".frag" ) );
  158. // Set flags to 0 so we don't delete the texture on deconstruction.
  159. m_flags = 0;
  160. m_texture = texture;
  161. if ( GLEW_VERSION_3_0 ) {
  162. glGenFramebuffers( 1, &m_frame );
  163. glBindFramebuffer( GL_FRAMEBUFFER, m_frame );
  164. glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_texture, 0 );
  165. } else if ( GLEW_EXT_framebuffer_object ) {
  166. glGenFramebuffersEXT( 1, &m_frame );
  167. glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, m_frame );
  168. glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, m_texture, 0 );
  169. }
  170. check();
  171. glBindFramebuffer( GL_FRAMEBUFFER, 0 );
  172. }
  173. void slop::Framebuffer::create( unsigned int width, unsigned int height, unsigned char flags, std::string shader ) {
  174. if ( m_width == width && m_height == height && m_flags == flags ) {
  175. return;
  176. }
  177. delete m_shader;
  178. m_shader = new slop::Shader( shader, resource->getRealPath( shader + ".vert" ), resource->getRealPath( shader + ".frag" ) );
  179. if ( GLEW_VERSION_3_0 ) {
  180. glDeleteFramebuffers( 1, &m_frame );
  181. if ( m_flags & color ) {
  182. glDeleteTextures( 1, &m_texture );
  183. }
  184. if ( m_flags & depth && !( m_flags & stencil ) ) {
  185. glDeleteRenderbuffers( 1, &m_depth );
  186. }
  187. if ( m_flags & stencil ) {
  188. glDeleteRenderbuffers( 1, &m_stencil );
  189. }
  190. } else if ( GLEW_EXT_framebuffer_object ) {
  191. glDeleteFramebuffersEXT( 1, &m_frame );
  192. if ( m_flags & color ) {
  193. glDeleteTextures( 1, &m_texture );
  194. }
  195. if ( m_flags & depth && !( m_flags & stencil ) ) {
  196. glDeleteRenderbuffersEXT( 1, &m_depth );
  197. }
  198. if ( m_flags & stencil ) {
  199. glDeleteRenderbuffersEXT( 1, &m_stencil );
  200. }
  201. }
  202. m_flags = flags;
  203. m_width = width;
  204. m_height = height;
  205. if ( GLEW_VERSION_3_0 ) {
  206. glGenFramebuffers( 1, &m_frame );
  207. glBindFramebuffer( GL_FRAMEBUFFER, m_frame );
  208. if ( m_flags & color ) {
  209. glGenTextures( 1, &m_texture );
  210. glBindTexture( GL_TEXTURE_2D, m_texture );
  211. glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, m_width, m_height, 0, GL_RGB, GL_UNSIGNED_BYTE, 0 );
  212. glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
  213. glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
  214. glFramebufferTexture2D( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_texture, 0 );
  215. }
  216. if ( m_flags & depth && !( m_flags & stencil ) ) {
  217. glGenRenderbuffers( 1, &m_depth );
  218. glBindRenderbuffer( GL_RENDERBUFFER, m_depth );
  219. glRenderbufferStorage( GL_RENDERBUFFER, GL_DEPTH_COMPONENT, m_width, m_height );
  220. glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_depth );
  221. }
  222. //This is the only way I could get a proper stencil buffer, by making a GL_DEPTH_STENCIL attachment to both points.
  223. if ( m_flags & stencil ) {
  224. glGenRenderbuffers( 1, &m_stencil );
  225. glBindRenderbuffer( GL_RENDERBUFFER, m_stencil );
  226. glRenderbufferStorage( GL_RENDERBUFFER, GL_DEPTH_STENCIL, m_width, m_height );
  227. glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_stencil );
  228. glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_stencil );
  229. }
  230. //Make sure we unbind when we're done.
  231. glBindFramebuffer( GL_FRAMEBUFFER, 0 );
  232. } else if ( GLEW_EXT_framebuffer_object ) {
  233. glGenFramebuffersEXT( 1, &m_frame );
  234. glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, m_frame );
  235. if ( m_flags & color ) {
  236. glGenTextures( 1, &m_texture );
  237. glBindTexture( GL_TEXTURE_2D, m_texture );
  238. glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, m_width, m_height, 0, GL_RGB, GL_UNSIGNED_BYTE, 0 );
  239. glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
  240. glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
  241. glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, m_texture, 0 );
  242. }
  243. if ( m_flags & depth && !( m_flags & stencil ) ) {
  244. glGenRenderbuffersEXT( 1, &m_depth );
  245. glBindRenderbufferEXT( GL_RENDERBUFFER_EXT, m_depth );
  246. glRenderbufferStorageEXT( GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, m_width, m_height );
  247. glFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_depth );
  248. }
  249. //This is the only way I could get a proper stencil buffer, by making a GL_DEPTH_STENCIL attachment to both points.
  250. if ( m_flags & stencil ) {
  251. glGenRenderbuffersEXT( 1, &m_stencil );
  252. glBindRenderbufferEXT( GL_RENDERBUFFER_EXT, m_stencil );
  253. glRenderbufferStorageEXT( GL_RENDERBUFFER_EXT, GL_DEPTH_STENCIL_EXT, m_width, m_height );
  254. glFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_stencil );
  255. glFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_stencil );
  256. }
  257. //Make sure we unbind when we're done.
  258. glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 );
  259. }
  260. }
  261. void slop::Framebuffer::check()
  262. {
  263. if ( GLEW_VERSION_3_0 ) {
  264. glBindFramebuffer( GL_FRAMEBUFFER, m_frame );
  265. unsigned int err = glCheckFramebufferStatus( GL_FRAMEBUFFER );
  266. if ( err == GL_FRAMEBUFFER_COMPLETE ) {
  267. return;
  268. }
  269. fprintf( stderr, "Error: Framebuffer failed a check procedure for reason: " );
  270. switch ( err ) {
  271. case GL_FRAMEBUFFER_UNDEFINED: {
  272. fprintf( stderr, "GL_FRAMEBUFFER_UNDEFINED\n" );
  273. break;
  274. }
  275. case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: {
  276. fprintf( stderr, "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT\n" );
  277. break;
  278. }
  279. case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: {
  280. fprintf( stderr, "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT\n" );
  281. break;
  282. }
  283. case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER: {
  284. fprintf( stderr, "GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER\n" );
  285. break;
  286. }
  287. case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER: {
  288. fprintf( stderr, "GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER\n" );
  289. break;
  290. }
  291. case GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS: {
  292. fprintf( stderr, "GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS\n" );
  293. break;
  294. }
  295. case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE: {
  296. fprintf( stderr, "GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE\n" );
  297. break;
  298. }
  299. case GL_FRAMEBUFFER_UNSUPPORTED: {
  300. fprintf( stderr, "GL_FRAMEBUFFER_UNSUPPORTED\n" );
  301. break;
  302. }
  303. default: {
  304. fprintf( stderr, "UNKNOWN\n" );
  305. break;
  306. }
  307. }
  308. glBindFramebuffer( GL_FRAMEBUFFER, 0 );
  309. } else if ( GLEW_EXT_framebuffer_object ) {
  310. glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, m_frame );
  311. unsigned int err = glCheckFramebufferStatusEXT( GL_FRAMEBUFFER_EXT );
  312. if ( err == GL_FRAMEBUFFER_COMPLETE_EXT ) {
  313. return;
  314. }
  315. switch ( err ) {
  316. /* Apparently doesn't exist as an extension.
  317. case GL_FRAMEBUFFER_UNDEFINED_EXT: {
  318. fprintf( stderr, "GL_FRAMEBUFFER_UNDEFINED_EXT\n" );
  319. break;
  320. }*/
  321. case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT: {
  322. fprintf( stderr, "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT\n" );
  323. break;
  324. }
  325. case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT: {
  326. fprintf( stderr, "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT\n" );
  327. break;
  328. }
  329. case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT: {
  330. fprintf( stderr, "GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT\n" );
  331. break;
  332. }
  333. case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT: {
  334. fprintf( stderr, "GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT\n" );
  335. break;
  336. }
  337. case GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT: {
  338. fprintf( stderr, "GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT\n" );
  339. break;
  340. }
  341. case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT: {
  342. fprintf( stderr, "GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT\n" );
  343. break;
  344. }
  345. case GL_FRAMEBUFFER_UNSUPPORTED_EXT: {
  346. fprintf( stderr, "GL_FRAMEBUFFER_UNSUPPORTED_EXT\n" );
  347. break;
  348. }
  349. default: {
  350. fprintf( stderr, "Unknown framebuffer error!\n" );
  351. break;
  352. }
  353. }
  354. glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 );
  355. }
  356. }
  357. void slop::Framebuffer::generateBuffers() {
  358. if ( generatedBuffers ) {
  359. return;
  360. }
  361. std::vector<glm::vec2> verts;
  362. std::vector<glm::vec2> uvs;
  363. verts.push_back( glm::vec2( -1, -1 ) );
  364. verts.push_back( glm::vec2( 1, -1 ) );
  365. verts.push_back( glm::vec2( 1, 1 ) );
  366. verts.push_back( glm::vec2( -1, 1 ) );
  367. uvs.push_back( glm::vec2( 0, 0 ) );
  368. uvs.push_back( glm::vec2( 1, 0 ) );
  369. uvs.push_back( glm::vec2( 1, 1 ) );
  370. uvs.push_back( glm::vec2( 0, 1 ) );
  371. glGenBuffers( 2, m_buffers );
  372. glBindBuffer( GL_ARRAY_BUFFER, m_buffers[0] );
  373. glBufferData( GL_ARRAY_BUFFER, verts.size() * sizeof( glm::vec2 ), &verts[0], GL_STATIC_DRAW );
  374. glBindBuffer( GL_ARRAY_BUFFER, m_buffers[1] );
  375. glBufferData( GL_ARRAY_BUFFER, uvs.size() * sizeof( glm::vec2 ), &uvs[0], GL_STATIC_DRAW );
  376. generatedBuffers = true;
  377. }
  378. void slop::Framebuffer::clear( glm::vec4 clearcolor, unsigned char flags ) {
  379. // FIXME: This should auto-bind and unbind, but I was too lazy to find out how to push and pop gl states.
  380. unsigned int colorbit = 0;
  381. if ( flags & color ) {
  382. colorbit = colorbit | GL_COLOR_BUFFER_BIT;
  383. }
  384. if ( m_flags & depth && flags & depth ) {
  385. colorbit = colorbit | GL_DEPTH_BUFFER_BIT;
  386. }
  387. if ( m_flags & stencil && flags & stencil) {
  388. colorbit = colorbit | GL_STENCIL_BUFFER_BIT;
  389. }
  390. glClearColor( clearcolor.x, clearcolor.y, clearcolor.z, clearcolor.w );
  391. glClear( colorbit );
  392. }
  393. void slop::Framebuffer::draw( float time, unsigned int desktop ) {
  394. if ( !( m_flags & color ) ) {
  395. return;
  396. }
  397. generateBuffers();
  398. //slop::Shader* shader = shaders->get( "simple" );
  399. m_shader->bind();
  400. m_shader->setParameter( "texture", 0 );
  401. m_shader->setParameter( "desktop", 1 );
  402. m_shader->setParameter( "time", time );
  403. m_shader->setParameter( "desktopWidth", (int)xengine->getWidth() );
  404. m_shader->setParameter( "desktopHeight", (int)xengine->getHeight() );
  405. m_shader->setAttribute( "vertex", m_buffers[0], 2 );
  406. m_shader->setAttribute( "uv", m_buffers[1], 2 );
  407. glActiveTexture(GL_TEXTURE0 + 0);
  408. glBindTexture( GL_TEXTURE_2D, m_texture );
  409. glActiveTexture(GL_TEXTURE0 + 1);
  410. glBindTexture( GL_TEXTURE_2D, desktop );
  411. glActiveTexture(GL_TEXTURE0 + 0);
  412. glEnable( GL_TEXTURE_2D );
  413. glDrawArrays( GL_QUADS, 0, 4 );
  414. glDisable( GL_TEXTURE_2D );
  415. m_shader->unbind();
  416. }