@@ -251,18 +251,20 @@ type
251251        source* : string 
252252        setupProc* : proc (cc: CompiledComposition )
253253        mainProcName* : string 
254+         seenFlag: bool  #  Used on compilation phase, should not be used elsewhere.
254255        id* : int 
255256
256257    CompiledComposition  =  ref  object 
257258        program* : ProgramRef 
258-         uniformLocations: seq [UniformLocation ]
259+         uniformLocations* : seq [UniformLocation ]
259260        iTexIndex* : GLint 
260261        iUniform* : int 
261262
262263var  programCache =  initTable [Hash , CompiledComposition ]()
263264
264265type Composition *  =  object 
265266    definition: string 
267+     vsDefinition: string  #  Vertex shader source code
266268    requiresPrequel: bool 
267269    id* : int 
268270
@@ -311,19 +313,27 @@ proc newPostEffect*(definition: static[string], mainProcName: string): PostEffec
311313    result .mainProcName =  mainProcName
312314    result .id =  hash (preprocessedDefinition)
313315
314- proc  newComposition * (definition : static [string ], requiresPrequel: bool  =  true ): Composition  = 
315-     const  preprocessedDefinition =  preprocessDefinition (definition )
316+ proc  newComposition * (vsDef, fsDef : static [string ], requiresPrequel: bool  =  true ): Composition  = 
317+     const  preprocessedDefinition =  preprocessDefinition (fsDef )
316318    result .definition =  preprocessedDefinition
319+     result .vsDefinition =  vsDef
317320    result .requiresPrequel =  requiresPrequel
318321    result .id =  hash (preprocessedDefinition)
319322
323+ template  newComposition * (definition: static [string ], requiresPrequel: bool  =  true ): Composition  = 
324+     newComposition (nil , definition, requiresPrequel)
325+ 
320326template  newCompositionWithNimsl * (mainProc: typed ): Composition  = 
321327    newComposition (getGLSLFragmentShader (mainProc, " compose" false )
322328
323- var  postEffectStack =  newSeq [PostEffect ]()
329+ type PostEffectStackElem  =  object 
330+     postEffect: PostEffect 
331+     setupProc* : proc (cc: CompiledComposition )
332+ 
333+ var  postEffectStack =  newSeq [PostEffectStackElem ]()
324334var  postEffectIdStack =  newSeq [Hash ]()
325335
326- proc  compileComposition * (gl: GL , comp: var   Composition , cchash: Hash ): CompiledComposition  = 
336+ proc  compileComposition * (gl: GL , comp: Composition , cchash: Hash ): CompiledComposition  = 
327337    var  fragmentShaderCode =  " " 
328338    if  comp.requiresPrequel:
329339        fragmentShaderCode =  """ 
@@ -342,18 +352,29 @@ uniform vec4 bounds;
342352
343353    fragmentShaderCode &=  comp.definition
344354
345-     for  pe in  postEffectStack:
346-         fragmentShaderCode &=  pe.source
355+     let  ln =  postEffectStack.len
356+     var  i =  0 
357+     while  i <  ln:
358+         let  pe =  postEffectStack[i].postEffect
359+         if  not  pe.seenFlag:
360+             fragmentShaderCode &=  pe.source
361+             pe.seenFlag =  true 
362+         inc  i
363+ 
364+     i =  0 
365+     while  i <  ln:
366+         postEffectStack[i].postEffect.seenFlag =  false 
367+         inc  i
347368
348369    fragmentShaderCode &=  """ void main() { gl_FragColor = vec4(0.0); compose();  """ 
349-     var   i =  postEffectStack.len -  1 
370+     i =  postEffectStack.len -  1 
350371    while  i >=  0 :
351-         fragmentShaderCode &=  postEffectStack[i].mainProcName &  " ();" 
372+         fragmentShaderCode &=  postEffectStack[i].postEffect. mainProcName &  " ();" 
352373        dec  i
353374    fragmentShaderCode &=  " }" 
354375
355376    result .new ()
356-     result .program =  gl.newShaderProgram (vertexShaderCode, fragmentShaderCode, [(posAttr, " aPosition" 
377+     result .program =  gl.newShaderProgram (if  comp.vsDefinition.isNil:  vertexShaderCode  else : comp.vsDefinition , fragmentShaderCode, [(posAttr, " aPosition" 
357378    result .uniformLocations =  newSeq [UniformLocation ]()
358379    programCache[cchash] =  result 
359380
@@ -368,7 +389,7 @@ proc unwrapPointArray(a: openarray[Point]): seq[GLfloat] =
368389
369390var  texQuad : array [4 , GLfloat ]
370391
371- template  compositionDrawingDefinitions (cc: CompiledComposition , ctx: GraphicsContext , gl: GL ) = 
392+ template  compositionDrawingDefinitions * (cc: CompiledComposition , ctx: GraphicsContext , gl: GL ) = 
372393    template  uniformLocation (name: string ): UniformLocation  = 
373394        inc  cc.iUniform
374395        if  cc.uniformLocations.len -  1  <  cc.iUniform:
@@ -407,29 +428,38 @@ template compositionDrawingDefinitions(cc: CompiledComposition, ctx: GraphicsCon
407428        inc  cc.iTexIndex
408429
409430template  pushPostEffect * (pe: PostEffect , body: untyped ) = 
410-     pe.setupProc  =  proc (cc: CompiledComposition ) = 
431+     postEffectStack. add ( PostEffectStackElem (postEffect: pe, setupProc:  proc (cc: CompiledComposition ) = 
411432        let  ctx =  currentContext ()
412433        let  gl =  ctx.gl
413434        compositionDrawingDefinitions (cc, ctx, gl)
414435        body
436+     ))
415437
416-     postEffectStack.add (pe)
417438    let  oh =  if  postEffectIdStack.len >  0 : postEffectIdStack[^ 1 ] else : 0 
418439    postEffectIdStack.add (oh !&  pe.id)
419440
420441template  popPostEffect * () = 
421442    postEffectStack.setLen (postEffectStack.len -  1 )
422443    postEffectIdStack.setLen (postEffectIdStack.len -  1 )
423444
424- template  draw * (comp: var  Composition , r: Rect , code: untyped ): stmt = 
425-     let  ctx =  currentContext ()
426-     let  gl =  ctx.gl
445+ template  getCompiledComposition * (gl: GL , comp: Composition ): CompiledComposition  = 
427446    let  pehash =  if  postEffectIdStack.len >  0 : postEffectIdStack[^ 1 ] else : 0 
428447    let  cchash =  !$ (pehash !&  comp.id)
429- 
430448    var  cc =  programCache.getOrDefault (cchash)
431449    if  cc.isNil:
432450        cc =  gl.compileComposition (comp, cchash)
451+     cc.iUniform =  - 1 
452+     cc.iTexIndex =  0 
453+     cc
454+ 
455+ template  setupPosteffectUniforms * (cc: CompiledComposition ) = 
456+     for  pe in  postEffectStack:
457+         pe.setupProc (cc)
458+ 
459+ template  draw * (comp: var  Composition , r: Rect , code: untyped ): stmt = 
460+     let  ctx =  currentContext ()
461+     let  gl =  ctx.gl
462+     let  cc =  gl.getCompiledComposition (comp)
433463    gl.useProgram (cc.program)
434464    var  points : array [8 , GLfloat ]
435465    points[0 ] =  r.minX; points[1 ] =  r.minY
@@ -440,17 +470,14 @@ template draw*(comp: var Composition, r: Rect, code: untyped): stmt =
440470    const  componentCount : GLint  =  2 
441471    gl.enableVertexAttribArray (posAttr)
442472    gl.vertexAttribPointer (posAttr, componentCount, false , 0 , points)
443-     cc.iUniform =  - 1 
444-     cc.iTexIndex =  0 
445473
446474    compositionDrawingDefinitions (cc, ctx, gl)
447475
448476    gl.uniformMatrix4fv (uniformLocation (" uModelViewProjectionMatrix" false , ctx.transform)
449477
450478    setUniform (" bounds" 
451479
452-     for  pe in  postEffectStack:
453-         pe.setupProc (cc)
480+     setupPosteffectUniforms (cc)
454481
455482    block :
456483        code
0 commit comments