Per render target configuration of blending

Discuss your feature requests for the next release of Ardor3D here.
Forum rules
Discuss your feature requests for the next release of Ardor3D here. Please make a ticket and reference it in your first post.

Per render target configuration of blending

Postby martifa » Mon Apr 23, 2012 9:29 am

Hi all!

I want to be able to enable or disable blending individually for each of my render targets. A ticket has been created: http://ardorlabs.trac.cvsdude.com/Ardor3Dv1/attachment/ticket/215/.
I am currently testing an implementation using JOGL that seems to work:
Code: Select all
C:\Workspace\martin-misc>hg diff -c 78
diff -r c5b469b76287 -r 1bd1a4c4f61f Ardor3D/Enhancements/ardor3d-0.8/ardor3d-core/src/main/java/com/ardor3d/image/Texture.java
--- a/Ardor3D/Enhancements/ardor3d-0.8/ardor3d-core/src/main/java/com/ardor3d/image/Texture.java     Thu Apr 19 07:32:53 2012 +0200
+++ b/Ardor3D/Enhancements/ardor3d-0.8/ardor3d-core/src/main/java/com/ardor3d/image/Texture.java     Mon Apr 23 14:26:58 2012 +0200
@@ -38,6 +38,11 @@
public abstract class Texture implements Savable {

     public static boolean DEFAULT_STORE_IMAGE = Constants.storeSavableImages;
+
+    /**
+     * Used to control blending when used as a render target.
+     */
+    private boolean blendMRT = false;

