643 lines
24 KiB
Factor
643 lines
24 KiB
Factor
! Copyright (C) 2009 Joe Groff.
|
|
! See http://factorcode.org/license.txt for BSD license.
|
|
USING: accessors alien alien.c-types alien.data arrays
|
|
assocs classes classes.mixin classes.parser classes.singleton classes.struct
|
|
classes.tuple classes.tuple.private combinators combinators.tuple destructors fry
|
|
generic generic.parser gpu gpu.buffers gpu.framebuffers
|
|
gpu.framebuffers.private gpu.shaders gpu.shaders.private gpu.state
|
|
gpu.textures gpu.textures.private math.floats.half images kernel
|
|
lexer locals math math.order math.parser namespaces opengl
|
|
opengl.gl parser quotations sequences slots sorting
|
|
specialized-arrays strings ui.gadgets.worlds variants
|
|
vocabs.parser words math.vectors.simd ;
|
|
FROM: math => float ;
|
|
QUALIFIED-WITH: alien.c-types c
|
|
SPECIALIZED-ARRAYS: c:float c:int c:uchar c:ushort c:uint c:void* ;
|
|
IN: gpu.render
|
|
|
|
VARIANT: uniform-type
|
|
bool-uniform
|
|
bvec2-uniform
|
|
bvec3-uniform
|
|
bvec4-uniform
|
|
uint-uniform
|
|
uvec2-uniform
|
|
uvec3-uniform
|
|
uvec4-uniform
|
|
int-uniform
|
|
ivec2-uniform
|
|
ivec3-uniform
|
|
ivec4-uniform
|
|
float-uniform
|
|
vec2-uniform
|
|
vec3-uniform
|
|
vec4-uniform
|
|
|
|
mat2-uniform
|
|
mat2x3-uniform
|
|
mat2x4-uniform
|
|
|
|
mat3x2-uniform
|
|
mat3-uniform
|
|
mat3x4-uniform
|
|
|
|
mat4x2-uniform
|
|
mat4x3-uniform
|
|
mat4-uniform
|
|
|
|
texture-uniform ;
|
|
|
|
ALIAS: mat2x2-uniform mat2-uniform
|
|
ALIAS: mat3x3-uniform mat3-uniform
|
|
ALIAS: mat4x4-uniform mat4-uniform
|
|
|
|
TUPLE: uniform
|
|
{ name string read-only initial: "" }
|
|
{ uniform-type class read-only initial: float-uniform }
|
|
{ dim maybe{ integer } read-only initial: f } ;
|
|
|
|
VARIANT: index-type
|
|
ubyte-indexes
|
|
ushort-indexes
|
|
uint-indexes ;
|
|
|
|
TUPLE: index-range
|
|
{ start integer read-only }
|
|
{ count integer read-only } ;
|
|
|
|
C: <index-range> index-range
|
|
|
|
TUPLE: multi-index-range
|
|
{ starts uint-array read-only }
|
|
{ counts uint-array read-only } ;
|
|
|
|
C: <multi-index-range> multi-index-range
|
|
|
|
TUPLE: index-elements
|
|
{ ptr read-only }
|
|
{ count integer read-only }
|
|
{ index-type index-type read-only } ;
|
|
|
|
C: <index-elements> index-elements
|
|
|
|
TUPLE: multi-index-elements
|
|
{ buffer maybe{ buffer } read-only }
|
|
{ ptrs read-only }
|
|
{ counts uint-array read-only }
|
|
{ index-type index-type read-only } ;
|
|
|
|
C: <multi-index-elements> multi-index-elements
|
|
|
|
UNION: vertex-indexes
|
|
index-range
|
|
multi-index-range
|
|
index-elements
|
|
multi-index-elements
|
|
uchar-array
|
|
ushort-array
|
|
uint-array ;
|
|
|
|
VARIANT: primitive-mode
|
|
points-mode
|
|
lines-mode
|
|
line-strip-mode
|
|
lines-with-adjacency-mode
|
|
line-strip-with-adjacency-mode
|
|
line-loop-mode
|
|
triangles-mode
|
|
triangle-strip-mode
|
|
triangles-with-adjacency-mode
|
|
triangle-strip-with-adjacency-mode
|
|
triangle-fan-mode ;
|
|
|
|
TUPLE: uniform-tuple ;
|
|
|
|
ERROR: invalid-uniform-type uniform ;
|
|
|
|
<PRIVATE
|
|
|
|
: gl-index-type ( index-type -- gl-index-type )
|
|
{
|
|
{ ubyte-indexes [ GL_UNSIGNED_BYTE ] }
|
|
{ ushort-indexes [ GL_UNSIGNED_SHORT ] }
|
|
{ uint-indexes [ GL_UNSIGNED_INT ] }
|
|
} case ; inline
|
|
|
|
: gl-primitive-mode ( primitive-mode -- gl-primitive-mode )
|
|
{
|
|
{ points-mode [ GL_POINTS ] }
|
|
{ lines-mode [ GL_LINES ] }
|
|
{ line-strip-mode [ GL_LINE_STRIP ] }
|
|
{ line-loop-mode [ GL_LINE_LOOP ] }
|
|
{ triangles-mode [ GL_TRIANGLES ] }
|
|
{ triangle-strip-mode [ GL_TRIANGLE_STRIP ] }
|
|
{ triangle-fan-mode [ GL_TRIANGLE_FAN ] }
|
|
{ lines-with-adjacency-mode [ GL_LINES_ADJACENCY ] }
|
|
{ line-strip-with-adjacency-mode [ GL_LINE_STRIP_ADJACENCY ] }
|
|
{ triangles-with-adjacency-mode [ GL_TRIANGLES_ADJACENCY ] }
|
|
{ triangle-strip-with-adjacency-mode [ GL_TRIANGLE_STRIP_ADJACENCY ] }
|
|
} case ; inline
|
|
|
|
GENERIC: render-vertex-indexes ( primitive-mode vertex-indexes -- )
|
|
|
|
GENERIC#: render-vertex-indexes-instanced 1 ( primitive-mode vertex-indexes instances -- )
|
|
|
|
GENERIC: gl-array-element-type ( array -- type )
|
|
M: uchar-array gl-array-element-type drop GL_UNSIGNED_BYTE ; inline
|
|
M: ushort-array gl-array-element-type drop GL_UNSIGNED_SHORT ; inline
|
|
M: uint-array gl-array-element-type drop GL_UNSIGNED_INT ; inline
|
|
|
|
M: index-range render-vertex-indexes
|
|
[ gl-primitive-mode ] [ [ start>> ] [ count>> ] bi ] bi* glDrawArrays ;
|
|
|
|
M: index-range render-vertex-indexes-instanced
|
|
[ gl-primitive-mode ] [ [ start>> ] [ count>> ] bi ] [ ] tri*
|
|
glDrawArraysInstanced ;
|
|
|
|
M: multi-index-range render-vertex-indexes
|
|
[ gl-primitive-mode ] [ [ starts>> ] [ counts>> dup length ] bi ] bi*
|
|
glMultiDrawArrays ;
|
|
|
|
M: index-elements render-vertex-indexes
|
|
[ gl-primitive-mode ]
|
|
[ [ count>> ] [ index-type>> gl-index-type ] [ ptr>> ] tri ] bi*
|
|
index-buffer [ glDrawElements ] with-gpu-data-ptr ;
|
|
|
|
M: index-elements render-vertex-indexes-instanced
|
|
[ gl-primitive-mode ]
|
|
[ [ count>> ] [ index-type>> gl-index-type ] [ ptr>> ] tri ]
|
|
[ ] tri*
|
|
swap index-buffer [ swap glDrawElementsInstanced ] with-gpu-data-ptr ;
|
|
|
|
M: specialized-array render-vertex-indexes
|
|
GL_ELEMENT_ARRAY_BUFFER 0 glBindBuffer
|
|
[ gl-primitive-mode ]
|
|
[ [ length ] [ gl-array-element-type ] [ >c-ptr ] tri ] bi*
|
|
glDrawElements ;
|
|
|
|
M: specialized-array render-vertex-indexes-instanced
|
|
GL_ELEMENT_ARRAY_BUFFER 0 glBindBuffer
|
|
[ gl-primitive-mode ]
|
|
[ [ length ] [ gl-array-element-type ] [ >c-ptr ] tri ]
|
|
[ ] tri* glDrawElementsInstanced ;
|
|
|
|
M: multi-index-elements render-vertex-indexes
|
|
[ gl-primitive-mode ]
|
|
[ { [ counts>> ] [ index-type>> gl-index-type ] [ ptrs>> dup length ] [ buffer>> ] } cleave ]
|
|
bi*
|
|
GL_ELEMENT_ARRAY_BUFFER swap [ handle>> ] [ 0 ] if* glBindBuffer glMultiDrawElements ;
|
|
|
|
: (bind-texture-unit) ( texture texture-unit -- )
|
|
swap [ GL_TEXTURE0 + glActiveTexture ] [ bind-texture drop ] bi* ; inline
|
|
|
|
GENERIC: (bind-uniform-textures) ( program-instance uniform-tuple -- )
|
|
GENERIC: (bind-uniforms) ( program-instance uniform-tuple -- )
|
|
|
|
M: uniform-tuple (bind-uniform-textures)
|
|
2drop ;
|
|
M: uniform-tuple (bind-uniforms)
|
|
2drop ;
|
|
|
|
: uniform-slot-type ( uniform -- type )
|
|
dup dim>> [ drop sequence ] [
|
|
uniform-type>> {
|
|
{ bool-uniform [ boolean ] }
|
|
{ uint-uniform [ integer ] }
|
|
{ int-uniform [ integer ] }
|
|
{ float-uniform [ float ] }
|
|
{ texture-uniform [ texture ] }
|
|
[ drop sequence ]
|
|
} case
|
|
] if ;
|
|
|
|
: uniform>slot ( uniform -- slot )
|
|
[ name>> ] [ uniform-slot-type ] bi 2array ;
|
|
|
|
: uniform-type-texture-units ( uniform-type -- units )
|
|
dup texture-uniform = [ drop 1 ] [ "uniform-tuple-texture-units" word-prop 0 or ] if ;
|
|
|
|
: all-uniform-tuple-slots ( class -- slots )
|
|
dup "uniform-tuple-slots" word-prop
|
|
[ [ superclass-of all-uniform-tuple-slots ] dip append ] [ drop { } ] if* ;
|
|
|
|
DEFER: uniform-texture-accessors
|
|
|
|
: uniform-type-texture-accessors ( uniform-type -- accessors )
|
|
texture-uniform = [ { [ ] } ] [ { } ] if ;
|
|
|
|
: uniform-slot-texture-accessor ( uniform -- accessor )
|
|
[ name>> reader-word ] [ [ uniform-type>> ] [ dim>> ] bi uniform-texture-accessors ] bi
|
|
dup length 1 = [ first swap prefix ] [ [ ] 2sequence ] if ;
|
|
|
|
: uniform-tuple-texture-accessors ( uniform-type -- accessors )
|
|
all-uniform-tuple-slots [ uniform-type>> uniform-type-texture-units zero? ] reject
|
|
[ uniform-slot-texture-accessor ] map ;
|
|
|
|
: uniform-texture-accessors ( uniform-type dim -- accessors )
|
|
[
|
|
dup uniform-type?
|
|
[ uniform-type-texture-accessors ]
|
|
[ uniform-tuple-texture-accessors ] if
|
|
] [
|
|
2dup swap empty? not and [
|
|
<iota> [
|
|
[ swap nth ] swap prefix
|
|
over length 1 = [ swap first append ] [ swap suffix ] if
|
|
] with map
|
|
] [ drop ] if
|
|
] bi* ;
|
|
|
|
: texture-accessor>cleave ( unit accessors -- unit' cleaves )
|
|
dup last sequence?
|
|
[ [ last [ texture-accessor>cleave ] map ] [ but-last ] bi swap suffix \ cleave suffix ]
|
|
[ over suffix \ (bind-texture-unit) suffix [ 1 + ] dip ] if ;
|
|
|
|
: [bind-uniform-textures] ( class -- quot )
|
|
f uniform-texture-accessors
|
|
0 swap [ texture-accessor>cleave ] map nip
|
|
\ nip swap \ cleave [ ] 3sequence ;
|
|
|
|
UNION: binary-data
|
|
c-ptr specialized-array struct simd-128 ;
|
|
|
|
GENERIC: >uniform-bool-array ( sequence -- c-array )
|
|
GENERIC: >uniform-int-array ( sequence -- c-array )
|
|
GENERIC: >uniform-uint-array ( sequence -- c-array )
|
|
GENERIC: >uniform-float-array ( sequence -- c-array )
|
|
|
|
GENERIC#: >uniform-bvec-array 1 ( sequence dim -- c-array )
|
|
GENERIC#: >uniform-ivec-array 1 ( sequence dim -- c-array )
|
|
GENERIC#: >uniform-uvec-array 1 ( sequence dim -- c-array )
|
|
GENERIC#: >uniform-vec-array 1 ( sequence dim -- c-array )
|
|
|
|
GENERIC#: >uniform-matrix 2 ( sequence cols rows -- c-array )
|
|
|
|
GENERIC#: >uniform-matrix-array 2 ( sequence cols rows -- c-array )
|
|
|
|
GENERIC: bind-uniform-bvec2 ( index sequence -- )
|
|
GENERIC: bind-uniform-bvec3 ( index sequence -- )
|
|
GENERIC: bind-uniform-bvec4 ( index sequence -- )
|
|
GENERIC: bind-uniform-ivec2 ( index sequence -- )
|
|
GENERIC: bind-uniform-ivec3 ( index sequence -- )
|
|
GENERIC: bind-uniform-ivec4 ( index sequence -- )
|
|
GENERIC: bind-uniform-uvec2 ( index sequence -- )
|
|
GENERIC: bind-uniform-uvec3 ( index sequence -- )
|
|
GENERIC: bind-uniform-uvec4 ( index sequence -- )
|
|
GENERIC: bind-uniform-vec2 ( index sequence -- )
|
|
GENERIC: bind-uniform-vec3 ( index sequence -- )
|
|
GENERIC: bind-uniform-vec4 ( index sequence -- )
|
|
|
|
M: object >uniform-bool-array [ >c-bool ] int-array{ } map-as ; inline
|
|
M: binary-data >uniform-bool-array ; inline
|
|
|
|
M: object >uniform-int-array c:int >c-array ; inline
|
|
M: binary-data >uniform-int-array ; inline
|
|
|
|
M: object >uniform-uint-array c:uint >c-array ; inline
|
|
M: binary-data >uniform-uint-array ; inline
|
|
|
|
M: object >uniform-float-array c:float >c-array ; inline
|
|
M: binary-data >uniform-float-array ; inline
|
|
|
|
M: object >uniform-bvec-array '[ _ head-slice [ >c-bool ] int-array{ } map-as ] map concat ; inline
|
|
M: binary-data >uniform-bvec-array drop ; inline
|
|
|
|
M: object >uniform-ivec-array '[ _ head ] map int-array{ } concat-as ; inline
|
|
M: binary-data >uniform-ivec-array drop ; inline
|
|
|
|
M: object >uniform-uvec-array '[ _ head ] map uint-array{ } concat-as ; inline
|
|
M: binary-data >uniform-uvec-array drop ; inline
|
|
|
|
M: object >uniform-vec-array '[ _ head ] map float-array{ } concat-as ; inline
|
|
M: binary-data >uniform-vec-array drop ; inline
|
|
|
|
M:: object >uniform-matrix ( sequence cols rows -- c-array )
|
|
sequence flip cols head-slice
|
|
[ rows head-slice c:float >c-array ] { } map-as concat ; inline
|
|
M: binary-data >uniform-matrix 2drop ; inline
|
|
|
|
M: object >uniform-matrix-array
|
|
'[ _ _ >uniform-matrix ] map concat ; inline
|
|
M: binary-data >uniform-matrix-array 2drop ; inline
|
|
|
|
M: object bind-uniform-bvec2 ( index sequence -- )
|
|
1 swap 2 head-slice [ >c-bool ] int-array{ } map-as glUniform2iv ; inline
|
|
M: binary-data bind-uniform-bvec2 ( index sequence -- )
|
|
1 swap glUniform2iv ; inline
|
|
M: object bind-uniform-bvec3 ( index sequence -- )
|
|
1 swap 3 head-slice [ >c-bool ] int-array{ } map-as glUniform3iv ; inline
|
|
M: binary-data bind-uniform-bvec3 ( index sequence -- )
|
|
1 swap glUniform3iv ; inline
|
|
M: object bind-uniform-bvec4 ( index sequence -- )
|
|
1 swap 4 head-slice [ >c-bool ] int-array{ } map-as glUniform4iv ; inline
|
|
M: binary-data bind-uniform-bvec4 ( index sequence -- )
|
|
1 swap glUniform4iv ; inline
|
|
|
|
M: object bind-uniform-ivec2 ( index sequence -- ) first2 glUniform2i ; inline
|
|
M: binary-data bind-uniform-ivec2 ( index sequence -- ) 1 swap glUniform2iv ; inline
|
|
|
|
M: object bind-uniform-ivec3 ( index sequence -- ) first3 glUniform3i ; inline
|
|
M: binary-data bind-uniform-ivec3 ( index sequence -- ) 1 swap glUniform3iv ; inline
|
|
|
|
M: object bind-uniform-ivec4 ( index sequence -- ) first4 glUniform4i ; inline
|
|
M: binary-data bind-uniform-ivec4 ( index sequence -- ) 1 swap glUniform4iv ; inline
|
|
|
|
M: object bind-uniform-uvec2 ( index sequence -- ) first2 glUniform2ui ; inline
|
|
M: binary-data bind-uniform-uvec2 ( index sequence -- ) 1 swap glUniform2uiv ; inline
|
|
|
|
M: object bind-uniform-uvec3 ( index sequence -- ) first3 glUniform3ui ; inline
|
|
M: binary-data bind-uniform-uvec3 ( index sequence -- ) 1 swap glUniform3uiv ; inline
|
|
|
|
M: object bind-uniform-uvec4 ( index sequence -- ) first4 glUniform4ui ; inline
|
|
M: binary-data bind-uniform-uvec4 ( index sequence -- ) 1 swap glUniform4uiv ; inline
|
|
|
|
M: object bind-uniform-vec2 ( index sequence -- ) first2 glUniform2f ; inline
|
|
M: binary-data bind-uniform-vec2 ( index sequence -- ) 1 swap glUniform2fv ; inline
|
|
|
|
M: object bind-uniform-vec3 ( index sequence -- ) first3 glUniform3f ; inline
|
|
M: binary-data bind-uniform-vec3 ( index sequence -- ) 1 swap glUniform3fv ; inline
|
|
|
|
M: object bind-uniform-vec4 ( index sequence -- ) first4 glUniform4f ; inline
|
|
M: binary-data bind-uniform-vec4 ( index sequence -- ) 1 swap glUniform4fv ; inline
|
|
|
|
DEFER: [bind-uniform-tuple]
|
|
|
|
:: [bind-uniform-array] ( value>>-quot type texture-unit name dim -- texture-unit' quot )
|
|
{ name uniform-index } >quotation :> index-quot
|
|
{ index-quot value>>-quot bi* } >quotation :> pre-quot
|
|
|
|
type H{
|
|
{ bool-uniform { dim swap >uniform-bool-array glUniform1iv } }
|
|
{ int-uniform { dim swap >uniform-int-array glUniform1iv } }
|
|
{ uint-uniform { dim swap >uniform-uint-array glUniform1uiv } }
|
|
{ float-uniform { dim swap >uniform-float-array glUniform1fv } }
|
|
|
|
{ bvec2-uniform { dim swap 2 >uniform-bvec-array glUniform2iv } }
|
|
{ ivec2-uniform { dim swap 2 >uniform-ivec-array glUniform2i } }
|
|
{ uvec2-uniform { dim swap 2 >uniform-uvec-array glUniform2ui } }
|
|
{ vec2-uniform { dim swap 2 >uniform-vec-array glUniform2f } }
|
|
|
|
{ bvec3-uniform { dim swap 3 >uniform-bvec-array glUniform3iv } }
|
|
{ ivec3-uniform { dim swap 3 >uniform-ivec-array glUniform3i } }
|
|
{ uvec3-uniform { dim swap 3 >uniform-uvec-array glUniform3ui } }
|
|
{ vec3-uniform { dim swap 3 >uniform-vec-array glUniform3f } }
|
|
|
|
{ bvec4-uniform { dim swap 4 >uniform-bvec-array glUniform4iv } }
|
|
{ ivec4-uniform { dim swap 4 >uniform-ivec-array glUniform4iv } }
|
|
{ uvec4-uniform { dim swap 4 >uniform-uvec-array glUniform4uiv } }
|
|
{ vec4-uniform { dim swap 4 >uniform-vec-array glUniform4fv } }
|
|
|
|
{ mat2-uniform { [ dim 0 ] dip 2 2 >uniform-matrix-array glUniformMatrix2fv } }
|
|
{ mat2x3-uniform { [ dim 0 ] dip 2 3 >uniform-matrix-array glUniformMatrix2x3fv } }
|
|
{ mat2x4-uniform { [ dim 0 ] dip 2 4 >uniform-matrix-array glUniformMatrix2x4fv } }
|
|
|
|
{ mat3x2-uniform { [ dim 0 ] dip 3 2 >uniform-matrix-array glUniformMatrix3x2fv } }
|
|
{ mat3-uniform { [ dim 0 ] dip 3 3 >uniform-matrix-array glUniformMatrix3fv } }
|
|
{ mat3x4-uniform { [ dim 0 ] dip 3 4 >uniform-matrix-array glUniformMatrix3x4fv } }
|
|
|
|
{ mat4x2-uniform { [ dim 0 ] dip 4 2 >uniform-matrix-array glUniformMatrix4x2fv } }
|
|
{ mat4x3-uniform { [ dim 0 ] dip 4 3 >uniform-matrix-array glUniformMatrix4x3fv } }
|
|
{ mat4-uniform { [ dim 0 ] dip 4 4 >uniform-matrix-array glUniformMatrix4fv } }
|
|
|
|
{ texture-uniform { drop dim dup <iota> [ texture-unit + ] int-array{ } map-as glUniform1iv } }
|
|
} at [ uniform invalid-uniform-type ] unless* >quotation :> value-quot
|
|
|
|
type uniform-type-texture-units dim * texture-unit +
|
|
pre-quot value-quot append ;
|
|
|
|
:: [bind-uniform-value] ( value>>-quot type texture-unit name -- texture-unit' quot )
|
|
{ name uniform-index } >quotation :> index-quot
|
|
{ index-quot value>>-quot bi* } >quotation :> pre-quot
|
|
|
|
type H{
|
|
{ bool-uniform [ >c-bool glUniform1i ] }
|
|
{ int-uniform [ glUniform1i ] }
|
|
{ uint-uniform [ glUniform1ui ] }
|
|
{ float-uniform [ glUniform1f ] }
|
|
|
|
{ bvec2-uniform [ bind-uniform-bvec2 ] }
|
|
{ ivec2-uniform [ bind-uniform-ivec2 ] }
|
|
{ uvec2-uniform [ bind-uniform-uvec2 ] }
|
|
{ vec2-uniform [ bind-uniform-vec2 ] }
|
|
|
|
{ bvec3-uniform [ bind-uniform-bvec3 ] }
|
|
{ ivec3-uniform [ bind-uniform-ivec3 ] }
|
|
{ uvec3-uniform [ bind-uniform-uvec3 ] }
|
|
{ vec3-uniform [ bind-uniform-vec3 ] }
|
|
|
|
{ bvec4-uniform [ bind-uniform-bvec4 ] }
|
|
{ ivec4-uniform [ bind-uniform-ivec4 ] }
|
|
{ uvec4-uniform [ bind-uniform-uvec4 ] }
|
|
{ vec4-uniform [ bind-uniform-vec4 ] }
|
|
|
|
{ mat2-uniform [ [ 1 0 ] dip 2 2 >uniform-matrix glUniformMatrix2fv ] }
|
|
{ mat2x3-uniform [ [ 1 0 ] dip 2 3 >uniform-matrix glUniformMatrix2x3fv ] }
|
|
{ mat2x4-uniform [ [ 1 0 ] dip 2 4 >uniform-matrix glUniformMatrix2x4fv ] }
|
|
|
|
{ mat3x2-uniform [ [ 1 0 ] dip 3 2 >uniform-matrix glUniformMatrix3x2fv ] }
|
|
{ mat3-uniform [ [ 1 0 ] dip 3 3 >uniform-matrix glUniformMatrix3fv ] }
|
|
{ mat3x4-uniform [ [ 1 0 ] dip 3 4 >uniform-matrix glUniformMatrix3x4fv ] }
|
|
|
|
{ mat4x2-uniform [ [ 1 0 ] dip 4 2 >uniform-matrix glUniformMatrix4x2fv ] }
|
|
{ mat4x3-uniform [ [ 1 0 ] dip 4 3 >uniform-matrix glUniformMatrix4x3fv ] }
|
|
{ mat4-uniform [ [ 1 0 ] dip 4 4 >uniform-matrix glUniformMatrix4fv ] }
|
|
|
|
{ texture-uniform { drop texture-unit glUniform1i } }
|
|
} at [ uniform invalid-uniform-type ] unless* >quotation :> value-quot
|
|
|
|
type uniform-type-texture-units texture-unit +
|
|
pre-quot value-quot append ;
|
|
|
|
:: [bind-uniform-struct] ( value>>-quot type texture-unit name dim -- texture-unit' quot )
|
|
dim
|
|
[
|
|
<iota>
|
|
[ [ [ swap nth ] swap prefix ] map ]
|
|
[ [ number>string name "[" append "]." surround ] map ] bi
|
|
] [
|
|
{ [ ] }
|
|
name "." append 1array
|
|
] if* :> ( quot-prefixes name-prefixes )
|
|
type all-uniform-tuple-slots :> uniforms
|
|
|
|
texture-unit quot-prefixes name-prefixes [| quot-prefix name-prefix |
|
|
uniforms name-prefix [bind-uniform-tuple]
|
|
quot-prefix prepend
|
|
] 2map :> ( texture-unit' value-cleave )
|
|
|
|
texture-unit'
|
|
value>>-quot { value-cleave 2cleave } append ;
|
|
|
|
:: [bind-uniform] ( texture-unit uniform prefix -- texture-unit' quot )
|
|
prefix uniform name>> append hyphens>underscores :> name
|
|
uniform uniform-type>> :> type
|
|
uniform dim>> :> dim
|
|
uniform name>> reader-word 1quotation :> value>>-quot
|
|
|
|
value>>-quot type texture-unit name {
|
|
{ [ type uniform-type? dim and ] [ dim [bind-uniform-array] ] }
|
|
{ [ type uniform-type? dim not and ] [ [bind-uniform-value] ] }
|
|
[ dim [bind-uniform-struct] ]
|
|
} cond ;
|
|
|
|
:: [bind-uniform-tuple] ( texture-unit uniforms prefix -- texture-unit' quot )
|
|
texture-unit uniforms [ prefix [bind-uniform] ] map :> ( texture-unit' uniforms-cleave )
|
|
|
|
texture-unit'
|
|
{ uniforms-cleave 2cleave } >quotation ;
|
|
|
|
:: [bind-uniforms] ( superclass uniforms -- quot )
|
|
superclass "uniform-tuple-texture-units" word-prop 0 or :> first-texture-unit
|
|
superclass \ (bind-uniforms) lookup-method :> next-method
|
|
first-texture-unit uniforms "" [bind-uniform-tuple] nip :> bind-quot
|
|
|
|
{ 2dup next-method } bind-quot [ ] append-as ;
|
|
|
|
: define-uniform-tuple-methods ( class superclass uniforms -- )
|
|
[
|
|
2drop
|
|
[ \ (bind-uniform-textures) create-method-in ]
|
|
[ [bind-uniform-textures] ] bi define
|
|
] [
|
|
[ \ (bind-uniforms) create-method-in ] 2dip
|
|
[bind-uniforms] define
|
|
] 3bi ;
|
|
|
|
: parse-uniform-tuple-definition ( -- class superclass uniforms )
|
|
scan-new-class scan-token {
|
|
{ ";" [ uniform-tuple f ] }
|
|
{ "<" [ scan-word parse-array-def [ first3 uniform boa ] map ] }
|
|
{ "{" [
|
|
uniform-tuple
|
|
\ } parse-until parse-array-def swap prefix
|
|
[ first3 uniform boa ] map
|
|
] }
|
|
} case ;
|
|
|
|
: (define-uniform-tuple) ( class superclass uniforms -- )
|
|
{
|
|
[ [ uniform>slot ] map define-tuple-class ]
|
|
[
|
|
[ uniform-type-texture-units ]
|
|
[
|
|
[ [ uniform-type>> uniform-type-texture-units ] [ dim>> 1 or ] bi * ]
|
|
[ + ] map-reduce
|
|
] bi* +
|
|
"uniform-tuple-texture-units" set-word-prop
|
|
]
|
|
[ nip "uniform-tuple-slots" set-word-prop ]
|
|
[ define-uniform-tuple-methods ]
|
|
} 3cleave ;
|
|
|
|
: true-subclasses ( class -- seq )
|
|
[ subclasses ] keep [ = ] curry reject ;
|
|
|
|
PRIVATE>
|
|
|
|
: define-uniform-tuple ( class superclass uniforms -- )
|
|
(define-uniform-tuple) ; inline
|
|
|
|
SYNTAX: UNIFORM-TUPLE:
|
|
parse-uniform-tuple-definition define-uniform-tuple ;
|
|
|
|
<PRIVATE
|
|
|
|
: bind-unnamed-output-attachments ( framebuffer attachments -- )
|
|
[ gl-attachment ] with map
|
|
dup length 1 =
|
|
[ first glDrawBuffer ]
|
|
[ [ length ] [ c:int >c-array ] bi glDrawBuffers ] if ;
|
|
|
|
: bind-named-output-attachments ( program-instance framebuffer attachments -- )
|
|
rot '[ first _ swap output-index ] sort-with values
|
|
bind-unnamed-output-attachments ;
|
|
|
|
: bind-output-attachments ( program-instance framebuffer attachments -- )
|
|
dup first sequence?
|
|
[ bind-named-output-attachments ] [ nipd bind-unnamed-output-attachments ] if ;
|
|
|
|
GENERIC: bind-transform-feedback-output ( output -- )
|
|
|
|
M: buffer bind-transform-feedback-output
|
|
[ GL_TRANSFORM_FEEDBACK_BUFFER 0 ] dip handle>> glBindBufferBase ; inline
|
|
|
|
M: buffer-range bind-transform-feedback-output
|
|
[ GL_TRANSFORM_FEEDBACK_BUFFER 0 ] dip
|
|
[ handle>> ] [ offset>> ] [ size>> ] tri glBindBufferRange ; inline
|
|
|
|
M: buffer-ptr bind-transform-feedback-output
|
|
buffer-ptr>range bind-transform-feedback-output ; inline
|
|
|
|
: gl-feedback-primitive-mode ( primitive-mode -- gl-mode )
|
|
{
|
|
{ points-mode [ GL_POINTS ] }
|
|
{ lines-mode [ GL_LINES ] }
|
|
{ line-strip-mode [ GL_LINES ] }
|
|
{ line-loop-mode [ GL_LINES ] }
|
|
{ triangles-mode [ GL_TRIANGLES ] }
|
|
{ triangle-strip-mode [ GL_TRIANGLES ] }
|
|
{ triangle-fan-mode [ GL_TRIANGLES ] }
|
|
} case ;
|
|
|
|
PRIVATE>
|
|
|
|
UNION: transform-feedback-output buffer buffer-range POSTPONE: f ;
|
|
|
|
TUPLE: render-set
|
|
{ primitive-mode primitive-mode read-only }
|
|
{ vertex-array vertex-array initial: T{ vertex-array-collection } read-only }
|
|
{ uniforms uniform-tuple read-only }
|
|
{ indexes vertex-indexes initial: T{ index-range } read-only }
|
|
{ instances maybe{ integer } initial: f read-only }
|
|
{ framebuffer maybe{ any-framebuffer } initial: system-framebuffer read-only }
|
|
{ output-attachments sequence initial: { default-attachment } read-only }
|
|
{ transform-feedback-output transform-feedback-output initial: f read-only } ;
|
|
|
|
: <render-set> ( x quot-assoc -- render-set )
|
|
render-set swap make-tuple ; inline
|
|
|
|
: 2<render-set> ( x y quot-assoc -- render-set )
|
|
render-set swap 2make-tuple ; inline
|
|
|
|
: 3<render-set> ( x y z quot-assoc -- render-set )
|
|
render-set swap 3make-tuple ; inline
|
|
|
|
: bind-uniforms ( program-instance uniforms -- )
|
|
[ (bind-uniform-textures) ] [ (bind-uniforms) ] 2bi ; inline
|
|
|
|
: render ( render-set -- )
|
|
{
|
|
[ vertex-array>> program-instance>> handle>> glUseProgram ]
|
|
[
|
|
[ vertex-array>> program-instance>> ] [ uniforms>> ] bi
|
|
bind-uniforms
|
|
]
|
|
[
|
|
framebuffer>>
|
|
[ GL_DRAW_FRAMEBUFFER swap framebuffer-handle glBindFramebuffer ]
|
|
[ GL_DRAW_FRAMEBUFFER 0 glBindFramebuffer GL_RASTERIZER_DISCARD glEnable ] if*
|
|
]
|
|
[
|
|
[ vertex-array>> program-instance>> ]
|
|
[ framebuffer>> ]
|
|
[ output-attachments>> ] tri
|
|
bind-output-attachments
|
|
]
|
|
[ vertex-array>> bind-vertex-array ]
|
|
[
|
|
dup transform-feedback-output>> [
|
|
[ primitive-mode>> gl-feedback-primitive-mode glBeginTransformFeedback ]
|
|
[ bind-transform-feedback-output ] bi*
|
|
] [ drop ] if*
|
|
]
|
|
|
|
[
|
|
[ primitive-mode>> ] [ indexes>> ] [ instances>> ] tri
|
|
[ render-vertex-indexes-instanced ]
|
|
[ render-vertex-indexes ] if*
|
|
]
|
|
|
|
[ transform-feedback-output>> [ glEndTransformFeedback ] when ]
|
|
[ framebuffer>> [ GL_RASTERIZER_DISCARD glDisable ] unless ]
|
|
} cleave ; inline
|