move vertex-formats and vertex-arrays to gpu.shaders so we can use them for transform feedback formats

db4
Joe Groff 2009-07-25 11:30:59 -05:00
parent f034be3c9e
commit 33395eeabd
5 changed files with 280 additions and 240 deletions

View File

@ -34,13 +34,6 @@ HELP: <multi-index-range>
}
{ $description "Constructs a " { $link multi-index-range } " tuple." } ;
HELP: <vertex-array>
{ $values
{ "program-instance" program-instance } { "vertex-formats" "a list of " { $link buffer-ptr } "/" { $link vertex-format } " pairs" }
{ "vertex-array" vertex-array }
}
{ $description "Creates a new " { $link vertex-array } " to feed data to " { $snippet "program-instance" } " from the set of " { $link buffer } "s specified in " { $snippet "vertex-formats" } "." } ;
HELP: UNIFORM-TUPLE:
{ $syntax <" UNIFORM-TUPLE: class-name
{ "slot" uniform-type dimension }
@ -78,30 +71,9 @@ $nl
"A value of a uniform tuple type is a standard Factor tuple. Uniform tuples are constructed with " { $link new } " or " { $link boa } ", and values are placed inside them using standard slot accessors."
} ;
HELP: VERTEX-FORMAT:
{ $syntax <" VERTEX-FORMAT: format-name
{ "attribute"/f component-type dimension normalize? }
{ "attribute"/f component-type dimension normalize? }
...
{ "attribute"/f component-type dimension normalize? } ; "> }
{ $description "Defines a new binary " { $link vertex-format } " for structuring vertex data stored in " { $link buffer } "s. Each " { $snippet "attribute" } " name either corresponds to an input parameter of a vertex shader, or is " { $link f } " to include padding in the vertex format. The " { $link component-type } " determines the format of the components, and the " { $snippet "dimension" } " determines the number of components. If the " { $snippet "component-type" } " is an integer type and " { $snippet "normalize?" } " is true, the component values will be scaled to the range 0.0 to 1.0 when fed to the vertex shader; otherwise, they will be cast to floats retaining their integral values." } ;
HELP: VERTEX-STRUCT:
{ $syntax <" VERTEX-STRUCT: struct-name format-name "> }
{ $description "Defines a struct C type (like " { $link POSTPONE: C-STRUCT: } ") with the same binary format and component types as the given " { $link vertex-format } "." } ;
HELP: bool-uniform
{ $class-description "This " { $link uniform-type } " indicates that a slot of a " { $link uniform-tuple } " corresponds to a boolean uniform parameter." } ;
HELP: buffer>vertex-array
{ $values
{ "vertex-buffer" buffer } { "program-instance" program-instance } { "format" vertex-format }
{ "vertex-array" vertex-array }
}
{ $description "Creates a new " { $link vertex-array } " from the entire contents of a single " { $link buffer } " in a single " { $link vertex-format } " for use with " { $snippet "program-instance" } "." } ;
{ vertex-array <vertex-array> buffer>vertex-array } related-words
HELP: bvec2-uniform
{ $class-description "This " { $link uniform-type } " indicates that a slot of a " { $link uniform-tuple } " corresponds to a two-component boolean vector uniform parameter." } ;
@ -117,18 +89,6 @@ HELP: define-uniform-tuple
}
{ $description "Defines a new " { $link uniform-tuple } " as a subclass of " { $snippet "superclass" } " with the slots specified by the " { $link uniform } " tuple values in " { $snippet "uniforms" } ". The runtime equivalent of " { $link POSTPONE: UNIFORM-TUPLE: } ". This word must be called inside a compilation unit." } ;
HELP: define-vertex-format
{ $values
{ "class" class } { "vertex-attributes" sequence }
}
{ $description "Defines a new " { $link vertex-format } " with the binary format specified by the " { $link vertex-attribute } " tuple values in " { $snippet "vertex-attributes" } ". The runtime equivalent of " { $link POSTPONE: VERTEX-FORMAT: } ". This word must be called inside a compilation unit." } ;
HELP: define-vertex-struct
{ $values
{ "struct-name" string } { "vertex-format" vertex-format }
}
{ $description "Defines a new struct C type from a " { $link vertex-format } ". The runtime equivalent of " { $link POSTPONE: VERTEX-STRUCT: } ". This word must be called inside a compilation unit." } ;
HELP: float-uniform
{ $class-description "This " { $link uniform-type } " indicates that a slot of a " { $link uniform-tuple } " corresponds to a float uniform parameter." } ;
@ -254,9 +214,10 @@ HELP: render-set
{ "The " { $snippet "uniforms" } " slot contains a " { $link uniform-tuple } " with values for the shader program's uniform parameters." }
{ "The " { $snippet "indexes" } " slot contains one of the " { $link vertex-indexes } " types and selects elements from the vertex array to be rendered." }
{ "The " { $snippet "instances" } " slot, if not " { $link f } ", instructs the GPU to render several instances of the same set of vertexes. Instancing requires OpenGL 3.1 or one of the " { $snippet "GL_EXT_draw_instanced" } " or " { $snippet "GL_ARB_draw_instanced" } " extensions." }
{ "The " { $snippet "framebuffer" } " slot determines the target for the rendering output. Either the " { $link system-framebuffer } " or a user-created " { $link framebuffer } " object can be specified. User-created framebuffers require OpenGL 3.0 or one of the " { $snippet "GL_EXT_framebuffer_object" } " or " { $snippet "GL_ARB_framebuffer_object" } " extensions." }
{ "The " { $snippet "output-attachments" } " slot specifies which of the framebuffer's " { $link color-attachment-ref } "s to write the fragment shader's color output to. If the shader uses " { $snippet "gl_FragColor" } " or " { $snippet "gl_FragData[n]" } " to write its output, then " { $snippet "output-attachments" } " should be an array of " { $link color-attachment-ref } "s, and the output to color attachment binding is determined positionally. If the shader uses named output values, then " { $snippet "output-attachments" } " should be a list of string/" { $link color-attachment-ref } " pairs, mapping output names to color attachments. Named output values are available in GLSL 1.30 or later, and GLSL 1.20 and earlier using the " { $snippet "GL_EXT_gpu_shader4" } " extension." }
} } ;
{ "The " { $snippet "framebuffer" } " slot determines the target for the rendering output. Either the " { $link system-framebuffer } " or a user-created " { $link framebuffer } " object can be specified. " { $link f } " can also be specified to disable rasterization and only run the vertex transformation rendering stage." }
{ "The " { $snippet "output-attachments" } " slot specifies which of the framebuffer's " { $link color-attachment-ref } "s to write the fragment shader's color output to. If the shader uses " { $snippet "gl_FragColor" } " or " { $snippet "gl_FragData[n]" } " to write its output, then " { $snippet "output-attachments" } " should be an array of " { $link color-attachment-ref } "s, and the output to color attachment binding is determined positionally. If the shader uses named output values, then " { $snippet "output-attachments" } " should be a list of string/" { $link color-attachment-ref } " pairs, mapping output names to color attachments." }
} }
{ $notes "User-created framebuffers require OpenGL 3.0 or one of the " { $snippet "GL_EXT_framebuffer_object" } " or " { $snippet "GL_ARB_framebuffer_object" } " extensions. Disabling rasterization requires OpenGL 3.0 or the " { $snippet "GL_EXT_transform_feedback" } " extension. Named output-attachment values are available in GLSL 1.30 or later, and GLSL 1.20 and earlier using the " { $snippet "GL_EXT_gpu_shader4" } " extension." } ;
{ render render-set } related-words
@ -313,29 +274,6 @@ HELP: vec3-uniform
HELP: vec4-uniform
{ $class-description "This " { $link uniform-type } " indicates that a slot of a " { $link uniform-tuple } " corresponds to a four-component float vector uniform parameter." } ;
HELP: vertex-array
{ $class-description "A " { $snippet "vertex-array" } " object associates a shader " { $link program-instance } " with vertex attribute data from one or more " { $link buffer } "s. The format of the binary data inside these buffers is described using " { $link vertex-format } "s. " { $snippet "vertex-array" } "s are constructed using the " { $link <vertex-array> } " or " { $link buffer>vertex-array } " words." } ;
HELP: vertex-array-buffer
{ $values
{ "vertex-array" vertex-array }
{ "vertex-buffer" buffer }
}
{ $description "Returns the first " { $link buffer } " object comprised in " { $snippet "vertex-array" } "." } ;
HELP: vertex-attribute
{ $class-description "This tuple type is passed to " { $link define-vertex-format } " to define a new " { $link vertex-format } " type." } ;
HELP: vertex-format
{ $class-description "This class encompasses all vertex formats defined by " { $link POSTPONE: VERTEX-FORMAT: } ". A vertex format defines the binary layout of vertex attribute data in a " { $link buffer } " for use as part of a " { $link vertex-array } ". See the " { $link POSTPONE: VERTEX-FORMAT: } " documentation for details on how vertex formats are defined." } ;
HELP: vertex-format-size
{ $values
{ "format" vertex-format }
{ "size" integer }
}
{ $description "Returns the size in bytes of a set of vertex attributes in " { $snippet "format" } "." } ;
HELP: vertex-indexes
{ $class-description "This class is a union of the following tuple types, any of which can be used as the " { $snippet "indexes" } " slot of a " { $link render-set } " to select elements from a " { $link vertex-array } " for rendering."
{ $list
@ -349,11 +287,6 @@ ARTICLE: "gpu.render" "Rendering"
"The " { $vocab-link "gpu.render" } " vocabulary contains words for organizing and submitting data to the GPU for rendering."
{ $subsection render }
{ $subsection render-set }
"Render data inside GPU " { $link buffer } "s is organized into " { $link vertex-array } "s for consumption by shader code:"
{ $subsection vertex-array }
{ $subsection <vertex-array> }
{ $subsection buffer>vertex-array }
{ $subsection POSTPONE: VERTEX-FORMAT: }
{ $link uniform-tuple } "s provide Factor types for containing and submitting shader uniform parameters:"
{ $subsection POSTPONE: UNIFORM-TUPLE: }
;

View File

@ -3,24 +3,17 @@ USING: accessors alien alien.c-types alien.structs arrays
assocs classes classes.mixin classes.parser classes.singleton
classes.tuple classes.tuple.private combinators combinators.tuple destructors fry
generic generic.parser gpu gpu.buffers gpu.framebuffers
gpu.framebuffers.private gpu.shaders gpu.state gpu.textures
gpu.textures.private half-floats images kernel lexer locals
math math.order math.parser namespaces opengl opengl.gl parser
quotations sequences slots sorting specialized-arrays.alien
specialized-arrays.float specialized-arrays.int
gpu.framebuffers.private gpu.shaders gpu.shaders.private gpu.state
gpu.textures gpu.textures.private half-floats images kernel
lexer locals math math.order math.parser namespaces opengl
opengl.gl parser quotations sequences slots sorting
specialized-arrays.alien specialized-arrays.float specialized-arrays.int
specialized-arrays.uint strings tr ui.gadgets.worlds variants
vocabs.parser words ;
IN: gpu.render
UNION: ?string string POSTPONE: f ;
UNION: ?integer integer POSTPONE: f ;
TUPLE: vertex-attribute
{ name ?string read-only initial: f }
{ component-type component-type read-only initial: float-components }
{ dim integer read-only initial: 4 }
{ normalize? boolean read-only initial: f } ;
VARIANT: uniform-type
bool-uniform
bvec2-uniform
@ -111,52 +104,12 @@ VARIANT: primitive-mode
triangle-strip-mode
triangle-fan-mode ;
MIXIN: vertex-format
TUPLE: uniform-tuple ;
GENERIC: vertex-format-size ( format -- size )
ERROR: invalid-uniform-type uniform ;
<PRIVATE
: gl-vertex-type ( component-type -- gl-type )
{
{ ubyte-components [ GL_UNSIGNED_BYTE ] }
{ ushort-components [ GL_UNSIGNED_SHORT ] }
{ uint-components [ GL_UNSIGNED_INT ] }
{ half-components [ GL_HALF_FLOAT ] }
{ float-components [ GL_FLOAT ] }
{ byte-integer-components [ GL_BYTE ] }
{ short-integer-components [ GL_SHORT ] }
{ int-integer-components [ GL_INT ] }
{ ubyte-integer-components [ GL_UNSIGNED_BYTE ] }
{ ushort-integer-components [ GL_UNSIGNED_SHORT ] }
{ uint-integer-components [ GL_UNSIGNED_INT ] }
} case ;
: vertex-type-size ( component-type -- size )
{
{ ubyte-components [ 1 ] }
{ ushort-components [ 2 ] }
{ uint-components [ 4 ] }
{ half-components [ 2 ] }
{ float-components [ 4 ] }
{ byte-integer-components [ 1 ] }
{ short-integer-components [ 2 ] }
{ int-integer-components [ 4 ] }
{ ubyte-integer-components [ 1 ] }
{ ushort-integer-components [ 2 ] }
{ uint-integer-components [ 4 ] }
} case ;
: vertex-attribute-size ( vertex-attribute -- size )
[ component-type>> vertex-type-size ] [ dim>> ] bi * ;
: vertex-attributes-size ( vertex-attributes -- size )
[ vertex-attribute-size ] [ + ] map-reduce ;
: gl-index-type ( index-type -- gl-index-type )
{
{ ubyte-indexes [ GL_UNSIGNED_BYTE ] }
@ -210,56 +163,6 @@ M: multi-index-elements render-vertex-indexes
: (bind-texture-unit) ( texture texture-unit -- )
swap [ GL_TEXTURE0 + glActiveTexture ] [ bind-texture drop ] bi* ; inline
:: [bind-vertex-attribute] ( stride offset vertex-attribute -- stride offset' quot )
vertex-attribute name>> :> name
vertex-attribute component-type>> :> type
type gl-vertex-type :> gl-type
vertex-attribute dim>> :> dim
vertex-attribute normalize?>> >c-bool :> normalize?
vertex-attribute vertex-attribute-size :> size
stride offset size +
{
{ [ name not ] [ [ 2drop ] ] }
{
[ type unnormalized-integer-components? ]
[
{
name attribute-index [ glEnableVertexAttribArray ] keep
dim gl-type stride offset
} >quotation :> dip-block
{ dip-block dip <displaced-alien> glVertexAttribIPointer } >quotation
]
}
[
{
name attribute-index [ glEnableVertexAttribArray ] keep
dim gl-type normalize? stride offset
} >quotation :> dip-block
{ dip-block dip <displaced-alien> glVertexAttribPointer } >quotation
]
} cond ;
:: [bind-vertex-format] ( vertex-attributes -- quot )
vertex-attributes vertex-attributes-size :> stride
stride 0 vertex-attributes [ [bind-vertex-attribute] ] { } map-as 2nip :> attributes-cleave
{ attributes-cleave 2cleave } >quotation :> with-block
{ drop vertex-buffer with-block with-buffer-ptr } >quotation ;
GENERIC: bind-vertex-format ( program-instance buffer-ptr format -- )
: define-vertex-format-methods ( class vertex-attributes -- )
[
[ \ bind-vertex-format create-method-in ] dip
[bind-vertex-format] define
] [
[ \ vertex-format-size create-method-in ] dip
[ \ drop ] dip vertex-attributes-size [ ] 2sequence define
] 2bi ;
GENERIC: bind-uniform-textures ( program-instance uniform-tuple -- )
GENERIC: bind-uniforms ( program-instance uniform-tuple -- )
@ -510,12 +413,6 @@ padding-no [ 0 ] initialize
"(" ")" surround
padding-no inc ;
: vertex-attribute>c-type ( vertex-attribute -- {type,name} )
[
[ component-type>> component-type>c-type ]
[ dim>> c-array-dim ] bi append
] [ name>> [ padding-name ] unless* ] bi 2array ;
: (define-uniform-tuple) ( class superclass uniforms -- )
{
[ [ uniform>slot ] map define-tuple-class ]
@ -536,55 +433,12 @@ padding-no [ 0 ] initialize
PRIVATE>
: define-vertex-format ( class vertex-attributes -- )
[
[
[ define-singleton-class ]
[ vertex-format add-mixin-instance ]
[ ] tri
] [ define-vertex-format-methods ] bi*
]
[ "vertex-format-attributes" set-word-prop ] 2bi ;
SYNTAX: VERTEX-FORMAT:
CREATE-CLASS parse-definition
[ first4 vertex-attribute boa ] map
define-vertex-format ;
: define-vertex-struct ( struct-name vertex-format -- )
[ current-vocab ] dip
"vertex-format-attributes" word-prop [ vertex-attribute>c-type ] map
define-struct ;
SYNTAX: VERTEX-STRUCT:
scan scan-word define-vertex-struct ;
: define-uniform-tuple ( class superclass uniforms -- )
(define-uniform-tuple) ; inline
SYNTAX: UNIFORM-TUPLE:
parse-uniform-tuple-definition define-uniform-tuple ;
TUPLE: vertex-array < gpu-object
{ program-instance program-instance read-only }
{ vertex-buffers sequence read-only } ;
M: vertex-array dispose
[ [ delete-vertex-array ] when* f ] change-handle drop ;
: <vertex-array> ( program-instance vertex-formats -- vertex-array )
gen-vertex-array
[ glBindVertexArray [ first2 bind-vertex-format ] with each ]
[ -rot [ first buffer>> ] map vertex-array boa ] 3bi
window-resource ;
: buffer>vertex-array ( vertex-buffer program-instance format -- vertex-array )
[ swap ] dip
[ 0 <buffer-ptr> ] dip 2array 1array <vertex-array> ; inline
: vertex-array-buffer ( vertex-array -- vertex-buffer )
vertex-buffers>> first ;
<PRIVATE
: bind-vertex-array ( vertex-array -- )
@ -606,13 +460,15 @@ M: vertex-array dispose
PRIVATE>
UNION: ?any-framebuffer any-framebuffer POSTPONE: f ;
TUPLE: render-set
{ primitive-mode primitive-mode read-only }
{ vertex-array vertex-array read-only }
{ uniforms uniform-tuple read-only }
{ indexes vertex-indexes initial: T{ index-range } read-only }
{ instances ?integer initial: f read-only }
{ framebuffer any-framebuffer initial: system-framebuffer read-only }
{ framebuffer ?any-framebuffer initial: system-framebuffer read-only }
{ output-attachments sequence initial: { default-attachment } read-only } ;
: <render-set> ( x quot-assoc -- render-set )
@ -631,7 +487,11 @@ TUPLE: render-set
[ vertex-array>> program-instance>> ] [ uniforms>> ] bi
[ bind-uniform-textures ] [ bind-uniforms ] 2bi
]
[ GL_DRAW_FRAMEBUFFER swap framebuffer>> framebuffer-handle glBindFramebuffer ]
[
framebuffer>>
[ GL_DRAW_FRAMEBUFFER swap framebuffer-handle glBindFramebuffer ]
[ GL_RASTERIZER_DISCARD glEnable ] if*
]
[
[ vertex-array>> program-instance>> ]
[ framebuffer>> ]
@ -644,5 +504,6 @@ TUPLE: render-set
[ render-vertex-indexes-instanced ]
[ render-vertex-indexes ] if*
]
[ framebuffer>> [ GL_RASTERIZER_DISCARD glDisable ] unless ]
} cleave ; inline

View File

@ -1,5 +1,6 @@
! (c)2009 Joe Groff bsd license
USING: help.markup help.syntax kernel math multiline quotations strings ;
USING: alien.syntax classes gpu.buffers help.markup help.syntax
images kernel math multiline quotations sequences strings ;
IN: gpu.shaders
HELP: <program-instance>
@ -16,6 +17,13 @@ HELP: <shader-instance>
}
{ $description "Compiles an instance of " { $snippet "shader" } " for the current graphics context. If an instance already exists for " { $snippet "shader" } " in the current context, it is reused." } ;
HELP: <vertex-array>
{ $values
{ "program-instance" program-instance } { "vertex-formats" "a list of " { $link buffer-ptr } "/" { $link vertex-format } " pairs" }
{ "vertex-array" vertex-array }
}
{ $description "Creates a new " { $link vertex-array } " to feed data to " { $snippet "program-instance" } " from the set of " { $link buffer } "s specified in " { $snippet "vertex-formats" } "." } ;
HELP: GLSL-PROGRAM:
{ $syntax "GLSL-PROGRAM: program-name shader shader ... shader ;" }
{ $description "Defines a new " { $link program } " named " { $snippet "program-name" } ". When the program is instantiated with " { $link <program-instance> } ", it will link together instances of all of the specified " { $link shader } "s to create the program instance." } ;
@ -32,6 +40,18 @@ shader source
; "> }
{ $description "Defines a new " { $link shader } " of kind " { $link shader-kind } " named " { $snippet "shader-name" } ". The shader will read its source code from the current Factor source file between the " { $snippet "GLSL-SHADER:" } " line and the first subsequent line with a single semicolon on it." } ;
HELP: VERTEX-FORMAT:
{ $syntax <" VERTEX-FORMAT: format-name
{ "attribute"/f component-type dimension normalize? }
{ "attribute"/f component-type dimension normalize? }
...
{ "attribute"/f component-type dimension normalize? } ; "> }
{ $description "Defines a new binary " { $link vertex-format } " for structuring vertex data stored in " { $link buffer } "s. Each " { $snippet "attribute" } " name either corresponds to an input parameter of a vertex shader, or is " { $link f } " to include padding in the vertex format. The " { $link component-type } " determines the format of the components, and the " { $snippet "dimension" } " determines the number of components. If the " { $snippet "component-type" } " is an integer type and " { $snippet "normalize?" } " is true, the component values will be scaled to the range 0.0 to 1.0 when fed to the vertex shader; otherwise, they will be cast to floats retaining their integral values." } ;
HELP: VERTEX-STRUCT:
{ $syntax <" VERTEX-STRUCT: struct-name format-name "> }
{ $description "Defines a struct C type (like " { $link POSTPONE: C-STRUCT: } ") with the same binary format and component types as the given " { $link vertex-format } "." } ;
{ POSTPONE: GLSL-PROGRAM: POSTPONE: GLSL-SHADER-FILE: POSTPONE: GLSL-SHADER: } related-words
HELP: attribute-index
@ -41,6 +61,15 @@ HELP: attribute-index
}
{ $description "Returns the numeric index of the vertex attribute named " { $snippet "attribute-name" } " in " { $snippet "program-instance" } "." } ;
HELP: buffer>vertex-array
{ $values
{ "vertex-buffer" buffer } { "program-instance" program-instance } { "format" vertex-format }
{ "vertex-array" vertex-array }
}
{ $description "Creates a new " { $link vertex-array } " from the entire contents of a single " { $link buffer } " in a single " { $link vertex-format } " for use with " { $snippet "program-instance" } "." } ;
{ vertex-array <vertex-array> buffer>vertex-array } related-words
HELP: compile-shader-error
{ $class-description "An error compiling the source for a " { $link shader } "."
{ $list
@ -48,6 +77,18 @@ HELP: compile-shader-error
{ "The " { $snippet "log" } " slot contains the error string from the GLSL compiler." }
} } ;
HELP: define-vertex-format
{ $values
{ "class" class } { "vertex-attributes" sequence }
}
{ $description "Defines a new " { $link vertex-format } " with the binary format specified by the " { $link vertex-attribute } " tuple values in " { $snippet "vertex-attributes" } ". The runtime equivalent of " { $link POSTPONE: VERTEX-FORMAT: } ". This word must be called inside a compilation unit." } ;
HELP: define-vertex-struct
{ $values
{ "struct-name" string } { "vertex-format" vertex-format }
}
{ $description "Defines a new struct C type from a " { $link vertex-format } ". The runtime equivalent of " { $link POSTPONE: VERTEX-STRUCT: } ". This word must be called inside a compilation unit." } ;
HELP: fragment-shader
{ $class-description "This " { $link shader-kind } " indicates that a " { $link shader } " is a fragment shader." } ;
@ -103,6 +144,29 @@ HELP: uniform-index
HELP: vertex-shader
{ $class-description "This " { $link shader-kind } " indicates that a " { $link shader } " is a vertex shader." } ;
HELP: vertex-array
{ $class-description "A " { $snippet "vertex-array" } " object associates a shader " { $link program-instance } " with vertex attribute data from one or more " { $link buffer } "s. The format of the binary data inside these buffers is described using " { $link vertex-format } "s. " { $snippet "vertex-array" } "s are constructed using the " { $link <vertex-array> } " or " { $link buffer>vertex-array } " words." } ;
HELP: vertex-array-buffer
{ $values
{ "vertex-array" vertex-array }
{ "vertex-buffer" buffer }
}
{ $description "Returns the first " { $link buffer } " object comprised in " { $snippet "vertex-array" } "." } ;
HELP: vertex-attribute
{ $class-description "This tuple type is passed to " { $link define-vertex-format } " to define a new " { $link vertex-format } " type." } ;
HELP: vertex-format
{ $class-description "This class encompasses all vertex formats defined by " { $link POSTPONE: VERTEX-FORMAT: } ". A vertex format defines the binary layout of vertex attribute data in a " { $link buffer } " for use as part of a " { $link vertex-array } ". See the " { $link POSTPONE: VERTEX-FORMAT: } " documentation for details on how vertex formats are defined." } ;
HELP: vertex-format-size
{ $values
{ "format" vertex-format }
{ "size" integer }
}
{ $description "Returns the size in bytes of a set of vertex attributes in " { $snippet "format" } "." } ;
ARTICLE: "gpu.shaders" "Shader objects"
"The " { $vocab-link "gpu.shaders" } " vocabulary supports defining, compiling, and linking " { $link shader } "s into " { $link program } "s that run on the GPU and control rendering."
{ $subsection POSTPONE: GLSL-PROGRAM: }
@ -111,6 +175,11 @@ ARTICLE: "gpu.shaders" "Shader objects"
"A program must be instantiated for each graphics context it is used in:"
{ $subsection <program-instance> }
"Program instances can be updated on the fly, allowing for interactive development of shaders:"
{ $subsection refresh-program } ;
{ $subsection refresh-program }
"Render data inside GPU " { $link buffer } "s is organized into " { $link vertex-array } "s for consumption by shader code:"
{ $subsection vertex-array }
{ $subsection <vertex-array> }
{ $subsection buffer>vertex-array }
{ $subsection POSTPONE: VERTEX-FORMAT: } ;
ABOUT: "gpu.shaders"

View File

@ -1,17 +1,29 @@
! (c)2009 Joe Groff bsd license
USING: accessors arrays assocs combinators
combinators.short-circuit definitions destructors gpu
io.encodings.ascii io.files io.pathnames kernel lexer
locals math math.parser memoize multiline namespaces
opengl.gl opengl.shaders parser sequences
USING: accessors alien alien.c-types alien.structs arrays
assocs classes.mixin classes.parser classes.singleton
combinators combinators.short-circuit definitions destructors
generic.parser gpu gpu.buffers hashtables
images io.encodings.ascii io.files io.pathnames kernel lexer
locals math math.parser memoize multiline namespaces opengl
opengl.gl opengl.shaders parser quotations sequences
specialized-arrays.int splitting strings ui.gadgets.worlds
variants hashtables vectors vocabs vocabs.loader words
variants vectors vocabs vocabs.loader vocabs.parser words
words.constant ;
IN: gpu.shaders
VARIANT: shader-kind
vertex-shader fragment-shader ;
UNION: ?string string POSTPONE: f ;
TUPLE: vertex-attribute
{ name ?string read-only initial: f }
{ component-type component-type read-only initial: float-components }
{ dim integer read-only initial: 4 }
{ normalize? boolean read-only initial: f } ;
MIXIN: vertex-format
TUPLE: shader
{ name word read-only initial: t }
{ kind shader-kind read-only }
@ -25,6 +37,7 @@ TUPLE: program
{ filename read-only }
{ line integer read-only }
{ shaders array read-only }
{ feedback-format vertex-format read-only }
{ instances hashtable read-only } ;
TUPLE: shader-instance < gpu-object
@ -35,8 +48,136 @@ TUPLE: program-instance < gpu-object
{ program program }
{ world world } ;
GENERIC: vertex-format-size ( format -- size )
MEMO: uniform-index ( program-instance uniform-name -- index )
[ handle>> ] dip glGetUniformLocation ;
MEMO: attribute-index ( program-instance attribute-name -- index )
[ handle>> ] dip glGetAttribLocation ;
MEMO: output-index ( program-instance output-name -- index )
[ handle>> ] dip glGetFragDataLocation ;
<PRIVATE
: gl-vertex-type ( component-type -- gl-type )
{
{ ubyte-components [ GL_UNSIGNED_BYTE ] }
{ ushort-components [ GL_UNSIGNED_SHORT ] }
{ uint-components [ GL_UNSIGNED_INT ] }
{ half-components [ GL_HALF_FLOAT ] }
{ float-components [ GL_FLOAT ] }
{ byte-integer-components [ GL_BYTE ] }
{ short-integer-components [ GL_SHORT ] }
{ int-integer-components [ GL_INT ] }
{ ubyte-integer-components [ GL_UNSIGNED_BYTE ] }
{ ushort-integer-components [ GL_UNSIGNED_SHORT ] }
{ uint-integer-components [ GL_UNSIGNED_INT ] }
} case ;
: vertex-type-size ( component-type -- size )
{
{ ubyte-components [ 1 ] }
{ ushort-components [ 2 ] }
{ uint-components [ 4 ] }
{ half-components [ 2 ] }
{ float-components [ 4 ] }
{ byte-integer-components [ 1 ] }
{ short-integer-components [ 2 ] }
{ int-integer-components [ 4 ] }
{ ubyte-integer-components [ 1 ] }
{ ushort-integer-components [ 2 ] }
{ uint-integer-components [ 4 ] }
} case ;
: vertex-attribute-size ( vertex-attribute -- size )
[ component-type>> vertex-type-size ] [ dim>> ] bi * ;
: vertex-attributes-size ( vertex-attributes -- size )
[ vertex-attribute-size ] [ + ] map-reduce ;
:: [bind-vertex-attribute] ( stride offset vertex-attribute -- stride offset' quot )
vertex-attribute name>> :> name
vertex-attribute component-type>> :> type
type gl-vertex-type :> gl-type
vertex-attribute dim>> :> dim
vertex-attribute normalize?>> >c-bool :> normalize?
vertex-attribute vertex-attribute-size :> size
stride offset size +
{
{ [ name not ] [ [ 2drop ] ] }
{
[ type unnormalized-integer-components? ]
[
{
name attribute-index [ glEnableVertexAttribArray ] keep
dim gl-type stride offset
} >quotation :> dip-block
{ dip-block dip <displaced-alien> glVertexAttribIPointer } >quotation
]
}
[
{
name attribute-index [ glEnableVertexAttribArray ] keep
dim gl-type normalize? stride offset
} >quotation :> dip-block
{ dip-block dip <displaced-alien> glVertexAttribPointer } >quotation
]
} cond ;
:: [bind-vertex-format] ( vertex-attributes -- quot )
vertex-attributes vertex-attributes-size :> stride
stride 0 vertex-attributes [ [bind-vertex-attribute] ] { } map-as 2nip :> attributes-cleave
{ attributes-cleave 2cleave } >quotation :> with-block
{ drop vertex-buffer with-block with-buffer-ptr } >quotation ;
GENERIC: bind-vertex-format ( program-instance buffer-ptr format -- )
: define-vertex-format-methods ( class vertex-attributes -- )
[
[ \ bind-vertex-format create-method-in ] dip
[bind-vertex-format] define
] [
[ \ vertex-format-size create-method-in ] dip
[ \ drop ] dip vertex-attributes-size [ ] 2sequence define
] 2bi ;
: component-type>c-type ( component-type -- c-type )
{
{ ubyte-components [ "uchar" ] }
{ ushort-components [ "ushort" ] }
{ uint-components [ "uint" ] }
{ half-components [ "half" ] }
{ float-components [ "float" ] }
{ byte-integer-components [ "char" ] }
{ ubyte-integer-components [ "uchar" ] }
{ short-integer-components [ "short" ] }
{ ushort-integer-components [ "ushort" ] }
{ int-integer-components [ "int" ] }
{ uint-integer-components [ "uint" ] }
} case ;
: c-array-dim ( dim -- string )
dup 1 = [ drop "" ] [ number>string "[" "]" surround ] if ;
SYMBOL: padding-no
padding-no [ 0 ] initialize
: padding-name ( -- name )
"padding-"
padding-no get number>string append
"(" ")" surround
padding-no inc ;
: vertex-attribute>c-type ( vertex-attribute -- {type,name} )
[
[ component-type>> component-type>c-type ]
[ dim>> c-array-dim ] bi append
] [ name>> [ padding-name ] unless* ] bi 2array ;
: shader-filename ( shader/program -- filename )
dup filename>> [ nip ] [ name>> where first ] if* file-name ;
@ -69,6 +210,49 @@ TUPLE: program-instance < gpu-object
PRIVATE>
: define-vertex-format ( class vertex-attributes -- )
[
[
[ define-singleton-class ]
[ vertex-format add-mixin-instance ]
[ ] tri
] [ define-vertex-format-methods ] bi*
]
[ "vertex-format-attributes" set-word-prop ] 2bi ;
SYNTAX: VERTEX-FORMAT:
CREATE-CLASS parse-definition
[ first4 vertex-attribute boa ] map
define-vertex-format ;
: define-vertex-struct ( struct-name vertex-format -- )
[ current-vocab ] dip
"vertex-format-attributes" word-prop [ vertex-attribute>c-type ] map
define-struct ;
SYNTAX: VERTEX-STRUCT:
scan scan-word define-vertex-struct ;
TUPLE: vertex-array < gpu-object
{ program-instance program-instance read-only }
{ vertex-buffers sequence read-only } ;
M: vertex-array dispose
[ [ delete-vertex-array ] when* f ] change-handle drop ;
: <vertex-array> ( program-instance vertex-formats -- vertex-array )
gen-vertex-array
[ glBindVertexArray [ first2 bind-vertex-format ] with each ]
[ -rot [ first buffer>> ] map vertex-array boa ] 3bi
window-resource ;
: buffer>vertex-array ( vertex-buffer program-instance format -- vertex-array )
[ swap ] dip
[ 0 <buffer-ptr> ] dip 2array 1array <vertex-array> ; inline
: vertex-array-buffer ( vertex-array -- vertex-buffer )
vertex-buffers>> first ;
TUPLE: compile-shader-error shader log ;
TUPLE: link-program-error program log ;
@ -82,13 +266,6 @@ TUPLE: link-program-error program log ;
DEFER: <shader-instance>
MEMO: uniform-index ( program-instance uniform-name -- index )
[ handle>> ] dip glGetUniformLocation ;
MEMO: attribute-index ( program-instance attribute-name -- index )
[ handle>> ] dip glGetAttribLocation ;
MEMO: output-index ( program-instance output-name -- index )
[ handle>> ] dip glGetFragDataLocation ;
<PRIVATE
: valid-handle? ( handle -- ? )

View File

@ -1,5 +1,5 @@
! (c)2009 Joe Groff bsd license
USING: gpu.buffers gpu.render gpu.textures images kernel
USING: gpu.buffers gpu.render gpu.shaders gpu.textures images kernel
specialized-arrays.float ;
IN: gpu.util