     public enum Type {
         /**
@@ -1513,4 +1518,12 @@
     public void setTextureMaxLevel(final int textureMaxLevel) {
         _textureMaxLevel = textureMaxLevel;
     }
+
+    public void setBlendMRT(boolean blendMRT) {
+        this.blendMRT = blendMRT;
+    }
+
+    public boolean getBlendMRT(){
+        return this.blendMRT;
+    }
}
diff -r c5b469b76287 -r 1bd1a4c4f61f Ardor3D/Enhancements/ardor3d-0.8/ardor3d-jogl/src/main/java/com/ardor3d/renderer/jogl/JoglTextureRenderer.java
--- a/Ardor3D/Enhancements/ardor3d-0.8/ardor3d-jogl/src/main/java/com/ardor3d/renderer/jogl/JoglTextureRenderer.java    Thu Apr 19 07:32:53 2012 +0200
+++ b/Ardor3D/Enhancements/ardor3d-0.8/ardor3d-jogl/src/main/java/com/ardor3d/renderer/jogl/JoglTextureRenderer.java    Mon Apr 23 14:26:58 2012 +0200
@@ -195,8 +195,11 @@
             for (int i = 0; i < groups; i++) {
                 // First handle colors
                 int colorsAdded = 0;
+                List<Texture> colorTextures = new LinkedList<Texture>();
                 while (colorsAdded < maxDrawBuffers && !colors.isEmpty()) {
                     final Texture tex = colors.removeFirst();
+                    colorTextures.add(tex);
+
                     if (tex.getType() == Type.TwoDimensional) {
                         gl.glFramebufferTexture2DEXT(GL.GL_FRAMEBUFFER_EXT, GL.GL_COLOR_ATTACHMENT0_EXT + colorsAdded,
                                 GL.GL_TEXTURE_2D, tex.getTextureIdForContext(context.getGlContextRep()), 0);
@@ -235,6 +238,8 @@
                 setDrawBuffers(colorsAdded);
                 setReadBuffer(colorsAdded != 0 ? GL.GL_COLOR_ATTACHMENT0_EXT : GL.GL_NONE);

+                enableDisableBlending(colorTextures, gl);
+
                 // Check FBO complete
                 checkFBOComplete(_fboID);

@@ -567,4 +572,16 @@
             gl.glDeleteRenderbuffersEXT(id.limit(), id);
         }
     }
+
+    private void enableDisableBlending(List<Texture> colorTextures, final GL gl) {
+        int index = 0;
+        for (Texture tex : colorTextures) {
+            if(tex.getBlendMRT()){
+                gl.glEnableIndexedEXT(GL.GL_BLEND, index++);
+            }
+            else{
+                gl.glDisableIndexedEXT(GL.GL_BLEND, index++);
+            }
+        }
+    }
}

C:\Workspace\martin-misc>hg diff -r 80
diff -r c85e4ea11986 Ardor3D/Enhancements/ardor3d-0.8/ardor3d-core/src/main/java/com/ardor3d/image/Texture.java
--- a/Ardor3D/Enhancements/ardor3d-0.8/ardor3d-core/src/main/java/com/ardor3d/image/Texture.java     Mon Apr 23 14:39:13 2012 +0200
+++ b/Ardor3D/Enhancements/ardor3d-0.8/ardor3d-core/src/main/java/com/ardor3d/image/Texture.java     Mon Apr 23 17:16:58 2012 +0200
@@ -1519,10 +1519,18 @@
         _textureMaxLevel = textureMaxLevel;
     }

+    /**
+     * Flags if blending should be enabled when this texture is used as a render target.
+     * @param blendMRT True if blending should be used.
+     */
     public void setBlendMRT(boolean blendMRT) {
         this.blendMRT = blendMRT;
     }
-
+
+    /**
+     * Flags if blending should be enabled when this texture is used as a render target.
+     * @return True if blending should be used.
+     */
     public boolean getBlendMRT(){
         return this.blendMRT;
     }
diff -r c85e4ea11986 Ardor3D/Enhancements/ardor3d-0.8/ardor3d-core/src/main/java/com/ardor3d/renderer/AbstractRenderer.java
--- a/Ardor3D/Enhancements/ardor3d-0.8/ardor3d-core/src/main/java/com/ardor3d/renderer/AbstractRenderer.java    Mon Apr 23 14:39:13 2012 +0200
+++ b/Ardor3D/Enhancements/ardor3d-0.8/ardor3d-core/src/main/java/com/ardor3d/renderer/AbstractRenderer.java    Mon Apr 23 17:16:58 2012 +0200
@@ -24,6 +24,7 @@
import com.ardor3d.util.Constants;
import com.ardor3d.util.stat.StatCollector;
import com.ardor3d.util.stat.StatType;
+import java.util.concurrent.ConcurrentLinkedQueue;

/**
  * Provides some common base level method implementations for Renderers.
@@ -41,6 +42,9 @@
     protected int _stencilClearValue;

     protected RenderLogic renderLogic;
+
+    protected volatile ConcurrentLinkedQueue<Integer> enabledBlendTargets = new ConcurrentLinkedQueue<Integer>();
+    protected volatile ConcurrentLinkedQueue<Integer> disabledBlendTargets = new ConcurrentLinkedQueue<Integer>();

     /** List of default rendering states for this specific renderer type */
     protected final EnumMap<RenderState.StateType, RenderState> defaultStateList = new EnumMap<RenderState.StateType, RenderState>(
@@ -188,4 +192,48 @@
     public void setRenderLogic(final RenderLogic renderLogic) {
         this.renderLogic = renderLogic;
     }
+
+    /**
+     * When FBO MRT is used calling this method enables blending for the rendertarget with the index given.
+     * @param i The index of the render target to enable blending for.
+     */
+    public void addEnabledBlendTarget(int i) {
+        enabledBlendTargets.add(i);
+        enabledBlendTargets = enabledBlendTargets;
+    }
+
+    /**
+     * When FBO MRT is used calling this method disables blending for the rendertarget with the index given.
+     * @param i The index of the render target to disable blending for.
+     */
+    public void addDisabledBlendTarget(int i) {
+        disabledBlendTargets.add(i);
+        disabledBlendTargets = disabledBlendTargets;
+    }
+
+    /**
+     * Clears the data structures populated by {@link #addEnabledBlendTarget(int)} and {@link #addDisabledBlendTarget(int) }.
+     */
+    public void clearBlendTargets(){
+        enabledBlendTargets.clear();
+        enabledBlendTargets = enabledBlendTargets;
+        disabledBlendTargets.clear();
+        disabledBlendTargets = disabledBlendTargets;
+    }
+
+    /**
+     * Returns the indices of the current render targets that blending is enabled for.
+     * @return
+     */
+    public ConcurrentLinkedQueue<Integer> getEnabledBlendTargets() {
+        return enabledBlendTargets;
+    }
+
+    /**
+     * Returns the indices of the current render targets that blending is disabled for.
+     * @return
+     */
+    public ConcurrentLinkedQueue<Integer> getDisabledBlendTargets() {
+        return disabledBlendTargets;
+    }
}
diff -r c85e4ea11986 Ardor3D/Enhancements/ardor3d-0.8/ardor3d-jogl/src/main/java/com/ardor3d/renderer/jogl/JoglTextureRenderer.java
--- a/Ardor3D/Enhancements/ardor3d-0.8/ardor3d-jogl/src/main/java/com/ardor3d/renderer/jogl/JoglTextureRenderer.java    Mon Apr 23 14:39:13 2012 +0200
+++ b/Ardor3D/Enhancements/ardor3d-0.8/ardor3d-jogl/src/main/java/com/ardor3d/renderer/jogl/JoglTextureRenderer.java    Mon Apr 23 17:16:58 2012 +0200
@@ -24,12 +24,7 @@
import com.ardor3d.image.Texture.Type;
import com.ardor3d.image.TextureCubeMap.Face;
import com.ardor3d.math.type.ReadOnlyColorRGBA;
-import com.ardor3d.renderer.AbstractFBOTextureRenderer;
-import com.ardor3d.renderer.ContextCapabilities;
-import com.ardor3d.renderer.ContextManager;
-import com.ardor3d.renderer.RenderContext;
-import com.ardor3d.renderer.Renderer;
-import com.ardor3d.renderer.TextureRendererFactory;
+import com.ardor3d.renderer.*;
import com.ardor3d.renderer.state.RenderState;
import com.ardor3d.renderer.state.record.RendererRecord;
import com.ardor3d.renderer.state.record.TextureRecord;
@@ -238,6 +233,7 @@
                 setDrawBuffers(colorsAdded);
                 setReadBuffer(colorsAdded != 0 ? GL.GL_COLOR_ATTACHMENT0_EXT : GL.GL_NONE);

+                //enable/disable blending for the different targets(textures)
                 enableDisableBlending(colorTextures, gl);

