/extra/gpu/framebuffers/framebuffers.factor

http://github.com/abeaumont/factor · Factor · 390 lines · 312 code · 77 blank · 1 comment · 26 complexity · 61b2a0679ff9a131be291632269d8a47 MD5 · raw file

  1. ! (c)2009 Joe Groff bsd license
  2. USING: accessors alien.c-types alien.data arrays byte-arrays
  3. combinators destructors gpu gpu.buffers gpu.private gpu.textures
  4. gpu.textures.private images kernel locals math math.rectangles
  5. opengl opengl.framebuffers opengl.gl opengl.textures sequences
  6. specialized-arrays typed ui.gadgets.worlds variants ;
  7. SPECIALIZED-ARRAY: int
  8. SPECIALIZED-ARRAY: uint
  9. IN: gpu.framebuffers
  10. SINGLETON: system-framebuffer
  11. TUPLE: renderbuffer < gpu-object
  12. { component-order component-order initial: RGBA }
  13. { component-type component-type initial: ubyte-components }
  14. { samples integer initial: 0 } ;
  15. <PRIVATE
  16. : get-framebuffer-int ( enum -- value )
  17. GL_RENDERBUFFER swap 0 int <ref>
  18. [ glGetRenderbufferParameteriv ] keep int deref ;
  19. PRIVATE>
  20. TYPED:: allocate-renderbuffer ( renderbuffer: renderbuffer dim -- )
  21. GL_RENDERBUFFER renderbuffer handle>> glBindRenderbuffer
  22. GL_RENDERBUFFER
  23. renderbuffer samples>> dup zero?
  24. [ drop renderbuffer texture-gl-internal-format dim first2 glRenderbufferStorage ]
  25. [ renderbuffer texture-gl-internal-format dim first2 glRenderbufferStorageMultisample ]
  26. if ;
  27. TYPED:: renderbuffer-dim ( renderbuffer: renderbuffer -- dim: array )
  28. GL_RENDERBUFFER renderbuffer handle>> glBindRenderbuffer
  29. GL_RENDERBUFFER_WIDTH get-framebuffer-int
  30. GL_RENDERBUFFER_HEIGHT get-framebuffer-int 2array ;
  31. TYPED: <renderbuffer> ( component-order: component-order
  32. component-type: component-type
  33. samples
  34. dim
  35. --
  36. renderbuffer )
  37. [ [ gen-renderbuffer ] 3dip renderbuffer boa dup ] dip
  38. [ allocate-renderbuffer ] [ drop ] if*
  39. window-resource ;
  40. M: renderbuffer dispose
  41. [ [ delete-renderbuffer ] when* f ] change-handle drop ;
  42. TUPLE: texture-1d-attachment
  43. { texture texture-1d-data-target read-only initial: T{ texture-1d } }
  44. { level integer read-only } ;
  45. C: <texture-1d-attachment> texture-1d-attachment
  46. TUPLE: texture-2d-attachment
  47. { texture texture-2d-data-target read-only initial: T{ texture-2d } }
  48. { level integer read-only } ;
  49. C: <texture-2d-attachment> texture-2d-attachment
  50. TUPLE: texture-3d-attachment
  51. { texture texture-3d read-only initial: T{ texture-3d } }
  52. { z-offset integer read-only }
  53. { level integer read-only } ;
  54. C: <texture-3d-attachment> texture-3d-attachment
  55. TUPLE: texture-layer-attachment
  56. { texture texture-3d-data-target read-only initial: T{ texture-3d } }
  57. { layer integer read-only }
  58. { level integer read-only } ;
  59. C: <texture-layer-attachment> texture-layer-attachment
  60. UNION: texture-attachment
  61. texture-1d-attachment texture-2d-attachment texture-3d-attachment texture-layer-attachment ;
  62. M: texture-attachment dispose texture>> dispose ;
  63. UNION: framebuffer-attachment renderbuffer texture-attachment ;
  64. GENERIC: attachment-object ( attachment -- object )
  65. M: renderbuffer attachment-object ;
  66. M: texture-attachment attachment-object texture>> texture-object ;
  67. TUPLE: framebuffer < gpu-object
  68. { color-attachments array read-only }
  69. { depth-attachment maybe{ framebuffer-attachment } read-only initial: f }
  70. { stencil-attachment maybe{ framebuffer-attachment } read-only initial: f } ;
  71. UNION: any-framebuffer system-framebuffer framebuffer ;
  72. VARIANT: framebuffer-attachment-side
  73. left-side right-side ;
  74. VARIANT: framebuffer-attachment-face
  75. back-face front-face ;
  76. VARIANT: color-attachment-ref
  77. default-attachment
  78. system-attachment: {
  79. { side maybe{ framebuffer-attachment-side } initial: f }
  80. { face maybe{ framebuffer-attachment-face } initial: back-face }
  81. }
  82. color-attachment: { { index integer } } ;
  83. VARIANT: non-color-attachment-ref
  84. depth-attachment
  85. stencil-attachment ;
  86. UNION: attachment-ref
  87. color-attachment-ref
  88. non-color-attachment-ref
  89. POSTPONE: f ;
  90. TUPLE: framebuffer-rect
  91. { framebuffer any-framebuffer read-only initial: system-framebuffer }
  92. { attachment color-attachment-ref read-only initial: default-attachment }
  93. { rect rect read-only } ;
  94. C: <framebuffer-rect> framebuffer-rect
  95. TYPED: framebuffer-attachment-at ( framebuffer: framebuffer
  96. attachment-ref: attachment-ref
  97. --
  98. attachment: framebuffer-attachment )
  99. {
  100. { default-attachment [ color-attachments>> first ] }
  101. { color-attachment [ swap color-attachments>> nth ] }
  102. { depth-attachment [ depth-attachment>> ] }
  103. { stencil-attachment [ stencil-attachment>> ] }
  104. } match ;
  105. <PRIVATE
  106. GENERIC: framebuffer-handle ( framebuffer -- handle )
  107. M: system-framebuffer framebuffer-handle drop 0 ;
  108. M: framebuffer framebuffer-handle handle>> ;
  109. GENERIC# allocate-framebuffer-attachment 1 ( framebuffer-attachment dim -- )
  110. M: texture-attachment allocate-framebuffer-attachment
  111. [ [ texture>> ] [ level>> ] bi ] dip f allocate-texture ;
  112. M: renderbuffer allocate-framebuffer-attachment
  113. allocate-renderbuffer ;
  114. GENERIC: framebuffer-attachment-dim ( framebuffer-attachment -- dim )
  115. M: texture-attachment framebuffer-attachment-dim
  116. [ texture>> ] [ level>> ] bi texture-dim
  117. dup number? [ 1 2array ] [ 2 head ] if ;
  118. M: renderbuffer framebuffer-attachment-dim
  119. renderbuffer-dim ;
  120. : each-attachment ( framebuffer quot: ( attachment -- ) -- )
  121. [ [ color-attachments>> ] dip each ]
  122. [ swap depth-attachment>> [ swap call ] [ drop ] if* ]
  123. [ swap stencil-attachment>> [ swap call ] [ drop ] if* ] 2tri ; inline
  124. :: each-attachment-target ( framebuffer quot: ( attachment-target attachment -- ) -- )
  125. framebuffer color-attachments>>
  126. [| attachment n | n GL_COLOR_ATTACHMENT0 + attachment quot call ] each-index
  127. framebuffer depth-attachment>>
  128. [| attachment | GL_DEPTH_ATTACHMENT attachment quot call ] when*
  129. framebuffer stencil-attachment>>
  130. [| attachment | GL_STENCIL_ATTACHMENT attachment quot call ] when* ; inline
  131. GENERIC: bind-framebuffer-attachment ( attachment-target attachment -- )
  132. M:: renderbuffer bind-framebuffer-attachment ( attachment-target renderbuffer -- )
  133. GL_DRAW_FRAMEBUFFER attachment-target
  134. GL_RENDERBUFFER renderbuffer handle>>
  135. glFramebufferRenderbuffer ;
  136. M:: texture-1d-attachment bind-framebuffer-attachment ( attachment-target texture-attachment -- )
  137. GL_DRAW_FRAMEBUFFER attachment-target
  138. texture-attachment [ texture>> [ texture-data-gl-target ] [ texture-object handle>> ] bi ] [ level>> ] bi
  139. glFramebufferTexture1D ;
  140. M:: texture-2d-attachment bind-framebuffer-attachment ( attachment-target texture-attachment -- )
  141. GL_DRAW_FRAMEBUFFER attachment-target
  142. texture-attachment [ texture>> [ texture-data-gl-target ] [ texture-object handle>> ] bi ] [ level>> ] bi
  143. glFramebufferTexture2D ;
  144. M:: texture-3d-attachment bind-framebuffer-attachment ( attachment-target texture-attachment -- )
  145. GL_DRAW_FRAMEBUFFER attachment-target
  146. texture-attachment
  147. [ texture>> [ texture-data-gl-target ] [ texture-object handle>> ] bi ]
  148. [ level>> ] [ z-offset>> ] tri
  149. glFramebufferTexture3D ;
  150. M:: texture-layer-attachment bind-framebuffer-attachment ( attachment-target texture-attachment -- )
  151. GL_DRAW_FRAMEBUFFER attachment-target
  152. texture-attachment
  153. [ texture>> texture-object handle>> ]
  154. [ level>> ] [ layer>> ] tri
  155. glFramebufferTextureLayer ;
  156. GENERIC: (default-gl-attachment) ( framebuffer -- gl-attachment )
  157. GENERIC: (default-attachment-type) ( framebuffer -- type )
  158. GENERIC: (default-attachment-image-type) ( framebuffer -- order type )
  159. M: system-framebuffer (default-gl-attachment)
  160. drop GL_BACK ;
  161. M: framebuffer (default-gl-attachment)
  162. drop GL_COLOR_ATTACHMENT0 ;
  163. SYMBOLS: float-type int-type uint-type ;
  164. : (color-attachment-type) ( framebuffer index -- type )
  165. swap color-attachments>> nth attachment-object component-type>> {
  166. { [ dup signed-unnormalized-integer-components? ] [ drop int-type ] }
  167. { [ dup unsigned-unnormalized-integer-components? ] [ drop uint-type ] }
  168. [ drop float-type ]
  169. } cond ;
  170. M: system-framebuffer (default-attachment-type)
  171. drop float-type ;
  172. M: framebuffer (default-attachment-type)
  173. 0 (color-attachment-type) ;
  174. M: system-framebuffer (default-attachment-image-type) ( framebuffer -- order type )
  175. drop RGBA ubyte-components ;
  176. M: framebuffer (default-attachment-image-type) ( framebuffer -- order type )
  177. color-attachments>> first attachment-object
  178. [ component-order>> ] [ component-type>> ] bi ;
  179. : gl-system-attachment ( side face -- attachment )
  180. 2array {
  181. { { f f } [ GL_FRONT_AND_BACK ] }
  182. { { f front-face } [ GL_FRONT ] }
  183. { { f back-face } [ GL_BACK ] }
  184. { { left-side f } [ GL_LEFT ] }
  185. { { left-side front-face } [ GL_FRONT_LEFT ] }
  186. { { left-side back-face } [ GL_BACK_LEFT ] }
  187. { { right-side f } [ GL_RIGHT ] }
  188. { { right-side front-face } [ GL_FRONT_RIGHT ] }
  189. { { right-side back-face } [ GL_BACK_RIGHT ] }
  190. } case ;
  191. : gl-attachment ( framebuffer attachment-ref -- gl-attachment )
  192. [ {
  193. { depth-attachment [ GL_DEPTH_ATTACHMENT ] }
  194. { stencil-attachment [ GL_STENCIL_ATTACHMENT ] }
  195. { color-attachment [ GL_COLOR_ATTACHMENT0 + ] }
  196. { system-attachment [ gl-system-attachment ] }
  197. { default-attachment [ dup (default-gl-attachment) ] }
  198. } match ] [ GL_NONE ] if* nip ;
  199. : color-attachment-image-type ( framebuffer attachment-ref -- order type )
  200. {
  201. { color-attachment [
  202. swap color-attachments>> nth
  203. attachment-object [ component-order>> ] [ component-type>> ] bi
  204. ] }
  205. { system-attachment [ 3drop RGBA ubyte-components ] }
  206. { default-attachment [ (default-attachment-image-type) ] }
  207. } match ;
  208. : framebuffer-rect-image-type ( framebuffer-rect -- order type )
  209. [ framebuffer>> ] [ attachment>> ] bi color-attachment-image-type ;
  210. HOOK: (clear-integer-color-attachment) gpu-api ( type value -- )
  211. M: opengl-2 (clear-integer-color-attachment)
  212. 4 0 pad-tail first4
  213. swap {
  214. { int-type [ glClearColorIiEXT ] }
  215. { uint-type [ glClearColorIuiEXT ] }
  216. } case GL_COLOR_BUFFER_BIT glClear ;
  217. M: opengl-3 (clear-integer-color-attachment)
  218. [ GL_COLOR 0 ] dip 4 0 pad-tail
  219. swap {
  220. { int-type [ int >c-array glClearBufferiv ] }
  221. { uint-type [ uint >c-array glClearBufferuiv ] }
  222. } case ;
  223. :: (clear-color-attachment) ( type attachment value -- )
  224. attachment glDrawBuffer
  225. type float-type =
  226. [ value 4 value last pad-tail first4 glClearColor GL_COLOR_BUFFER_BIT glClear ]
  227. [ type value (clear-integer-color-attachment) ] if ;
  228. : framebuffer-rect-size ( framebuffer-rect -- size )
  229. [ rect>> dim>> product ]
  230. [ framebuffer-rect-image-type (bytes-per-pixel) ] bi * ;
  231. PRIVATE>
  232. TYPED: <full-framebuffer-rect> ( framebuffer: any-framebuffer
  233. attachment: attachment-ref
  234. --
  235. framebuffer-rect: framebuffer-rect )
  236. 2dup framebuffer-attachment-at
  237. { 0 0 } swap framebuffer-attachment-dim <rect>
  238. <framebuffer-rect> ;
  239. TYPED: resize-framebuffer ( framebuffer: framebuffer dim -- )
  240. [ allocate-framebuffer-attachment ] curry each-attachment ;
  241. :: attach-framebuffer-attachments ( framebuffer -- )
  242. GL_DRAW_FRAMEBUFFER framebuffer handle>> glBindFramebuffer
  243. framebuffer [ bind-framebuffer-attachment ] each-attachment-target ; inline
  244. M: framebuffer dispose
  245. [ [ delete-framebuffer ] when* f ] change-handle drop ;
  246. TYPED: dispose-framebuffer-attachments ( framebuffer: framebuffer -- )
  247. [ [ dispose ] when* ] each-attachment ;
  248. : <framebuffer> ( color-attachments
  249. depth-attachment: framebuffer-attachment
  250. stencil-attachment: framebuffer-attachment
  251. dim
  252. --
  253. framebuffer: framebuffer )
  254. [ [ 0 ] 3dip framebuffer boa dup ] dip
  255. [ resize-framebuffer ] [ drop ] if*
  256. gen-framebuffer >>handle
  257. dup attach-framebuffer-attachments
  258. window-resource ;
  259. TYPED:: clear-framebuffer-attachment ( framebuffer: any-framebuffer
  260. attachment-ref: attachment-ref
  261. value -- )
  262. GL_DRAW_FRAMEBUFFER framebuffer framebuffer-handle glBindFramebuffer
  263. attachment-ref {
  264. { system-attachment [| side face |
  265. float-type
  266. side face gl-system-attachment
  267. value (clear-color-attachment)
  268. ] }
  269. { color-attachment [| i |
  270. framebuffer i (color-attachment-type)
  271. GL_COLOR_ATTACHMENT0 i +
  272. value (clear-color-attachment)
  273. ] }
  274. { default-attachment [
  275. framebuffer [ (default-attachment-type) ] [ (default-gl-attachment) ] bi
  276. value (clear-color-attachment)
  277. ] }
  278. { depth-attachment [ value glClearDepth GL_DEPTH_BUFFER_BIT glClear ] }
  279. { stencil-attachment [ value glClearStencil GL_STENCIL_BUFFER_BIT glClear ] }
  280. } match ;
  281. : clear-framebuffer ( framebuffer alist -- )
  282. [ first2 clear-framebuffer-attachment ] with each ; inline
  283. TYPED:: read-framebuffer-to ( framebuffer-rect: framebuffer-rect
  284. gpu-data-ptr -- )
  285. GL_READ_FRAMEBUFFER framebuffer-rect framebuffer>> framebuffer-handle glBindFramebuffer
  286. framebuffer-rect [ framebuffer>> ] [ attachment>> ] bi gl-attachment glReadBuffer
  287. framebuffer-rect rect>> [ loc>> first2 ] [ dim>> first2 ] bi
  288. framebuffer-rect framebuffer-rect-image-type image-data-format
  289. gpu-data-ptr pixel-pack-buffer [ glReadPixels ] with-gpu-data-ptr ;
  290. : read-framebuffer ( framebuffer-rect -- byte-array )
  291. dup framebuffer-rect-size <byte-array> [ read-framebuffer-to ] keep ; inline
  292. TYPED: read-framebuffer-image ( framebuffer-rect -- image )
  293. [ <image> ] dip {
  294. [ rect>> dim>> >>dim ]
  295. [
  296. framebuffer-rect-image-type
  297. [ >>component-order ] [ >>component-type ] bi*
  298. ]
  299. [ read-framebuffer >>bitmap ]
  300. } cleave ;
  301. TYPED:: copy-framebuffer ( to-fb-rect: framebuffer-rect
  302. from-fb-rect: framebuffer-rect
  303. depth? stencil? filter: texture-filter -- )
  304. GL_DRAW_FRAMEBUFFER to-fb-rect framebuffer>> framebuffer-handle glBindFramebuffer
  305. to-fb-rect [ framebuffer>> ] [ attachment>> ] bi gl-attachment glDrawBuffer
  306. GL_READ_FRAMEBUFFER from-fb-rect framebuffer>> framebuffer-handle glBindFramebuffer
  307. from-fb-rect [ framebuffer>> ] [ attachment>> ] bi gl-attachment glReadBuffer
  308. to-fb-rect attachment>> [ GL_COLOR_BUFFER_BIT ] [ 0 ] if
  309. depth? [ GL_DEPTH_BUFFER_BIT ] [ 0 ] if bitor
  310. stencil? [ GL_STENCIL_BUFFER_BIT ] [ 0 ] if bitor :> mask
  311. from-fb-rect rect>> rect-extent [ first2 ] bi@
  312. to-fb-rect rect>> rect-extent [ first2 ] bi@
  313. mask filter gl-mag-filter glBlitFramebuffer ;