c - Nested Stencil - OpenGL ES -


i have 2d node scene graph i'm trying 'nest' stencil clipping in.

i thinking when drawing stencil, increment pixel writes 1, , keep track of current 'layer' i'm on.

then when drawing, write pixel data color buffer if value of stencil @ pixel >= current layer #.

this code have now. doesn't quite work. messing up?

first call setupstencilformask(). draw stencil primitives. next, call setupstencilfordraw(). draw actual imagery when done layer, call disablestencil().

edit: updated solution. doesn't work individual items on same layer, otherwise fine. found great article on how pull off, although it's limited. http://cranialburnout.blogspot.com/2014/03/nesting-and-overlapping-translucent.html

// glclear(gl_stenicl_bit) @ start of each draw frame static int stencillayer = 0;  void setupstencilformask(void) {     if (stencillayer == 0)         glenable(gl_stencil_test);      glcolormask(gl_false, gl_false, gl_false, gl_false);     glstencilfunc(gl_less, stencillayer, 0xff);     glstencilop(gl_incr, gl_keep, gl_keep);     glstencilmask(0xff);      if (stencillayer == 0)         glclear(gl_stencil_buffer_bit);      stencillayer++; }  void setupstencilfordraw() {        glcolormask(gl_true, gl_true, gl_true, gl_true);     glstencilfunc(gl_equal, stencillayer, 0xff);     glstencilmask(0x00); }  void disablestencil(void) {     if (--stencillayer == 0)         gldisable(gl_stencil_test); } 

i have figured out way in libgdx. i'm not sure still need this, future reference here code:

/**  * start cropping  *   * @param cropmask  *            mask plane  */ public void startcropping(plane cropmask) {      // check if there active masking group     if (activecropmaskgroup == null) {          // create new 1         activecropmaskgroup = new cropmaskinggroupdescriptor(cropmask);     } else {          // increase hierarchy level         activecropmaskgroup.increasehierachy(cropmask);     }  }  /** end cropping */ public void endcropping() throws illegalstateexception {      // check if there active group mask     if (activecropmaskgroup == null) {         throw new illegalstateexception("call start cropping before this!");     }      if (activecropmaskgroup.gethierachy() > 0) {          activecropmaskgroup.decreasehierachy();     } else {          // finish setup of crop data         cropmaskgroups.add(activecropmaskgroup);         activecropmaskgroup = null;     }  }  /** crop registered planes cropping */ private void croprender(cropmaskinggroupdescriptor cropmaskgroupdescriptor) {      // draw mask stencil buffer     gdx.gl.glclear(gl20.gl_stencil_buffer_bit);      // setup drawing stencil buffer     gdx.gl20.glenable(gl20.gl_stencil_test);      // number of registered hierarchy levels     int hierarchylevels = cropmaskgroupdescriptor.getregisteredbatch().size();      // loop trough hierarchy     (int hierarchylevel = 0; hierarchylevel < hierarchylevels; hierarchylevel++) {          gdx.gl20.glstencilfunc(gl20.gl_always, 0x1, 0xffffffff);         gdx.gl20.glstencilop(gl20.gl_incr, gl20.gl_incr, gl20.gl_incr);         gdx.gl20.glcolormask(false, false, false, false);         gdx.gl20.gldepthmask(false);          // draw mask decal batch         cropmaskbatch.add(((nativeplane) cropmaskgroupdescriptor.getcroppingmasks().get(hierarchylevel)).getplane());         cropmaskbatch.flush();          // fix stencil buffer, enable color buffer         gdx.gl20.glcolormask(true, true, true, true);         gdx.gl20.gldepthmask(true);         gdx.gl20.glstencilop(gl20.gl_keep, gl20.gl_keep, gl20.gl_keep);          // draw pattern has been drawn         gdx.gl20.glstencilfunc(gl20.gl_lequal, hierarchylevel + 1, 0xffffffff);          // loop trough registered masked layers , found 1 belongs         //         // current hierarchy level         (int = 0; < cropmaskgroupdescriptor.getmaskedlayers().size(); i++) {              if (cropmaskgroupdescriptor.getmaskedlayers().get(i).gethierarchyid() == hierarchylevel) {                  plane plane = cropmaskgroupdescriptor.getmaskedlayers().get(i).getmaskedplane();                 cropmaskgroupdescriptor.getregisteredbatch().get(hierarchylevel).add(((nativeplane) plane).getplane());             }          }          cropmaskgroupdescriptor.getregisteredbatch().get(hierarchylevel).flush();      }      gdx.gl20.gldisable(gl20.gl_stencil_test);  } 

and inner class inside renderer module.

/** * cropped layer descriptor * * @author veljko ilkic * */ private class cropmasklayerdescriptor {

    /** layer needs masked */     private plane maskedplane;      /** hierarchy level in belongs */     private int hierarchyid = 0;      /** constructor 1 */     public cropmasklayerdescriptor(plane maskedplane, int hierarchyid) {         this.maskedplane = maskedplane;         this.hierarchyid = hierarchyid;     }      public plane getmaskedplane() {         return maskedplane;     }      public int gethierarchyid() {         return hierarchyid;     }  }  /**  * crop masking group descriptor class  *   * @author veljko ilkic  *   */ private class cropmaskinggroupdescriptor {      /** crop mask */     private arraylist<plane> croppingmasks = new arraylist<plane>();      /** planes masked crop mask */     private arraylist<cropmasklayerdescriptor> maskedlayers = new arraylist<renderer.cropmasklayerdescriptor>();      /** batch drawing masked planes */     private arraylist<decalbatch> hierarchybatches = new arraylist<decalbatch>();      private int activehierarchylayerid = 0;      /** constructor 1 */     public cropmaskinggroupdescriptor(plane toplevelcropmask) {          // create batch top level hierarchy         hierarchybatches.add(new decalbatch(new cameragroupstrategy(perspectivecamera)));          // register top level crop mask         croppingmasks.add(toplevelcropmask);     }      /** increase hierarchy level of group */     public void increasehierachy(plane hierarchycropmask) {         activehierarchylayerid++;          // create individual batch hierarchy level         hierarchybatches.add(new decalbatch(new cameragroupstrategy(perspectivecamera)));          // register crop mask current hierarchy level         croppingmasks.add(hierarchycropmask);     }      /** decrease hierarchy group */     public void decreasehierachy() {         activehierarchylayerid--;     }      /** current hierarchy level */     public int gethierachy() {         return activehierarchylayerid;     }      /** register plane masking */     public void registerlayer(plane maskedplane) {         hierarchybatches.get(activehierarchylayerid).add(((nativeplane) maskedplane).getplane());         maskedlayers.add(new cropmasklayerdescriptor(maskedplane, activehierarchylayerid));     }      /** registered batched */     public arraylist<decalbatch> getregisteredbatch() {         return hierarchybatches;     }      /** registered cropping masks */     public arraylist<plane> getcroppingmasks() {         return croppingmasks;     }      /** layer should masked */     public arraylist<cropmasklayerdescriptor> getmaskedlayers() {         return maskedlayers;     }      /** dispose */     public void dispose() {         (int = 0; < hierarchybatches.size(); i++) {             hierarchybatches.get(i).dispose();             hierarchybatches.set(i, null);         }          hierarchybatches.clear();     } } 

hope helps.


Popular posts from this blog

php - How should I create my API for mobile applications (Needs Authentication) -

5 Reasons to Blog Anonymously (and 5 Reasons Not To)

Google AdWords and AdSense - A Dynamic Small Business Marketing Duo