                 // Check FBO complete
@@ -252,6 +248,8 @@
                 }

                 switchCameraOut();
+
+                ((AbstractRenderer) getParentRenderer()).clearBlendTargets();
             }

             // automatically generate mipmaps for our textures.
@@ -573,14 +571,23 @@
         }
     }

+    /**
+     * Runs through the list of color textures that will be rendered to and enables or disables blending for these
+     * by registering them as blend enabled or disabled with the parent renderer.
+     * @param colorTextures A list of the color textures that will be rendered to in color attachment order.
+     * @param gl the current GL object.
+     */
     private void enableDisableBlending(List<Texture> colorTextures, final GL gl) {
         int index = 0;
+        AbstractRenderer parentRenderer = (AbstractRenderer) getParentRenderer();
         for (Texture tex : colorTextures) {
             if(tex.getBlendMRT()){
-                gl.glEnableIndexedEXT(GL.GL_BLEND, index++);
+                parentRenderer.addEnabledBlendTarget(index++);
+//                gl.glEnableIndexedEXT(GL.GL_BLEND, index++);
             }
             else{
-                gl.glDisableIndexedEXT(GL.GL_BLEND, index++);
+                parentRenderer.addDisabledBlendTarget(index++);
+//                gl.glDisableIndexedEXT(GL.GL_BLEND, index++);
             }
         }
     }
