Răsfoiți Sursa

- Framebuffer can now render to a cube map face, thanks to dflemstr
http://jmonkeyengine.org/groups/contribution-depot-jme3/forum/topic/how-do-i-render-to-a-face-of-a-texturecubemap/?#post-171990

git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@9363 75d07b2b-3a1a-0410-a2c5-0572b91ccdca

rem..om 13 ani în urmă
părinte
comite
311242b6d9

+ 48 - 3
engine/src/core/com/jme3/texture/FrameBuffer.java

@@ -92,7 +92,8 @@ public class FrameBuffer extends NativeObject {
         Image.Format format;
         int id = -1;
         int slot = -1;
-
+        int face = -1;
+        
         /**
          * @return The image format of the render buffer.
          */
@@ -128,6 +129,10 @@ public class FrameBuffer extends NativeObject {
         public int getSlot() {
             return slot;
         }
+        
+        public int getFace() {
+            return face;
+        }
 
         public void resetObject(){
             id = -1;
@@ -305,8 +310,8 @@ public class FrameBuffer extends NativeObject {
     /**
      * Set the color texture to use for this framebuffer.
      * This automatically clears all existing textures added previously
-     * with {@link FrameBuffer#addColorTexture(com.jme3.texture.Texture2D) }
-     * and adds this texture as the only target.
+     * with {@link FrameBuffer#addColorTexture } and adds this texture as the
+     * only target.
      * 
      * @param tex The color texture to set.
      */
@@ -314,6 +319,20 @@ public class FrameBuffer extends NativeObject {
         clearColorTargets();
         addColorTexture(tex);
     }
+    
+    /**
+     * Set the color texture to use for this framebuffer.
+     * This automatically clears all existing textures added previously
+     * with {@link FrameBuffer#addColorTexture } and adds this texture as the
+     * only target.
+     *
+     * @param tex The cube-map texture to set.
+     * @param face The face of the cube-map to render to.
+     */
+    public void setColorTexture(TextureCubeMap tex, TextureCubeMap.Face face) {
+        clearColorTargets();
+        addColorTexture(tex, face);
+    }
 
     /**
      * Clears all color targets that were set or added previously.
@@ -345,6 +364,32 @@ public class FrameBuffer extends NativeObject {
 
         colorBufs.add(colorBuf);
     }
+    
+     /**
+     * Add a color texture to use for this framebuffer.
+     * If MRT is enabled, then each subsequently added texture can be
+     * rendered to through a shader that writes to the array <code>gl_FragData</code>.
+     * If MRT is not enabled, then the index set with {@link FrameBuffer#setTargetIndex(int) }
+     * is rendered to by the shader.
+     *
+     * @param tex The cube-map texture to add.
+     * @param face The face of the cube-map to render to.
+     */
+    public void addColorTexture(TextureCubeMap tex, TextureCubeMap.Face face) {
+        if (id != -1)
+            throw new UnsupportedOperationException("FrameBuffer already initialized.");
+
+        Image img = tex.getImage();
+        checkSetTexture(tex, false);
+
+        RenderBuffer colorBuf = new RenderBuffer();
+        colorBuf.slot = colorBufs.size();
+        colorBuf.tex = tex;
+        colorBuf.format = img.getFormat();
+        colorBuf.face = face.ordinal();
+
+        colorBufs.add(colorBuf);
+    }
 
     /**
      * Set the depth texture to use for this framebuffer.

+ 20 - 3
engine/src/core/com/jme3/texture/TextureCubeMap.java

@@ -37,6 +37,8 @@ import com.jme3.export.JmeExporter;
 import com.jme3.export.JmeImporter;
 import com.jme3.export.OutputCapsule;
 import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
 
 /**
  * Describes a cubemap texture.
@@ -63,9 +65,10 @@ public class TextureCubeMap extends Texture {
      * Face of the Cubemap as described by its directional offset from the
      * origin.
      */
-//    public enum Face {
-//        PositiveX, NegativeX, PositiveY, NegativeY, PositiveZ, NegativeZ;
-//    }
+    public enum Face {
+
+        PositiveX, NegativeX, PositiveY, NegativeY, PositiveZ, NegativeZ;
+    }
 
     public TextureCubeMap(){
         super();
@@ -75,6 +78,20 @@ public class TextureCubeMap extends Texture {
         super();
         setImage(img);
     }
+    
+    public TextureCubeMap(int width, int height, Image.Format format){
+        this(createEmptyLayeredImage(width, height, 6, format));
+    }
+
+    private static Image createEmptyLayeredImage(int width, int height,
+            int layerCount, Image.Format format) {
+        ArrayList<ByteBuffer> layers = new ArrayList<ByteBuffer>();
+        for(int i = 0; i < layerCount; i++) {
+            layers.add(null);
+        }
+        Image image = new Image(format, width, height, 0, layers);
+        return image;
+    }
 
     public Texture createSimpleClone() {
         return createSimpleClone(new TextureCubeMap());

+ 21 - 15
engine/src/lwjgl/com/jme3/renderer/lwjgl/LwjglRenderer.java

@@ -267,8 +267,8 @@ public class LwjglRenderer implements Renderer {
         if (ctxCaps.GL_ARB_depth_buffer_float) {
             caps.add(Caps.FloatDepthBuffer);
         }
-        
-        if (ctxCaps.OpenGL30){
+
+        if (ctxCaps.OpenGL30) {
             caps.add(Caps.PackedDepthStencilBuffer);
         }
 
@@ -449,7 +449,7 @@ public class LwjglRenderer implements Renderer {
     }
 
     public void setAlphaToCoverage(boolean value) {
-        if (caps.contains(Caps.Multisample)){
+        if (caps.contains(Caps.Multisample)) {
             if (value) {
                 glEnable(ARBMultisample.GL_SAMPLE_ALPHA_TO_COVERAGE_ARB);
             } else {
@@ -992,10 +992,10 @@ public class LwjglRenderer implements Renderer {
                         new Object[]{source.getName(), infoLog});
             } else {
                 logger.log(Level.FINE, "{0} compile success", source.getName());
-            }            
-        } else {                        
+            }
+        } else {
             logger.log(Level.WARNING, "Bad compile of:\n{0}",
-                    new Object[]{ShaderDebug.formatShaderSource(source.getDefines(), source.getSource(),stringBuf.toString())});
+                    new Object[]{ShaderDebug.formatShaderSource(source.getDefines(), source.getSource(), stringBuf.toString())});
             if (infoLog != null) {
                 throw new RendererException("compile error in:" + source + " error:" + infoLog);
             } else {
@@ -1362,7 +1362,7 @@ public class LwjglRenderer implements Renderer {
         }
 
         TextureUtil.GLImageFormat glFmt = TextureUtil.getImageFormatWithError(rb.getFormat());
-        
+
         if (fb.getSamples() > 1 && GLContext.getCapabilities().GL_EXT_framebuffer_multisample) {
             int samples = fb.getSamples();
             if (maxFBOSamples < samples) {
@@ -1406,7 +1406,7 @@ public class LwjglRenderer implements Renderer {
 
         glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
                 convertAttachmentSlot(rb.getSlot()),
-                convertTextureType(tex.getType(), image.getMultiSamples()),
+                convertTextureType(tex.getType(), image.getMultiSamples(), rb.getFace()),
                 image.getId(),
                 0);
     }
@@ -1503,7 +1503,7 @@ public class LwjglRenderer implements Renderer {
                         && tex.getMinFilter().usesMipMapLevels()) {
                     setTexture(0, rb.getTexture());
 
-                    int textureType = convertTextureType(tex.getType(), tex.getImage().getMultiSamples());
+                    int textureType = convertTextureType(tex.getType(), tex.getImage().getMultiSamples(), rb.getFace());
                     glEnable(textureType);
                     glGenerateMipmapEXT(textureType);
                     glDisable(textureType);
@@ -1655,7 +1655,7 @@ public class LwjglRenderer implements Renderer {
     /*********************************************************************\
     |* Textures                                                          *|
     \*********************************************************************/
-    private int convertTextureType(Texture.Type type, int samples) {
+    private int convertTextureType(Texture.Type type, int samples, int face) {
         switch (type) {
             case TwoDimensional:
                 if (samples > 1) {
@@ -1672,7 +1672,13 @@ public class LwjglRenderer implements Renderer {
             case ThreeDimensional:
                 return GL_TEXTURE_3D;
             case CubeMap:
-                return GL_TEXTURE_CUBE_MAP;
+                if (face < 0) {
+                    return GL_TEXTURE_CUBE_MAP;
+                } else if (face < 6) {
+                    return GL_TEXTURE_CUBE_MAP_POSITIVE_X + face;
+                } else {
+                    throw new UnsupportedOperationException("Invalid cube map face index: " + face);
+                }
             default:
                 throw new UnsupportedOperationException("Unknown texture type: " + type);
         }
@@ -1728,7 +1734,7 @@ public class LwjglRenderer implements Renderer {
     @SuppressWarnings("fallthrough")
     private void setupTextureParams(Texture tex) {
         Image image = tex.getImage();
-        int target = convertTextureType(tex.getType(), image != null ? image.getMultiSamples() : 1);
+        int target = convertTextureType(tex.getType(), image != null ? image.getMultiSamples() : 1, -1);
 
         // filter things
         int minFilter = convertMinFilter(tex.getMinFilter());
@@ -1787,8 +1793,8 @@ public class LwjglRenderer implements Renderer {
             statistics.onNewTexture();
         }
 
-        // bind texture
-        int target = convertTextureType(type, img.getMultiSamples());
+        // bind texture       
+        int target = convertTextureType(type, img.getMultiSamples(), -1);
         if (context.boundTextureUnit != unit) {
             glActiveTexture(GL_TEXTURE0 + unit);
             context.boundTextureUnit = unit;
@@ -1893,7 +1899,7 @@ public class LwjglRenderer implements Renderer {
 
         Image[] textures = context.boundTextures;
 
-        int type = convertTextureType(tex.getType(), image.getMultiSamples());
+        int type = convertTextureType(tex.getType(), image.getMultiSamples(), -1);
 //        if (!context.textureIndexList.moveToNew(unit)) {
 //             if (context.boundTextureUnit != unit){
 //                glActiveTexture(GL_TEXTURE0 + unit);