diff --git a/sdk/jme3-core/src/com/jme3/gde/core/properties/TextureBrowser.form b/sdk/jme3-core/src/com/jme3/gde/core/properties/TextureBrowser.form index 44a11e516..c27d6cb68 100644 --- a/sdk/jme3-core/src/com/jme3/gde/core/properties/TextureBrowser.form +++ b/sdk/jme3-core/src/com/jme3/gde/core/properties/TextureBrowser.form @@ -42,7 +42,7 @@ - + @@ -73,7 +73,7 @@ - + diff --git a/sdk/jme3-core/src/com/jme3/gde/core/properties/TextureBrowser.java b/sdk/jme3-core/src/com/jme3/gde/core/properties/TextureBrowser.java index a03c16164..21c02d9d0 100644 --- a/sdk/jme3-core/src/com/jme3/gde/core/properties/TextureBrowser.java +++ b/sdk/jme3-core/src/com/jme3/gde/core/properties/TextureBrowser.java @@ -31,16 +31,22 @@ */ package com.jme3.gde.core.properties; -import Model.DDSImageFile; +import com.jme3.asset.TextureKey; import com.jme3.gde.core.assets.ProjectAssetManager; +import com.jme3.gde.core.scene.PreviewRequest; +import com.jme3.gde.core.scene.SceneApplication; +import com.jme3.gde.core.scene.SceneListener; +import com.jme3.gde.core.scene.SceneRequest; import com.jme3.gde.core.util.TreeUtil; +import com.jme3.material.Material; +import com.jme3.math.Vector2f; +import com.jme3.math.Vector3f; +import com.jme3.scene.Geometry; +import com.jme3.scene.Spatial; +import com.jme3.scene.shape.Quad; import com.jme3.texture.Texture; -import java.awt.Color; -import java.awt.Graphics2D; +import com.jme3.util.SkyFactory; import java.awt.event.MouseEvent; -import java.awt.image.BufferedImage; -import java.io.File; -import java.io.IOException; import java.util.logging.Logger; import javax.swing.DefaultListSelectionModel; import javax.swing.Icon; @@ -52,8 +58,6 @@ import javax.swing.tree.TreeNode; import javax.swing.tree.TreePath; import javax.swing.tree.TreeSelectionModel; import jme3tools.converters.ImageToAwt; -import org.openide.filesystems.FileUtil; -import org.openide.util.Exceptions; import org.openide.util.ImageUtilities; /** @@ -65,11 +69,16 @@ import org.openide.util.ImageUtilities; * * @author bowens */ -public class TextureBrowser extends javax.swing.JDialog implements TreeSelectionListener { +public class TextureBrowser extends javax.swing.JDialog implements TreeSelectionListener, SceneListener { private ProjectAssetManager assetManager; private TexturePropertyEditor editor; + private Geometry quad; + private Geometry quad3D; + private Material material; + private Material material3D; + public TextureBrowser(java.awt.Frame parent, boolean modal, ProjectAssetManager assetManager, TexturePropertyEditor editor) { super(parent, modal); this.assetManager = assetManager; @@ -78,6 +87,22 @@ public class TextureBrowser extends javax.swing.JDialog implements TreeSelection loadAvailableTextures(); setSelectedTexture((Texture) editor.getValue()); setLocationRelativeTo(null); + + Quad quadMesh = new Quad(4.5f, 4.5f); + Quad quadMesh3D = new Quad(4.5f, 4.5f); + quadMesh3D.scaleTextureCoordinates(new Vector2f(4, 4)); + quad = new Geometry("previewQuad", quadMesh); + quad.setLocalTranslation(new Vector3f(-2.25f, -2.25f, 0)); + quad3D = new Geometry("previewQuad", quadMesh3D); + quad3D.setLocalTranslation(new Vector3f(-2.25f, -2.25f, 0)); + material3D = new Material(assetManager, "com/jme3/gde/core/properties/preview/tex3DThumb.j3md"); + material3D.setFloat("InvDepth", 1f / 16f); + material3D.setInt("Rows", 4); + material = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md"); + + //quad.setMaterial(material); + SceneApplication.getApplication().addSceneListener(this); + } /** This method is called from within the constructor to @@ -127,7 +152,7 @@ public class TextureBrowser extends javax.swing.JDialog implements TreeSelection jPanel2Layout.setVerticalGroup( jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup() - .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 420, Short.MAX_VALUE) + .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 461, Short.MAX_VALUE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(infoLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 19, javax.swing.GroupLayout.PREFERRED_SIZE)) ); @@ -183,7 +208,7 @@ public class TextureBrowser extends javax.swing.JDialog implements TreeSelection .addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jPanel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addComponent(jScrollPane3, javax.swing.GroupLayout.DEFAULT_SIZE, 485, Short.MAX_VALUE) + .addComponent(jScrollPane3, javax.swing.GroupLayout.DEFAULT_SIZE, 526, Short.MAX_VALUE) ); pack(); @@ -311,27 +336,43 @@ private void jTree1MouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:even if (node.isLeaf()) { String selected = TreeUtil.getPath(node.getUserObjectPath()); selected = selected.substring(0, selected.lastIndexOf("/")); - Texture tex = assetManager.loadTexture(selected); Icon newicon = null; if (selected.endsWith(".dds") || selected.endsWith(".DDS")) { - try { - File file = FileUtil.toFile(assetManager.getAssetFolder().getFileObject(selected)); - DDSImageFile ddsImageFile = new DDSImageFile(file); - BufferedImage bufferedImage = ddsImageFile.getData(); - newicon = new ImageIcon(bufferedImage); - } catch (IOException ex) { - Exceptions.printStackTrace(ex); - BufferedImage img = new BufferedImage(320, 240, BufferedImage.TYPE_INT_ARGB); - Graphics2D g2d = (Graphics2D) img.getGraphics(); - g2d.setColor(Color.white); - g2d.drawString("Cannot display image", 15, 15); - newicon = new ImageIcon(img); + TextureKey key = new TextureKey(selected); + assetManager.deleteFromCache(key); + Texture t = assetManager.loadTexture(key); + Spatial geom = quad; + if (key.getTextureTypeHint() == Texture.Type.TwoDimensional) { + material.setTexture("ColorMap", t); + geom.setMaterial(material); + infoLabel.setText(" " + node.getUserObject() + " w : " + t.getImage().getWidth() + " h : " + t.getImage().getHeight()); + } else if (key.getTextureTypeHint() == Texture.Type.ThreeDimensional) { + geom = quad3D; + assetManager.deleteFromCache(key); + key.setAsTexture3D(true); + t = assetManager.loadTexture(key); + material3D.setTexture("Texture", t); + geom.setMaterial(material3D); + infoLabel.setText(" " + node.getUserObject() + " (Texture3D) w : " + t.getImage().getWidth() + " h : " + t.getImage().getHeight()+ " d : " + t.getImage().getDepth()); + } else if (key.getTextureTypeHint() == Texture.Type.CubeMap) { + assetManager.deleteFromCache(key); + geom = SkyFactory.createSky(assetManager, selected, false); + infoLabel.setText(" " + node.getUserObject() + " (CubeMap) w : " + t.getImage().getWidth() + " h : " + t.getImage().getHeight()); } + + PreviewRequest request = new PreviewRequest(this, geom, 450, 450); + request.getCameraRequest().setLocation(new Vector3f(0, 0, 5.3f)); + request.getCameraRequest().setLookAt(new Vector3f(0, 0, 0), Vector3f.UNIT_Y.mult(-1)); + SceneApplication.getApplication().createPreview(request); + + } else { + Texture tex = assetManager.loadTexture(selected); newicon = ImageUtilities.image2Icon(ImageToAwt.convert(tex.getImage(), false, true, 0)); + imagePreviewLabel.setIcon(newicon); + infoLabel.setText(" " + node.getUserObject() + " w : " + newicon.getIconWidth() + " h : " + newicon.getIconHeight()); } - imagePreviewLabel.setIcon(newicon); - infoLabel.setText(" " + node.getUserObject() + " w : " + newicon.getIconWidth() + " h : " + newicon.getIconHeight()); + } else { imagePreviewLabel.setIcon(null); infoLabel.setText(""); @@ -340,6 +381,25 @@ private void jTree1MouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:even } + public void sceneRequested(SceneRequest request) { + } + + public boolean sceneClose(SceneRequest request) { + return true; + } + + public void previewRequested(PreviewRequest request) { + if (request.getRequester() == this) { + final ImageIcon icon = new ImageIcon(request.getImage()); + java.awt.EventQueue.invokeLater(new Runnable() { + + public void run() { + imagePreviewLabel.setIcon(icon); + } + }); + } + } + class ToggleSelectionModel extends DefaultListSelectionModel { boolean gestureStarted = false; diff --git a/sdk/jme3-core/src/com/jme3/gde/core/properties/preview/tex3DThumb.frag b/sdk/jme3-core/src/com/jme3/gde/core/properties/preview/tex3DThumb.frag new file mode 100644 index 000000000..f6eb25a3b --- /dev/null +++ b/sdk/jme3-core/src/com/jme3/gde/core/properties/preview/tex3DThumb.frag @@ -0,0 +1,14 @@ +uniform sampler3D m_Texture; +uniform int m_Rows; +uniform float m_InvDepth; + +varying vec2 texCoord; + +void main(){ +float depthx=floor(texCoord.x); + float depthy=(m_Rows-1.0) - floor(texCoord.y); + //vec3 texC=vec3(texCoord.x,texCoord.y ,0.7);// + + vec3 texC=vec3(fract(texCoord.x),fract(texCoord.y),(depthy*m_Rows+depthx)*m_InvDepth);// + gl_FragColor= texture3D(m_Texture,texC); +} \ No newline at end of file diff --git a/sdk/jme3-core/src/com/jme3/gde/core/properties/preview/tex3DThumb.j3md b/sdk/jme3-core/src/com/jme3/gde/core/properties/preview/tex3DThumb.j3md new file mode 100644 index 000000000..47a64a1b1 --- /dev/null +++ b/sdk/jme3-core/src/com/jme3/gde/core/properties/preview/tex3DThumb.j3md @@ -0,0 +1,18 @@ +MaterialDef Tex3DThumb { + + MaterialParameters { + Texture3D Texture + Int Rows; + Float InvDepth; + } + + Technique { + VertexShader GLSL100: com/jme3/gde/core/properties/preview/tex3DThumb.vert + FragmentShader GLSL100: com/jme3/gde/core/properties/preview/tex3DThumb.frag + + WorldParameters { + WorldViewProjectionMatrix + } + } + +} diff --git a/sdk/jme3-core/src/com/jme3/gde/core/properties/preview/tex3DThumb.vert b/sdk/jme3-core/src/com/jme3/gde/core/properties/preview/tex3DThumb.vert new file mode 100644 index 000000000..6d27bc030 --- /dev/null +++ b/sdk/jme3-core/src/com/jme3/gde/core/properties/preview/tex3DThumb.vert @@ -0,0 +1,11 @@ +uniform mat4 g_WorldViewProjectionMatrix; + +attribute vec2 inTexCoord; +attribute vec3 inPosition; + +varying vec2 texCoord; + +void main(){ + gl_Position = g_WorldViewProjectionMatrix * vec4(inPosition,1.0); + texCoord=inTexCoord; +} \ No newline at end of file diff --git a/sdk/jme3-core/src/com/jme3/gde/core/scene/PreviewRequest.java b/sdk/jme3-core/src/com/jme3/gde/core/scene/PreviewRequest.java index ef221f1cf..425820361 100644 --- a/sdk/jme3-core/src/com/jme3/gde/core/scene/PreviewRequest.java +++ b/sdk/jme3-core/src/com/jme3/gde/core/scene/PreviewRequest.java @@ -33,7 +33,6 @@ package com.jme3.gde.core.scene; import com.jme3.math.Quaternion; import com.jme3.math.Vector3f; -import com.jme3.renderer.Camera; import com.jme3.scene.Spatial; import java.awt.image.BufferedImage; @@ -49,9 +48,15 @@ public class PreviewRequest { private CameraRequest cameraRequest; public PreviewRequest(Object requester, Spatial spatial) { + this(requester, spatial, 120, 120); + } + + public PreviewRequest(Object requester, Spatial spatial, int width, int height) { this.requester = requester; this.spatial = spatial; cameraRequest = new CameraRequest(); + cameraRequest.width = width; + cameraRequest.height = height; } /** @@ -92,6 +97,7 @@ public class PreviewRequest { Quaternion rotation = null; Vector3f lookAt = null; Vector3f up = null; + int width, height; public void setLocation(Vector3f location) { this.location = location; @@ -105,5 +111,22 @@ public class PreviewRequest { public void setRotation(Quaternion rotation) { this.rotation = rotation; } + + public int getWidth() { + return width; + } + + public void setWidth(int width) { + this.width = width; + } + + public int getHeight() { + return height; + } + + public void setHeight(int height) { + this.height = height; + } + } } diff --git a/sdk/jme3-core/src/com/jme3/gde/core/scene/ScenePreviewProcessor.java b/sdk/jme3-core/src/com/jme3/gde/core/scene/ScenePreviewProcessor.java index 5fdea66d1..3f23d35ef 100644 --- a/sdk/jme3-core/src/com/jme3/gde/core/scene/ScenePreviewProcessor.java +++ b/sdk/jme3-core/src/com/jme3/gde/core/scene/ScenePreviewProcessor.java @@ -55,10 +55,10 @@ import java.util.concurrent.ConcurrentLinkedQueue; * @author normenhansen */ public class ScenePreviewProcessor implements SceneProcessor { - - private static final int width = 120, height = 120; - private final ByteBuffer cpuBuf = BufferUtils.createByteBuffer(width * height * 4); - private final byte[] cpuArray = new byte[width * height * 4]; + + private static int width = 120, height = 120; + private ByteBuffer cpuBuf = BufferUtils.createByteBuffer(width * height * 4); + private byte[] cpuArray = new byte[width * height * 4]; protected Node previewNode = new Node("Preview Node"); protected JmeSpatial previewSpat = null; private FrameBuffer offBuffer; @@ -68,27 +68,55 @@ public class ScenePreviewProcessor implements SceneProcessor { private PreviewRequest currentPreviewRequest; private RenderManager rm; private PointLight light; - + public void addRequest(PreviewRequest request) { previewQueue.add(request); + boolean reInit = false; + if (request.getCameraRequest().getWidth() != width) { + reInit = true; + width = request.getCameraRequest().getWidth(); + } + if (request.getCameraRequest().getHeight() != height) { + reInit = true; + height = request.getCameraRequest().getHeight(); + } + if (reInit) { + setupPreviewView(); + } } - + private void update(float tpf) { previewNode.updateLogicalState(tpf); previewNode.updateGeometricState(); } - + public void setupPreviewView() { - offCamera = new Camera(width, height); + if (offCamera == null) { + offCamera = new Camera(width, height); + } else { + offCamera.resize(width, height, true); + } // create a pre-view. a view that is rendered before the main view - offView = SceneApplication.getApplication().getRenderManager().createPreView("Offscreen View", offCamera); - offView.setBackgroundColor(ColorRGBA.DarkGray); - offView.setClearFlags(true, true, true); - - offView.addProcessor(this); + if (offView == null) { + offView = SceneApplication.getApplication().getRenderManager().createPreView("Offscreen View", offCamera); + offView.setBackgroundColor(ColorRGBA.DarkGray); + offView.setClearFlags(true, true, true); + offView.addProcessor(this); + // setup framebuffer's scene + light = new PointLight(); + light.setPosition(offCamera.getLocation()); + light.setColor(ColorRGBA.White); + previewNode.addLight(light); + + // attach the scene to the viewport to be rendered + offView.attachScene(previewNode); + } + + cpuBuf = BufferUtils.createByteBuffer(width * height * 4); + cpuArray = new byte[width * height * 4]; - // create offscreen framebuffer + // create offscreen framebuffer offBuffer = new FrameBuffer(width, height, 0); //setup framebuffer's cam @@ -103,27 +131,20 @@ public class ScenePreviewProcessor implements SceneProcessor { //set viewport to render to offscreen framebuffer offView.setOutputFrameBuffer(offBuffer); - // setup framebuffer's scene - light = new PointLight(); - light.setPosition(offCamera.getLocation()); - light.setColor(ColorRGBA.White); - previewNode.addLight(light); - // attach the scene to the viewport to be rendered - offView.attachScene(previewNode); } - + public void initialize(RenderManager rm, ViewPort vp) { this.rm = rm; } - + public void reshape(ViewPort vp, int i, int i1) { } - + public boolean isInitialized() { return true; } - + public void preFrame(float f) { currentPreviewRequest = previewQueue.poll(); if (currentPreviewRequest != null) { @@ -141,10 +162,10 @@ public class ScenePreviewProcessor implements SceneProcessor { } update(f); } - + public void postQueue(RenderQueue rq) { } - + public void postFrame(FrameBuffer fb) { if (currentPreviewRequest != null) { cpuBuf.clear(); @@ -161,26 +182,26 @@ public class ScenePreviewProcessor implements SceneProcessor { byte g = cpuArray[i + 1]; byte r = cpuArray[i + 2]; byte a = cpuArray[i + 3]; - + cpuArray[i + 0] = a; cpuArray[i + 1] = b; cpuArray[i + 2] = g; cpuArray[i + 3] = r; } - + BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_4BYTE_ABGR); WritableRaster wr = image.getRaster(); DataBufferByte db = (DataBufferByte) wr.getDataBuffer(); System.arraycopy(cpuArray, 0, db.getData(), 0, cpuArray.length); - + currentPreviewRequest.setImage(image); previewNode.detachAllChildren(); SceneApplication.getApplication().notifySceneListeners(currentPreviewRequest); currentPreviewRequest = null; } } - + public void cleanup() { } }