diff -r c85e4ea11986 Ardor3D/Enhancements/ardor3d-0.8/ardor3d-jogl/src/main/java/com/ardor3d/scene/state/jogl/JoglBlendStateUtil.java
--- a/Ardor3D/Enhancements/ardor3d-0.8/ardor3d-jogl/src/main/java/com/ardor3d/scene/state/jogl/JoglBlendStateUtil.java  Mon Apr 23 14:39:13 2012 +0200
+++ b/Ardor3D/Enhancements/ardor3d-0.8/ardor3d-jogl/src/main/java/com/ardor3d/scene/state/jogl/JoglBlendStateUtil.java  Mon Apr 23 17:16:58 2012 +0200
@@ -24,6 +24,7 @@
import com.ardor3d.renderer.state.BlendState.SourceFunction;
import com.ardor3d.renderer.state.RenderState.StateType;
import com.ardor3d.renderer.state.record.BlendStateRecord;
+import java.util.Collection;

public abstract class JoglBlendStateUtil {

@@ -37,7 +38,7 @@
         final GL gl = GLU.getCurrentGL();

         if (state.isEnabled()) {
-            applyBlendEquations(gl, state.isBlendEnabled(), state, record, caps);
+            applyBlendEquations(gl, state.isBlendEnabled(), state, record, caps, renderer);
             applyBlendColor(gl, state.isBlendEnabled(), state, record, caps);
             applyBlendFunctions(gl, state.isBlendEnabled(), state, record, caps);

@@ -50,7 +51,7 @@
             }
         } else {
             // disable blend
-            applyBlendEquations(gl, false, state, record, caps);
+            applyBlendEquations(gl, false, state, record, caps, renderer);

             // disable alpha test
             applyTest(gl, false, state, record);
@@ -68,11 +69,11 @@
     }

     private static void applyBlendEquations(final GL gl, final boolean enabled, final BlendState state,
-            final BlendStateRecord record, final ContextCapabilities caps) {
+            final BlendStateRecord record, final ContextCapabilities caps, final JoglRenderer renderer) {
         if (record.isValid()) {
             if (enabled) {
                 if (!record.blendEnabled) {
-                    gl.glEnable(GL.GL_BLEND);
+                    enableDisableIndexed(gl, renderer);
                     record.blendEnabled = true;
                 }
                 final int blendEqRGB = getGLEquationValue(state.getBlendEquationRGB(), caps);
@@ -96,7 +97,7 @@

         } else {
             if (enabled) {
-                gl.glEnable(GL.GL_BLEND);
+                enableDisableIndexed(gl, renderer);
                 record.blendEnabled = true;
                 final int blendEqRGB = getGLEquationValue(state.getBlendEquationRGB(), caps);
                 if (caps.isSeparateBlendEquationsSupported()) {
@@ -115,6 +116,27 @@
         }
     }

+    /**
+     * Reads lists of indices from the supplied renderer stating which render targets blending should be enabled for an not.
+     * Enables disables blending for these.
+     * @param gl
+     * @param renderer
+     */
+    private static void enableDisableIndexed(final GL gl, final JoglRenderer renderer) {
+        Collection<Integer> enabled = renderer.getEnabledBlendTargets();
+        Collection<Integer> disabled = renderer.getDisabledBlendTargets();
+        if(enabled.isEmpty() && disabled.isEmpty()){
+            gl.glEnable(GL.GL_BLEND);
+        }
+        else{
+            for(int index: enabled){
+                gl.glEnableIndexedEXT(GL.GL_BLEND, index);
+            }
+            for(int index: disabled)
+                gl.glDisableIndexedEXT(GL.GL_BLEND, index);
+        }
+    }
+
     private static void applyBlendColor(final GL gl, final boolean enabled, final BlendState state,
             final BlendStateRecord record, final ContextCapabilities caps) {
         if (enabled) {

C:\Workspace\martin-misc>


-Martin
martifa
regular
 
Posts: 67
Joined: Thu Sep 15, 2011 5:16 am

Return to Wishlist

Who is online

Users browsing this forum: No registered users and 1 guest

cron