- PreviewRequest can now be requested with a given size
- DSS preview is now supported in texture browser for Texture2D, Texture3D and CubeMaps

git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@8013 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
3.0
rem..om 13 years ago
parent 70af91d981
commit 773f35131d
  1. 4
      sdk/jme3-core/src/com/jme3/gde/core/properties/TextureBrowser.form
  2. 112
      sdk/jme3-core/src/com/jme3/gde/core/properties/TextureBrowser.java
  3. 14
      sdk/jme3-core/src/com/jme3/gde/core/properties/preview/tex3DThumb.frag
  4. 18
      sdk/jme3-core/src/com/jme3/gde/core/properties/preview/tex3DThumb.j3md
  5. 11
      sdk/jme3-core/src/com/jme3/gde/core/properties/preview/tex3DThumb.vert
  6. 25
      sdk/jme3-core/src/com/jme3/gde/core/scene/PreviewRequest.java
  7. 83
      sdk/jme3-core/src/com/jme3/gde/core/scene/ScenePreviewProcessor.java

@ -42,7 +42,7 @@
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Component id="jPanel3" min="-2" max="-2" attributes="0"/> <Component id="jPanel3" min="-2" max="-2" attributes="0"/>
</Group> </Group>
<Component id="jScrollPane3" alignment="0" pref="485" max="32767" attributes="0"/> <Component id="jScrollPane3" alignment="0" pref="526" max="32767" attributes="0"/>
</Group> </Group>
</DimensionLayout> </DimensionLayout>
</Layout> </Layout>
@ -73,7 +73,7 @@
<DimensionLayout dim="1"> <DimensionLayout dim="1">
<Group type="103" groupAlignment="0" attributes="0"> <Group type="103" groupAlignment="0" attributes="0">
<Group type="102" alignment="1" attributes="0"> <Group type="102" alignment="1" attributes="0">
<Component id="jScrollPane2" pref="420" max="32767" attributes="1"/> <Component id="jScrollPane2" pref="461" max="32767" attributes="1"/>
<EmptySpace max="-2" attributes="0"/> <EmptySpace max="-2" attributes="0"/>
<Component id="infoLabel" min="-2" pref="19" max="-2" attributes="0"/> <Component id="infoLabel" min="-2" pref="19" max="-2" attributes="0"/>
</Group> </Group>

@ -31,16 +31,22 @@
*/ */
package com.jme3.gde.core.properties; 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.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.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 com.jme3.texture.Texture;
import java.awt.Color; import com.jme3.util.SkyFactory;
import java.awt.Graphics2D;
import java.awt.event.MouseEvent; import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.logging.Logger; import java.util.logging.Logger;
import javax.swing.DefaultListSelectionModel; import javax.swing.DefaultListSelectionModel;
import javax.swing.Icon; import javax.swing.Icon;
@ -52,8 +58,6 @@ import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath; import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel; import javax.swing.tree.TreeSelectionModel;
import jme3tools.converters.ImageToAwt; import jme3tools.converters.ImageToAwt;
import org.openide.filesystems.FileUtil;
import org.openide.util.Exceptions;
import org.openide.util.ImageUtilities; import org.openide.util.ImageUtilities;
/** /**
@ -65,11 +69,16 @@ import org.openide.util.ImageUtilities;
* *
* @author bowens * @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 ProjectAssetManager assetManager;
private TexturePropertyEditor editor; 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) { public TextureBrowser(java.awt.Frame parent, boolean modal, ProjectAssetManager assetManager, TexturePropertyEditor editor) {
super(parent, modal); super(parent, modal);
this.assetManager = assetManager; this.assetManager = assetManager;
@ -78,6 +87,22 @@ public class TextureBrowser extends javax.swing.JDialog implements TreeSelection
loadAvailableTextures(); loadAvailableTextures();
setSelectedTexture((Texture) editor.getValue()); setSelectedTexture((Texture) editor.getValue());
setLocationRelativeTo(null); 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 /** 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.setVerticalGroup(
jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup() .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) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(infoLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 19, javax.swing.GroupLayout.PREFERRED_SIZE)) .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) .addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jPanel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .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(); pack();
@ -311,27 +336,43 @@ private void jTree1MouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:even
if (node.isLeaf()) { if (node.isLeaf()) {
String selected = TreeUtil.getPath(node.getUserObjectPath()); String selected = TreeUtil.getPath(node.getUserObjectPath());
selected = selected.substring(0, selected.lastIndexOf("/")); selected = selected.substring(0, selected.lastIndexOf("/"));
Texture tex = assetManager.loadTexture(selected);
Icon newicon = null; Icon newicon = null;
if (selected.endsWith(".dds") || selected.endsWith(".DDS")) { if (selected.endsWith(".dds") || selected.endsWith(".DDS")) {
try { TextureKey key = new TextureKey(selected);
File file = FileUtil.toFile(assetManager.getAssetFolder().getFileObject(selected)); assetManager.deleteFromCache(key);
DDSImageFile ddsImageFile = new DDSImageFile(file); Texture t = assetManager.loadTexture(key);
BufferedImage bufferedImage = ddsImageFile.getData(); Spatial geom = quad;
newicon = new ImageIcon(bufferedImage); if (key.getTextureTypeHint() == Texture.Type.TwoDimensional) {
} catch (IOException ex) { material.setTexture("ColorMap", t);
Exceptions.printStackTrace(ex); geom.setMaterial(material);
BufferedImage img = new BufferedImage(320, 240, BufferedImage.TYPE_INT_ARGB); infoLabel.setText(" " + node.getUserObject() + " w : " + t.getImage().getWidth() + " h : " + t.getImage().getHeight());
Graphics2D g2d = (Graphics2D) img.getGraphics(); } else if (key.getTextureTypeHint() == Texture.Type.ThreeDimensional) {
g2d.setColor(Color.white); geom = quad3D;
g2d.drawString("Cannot display image", 15, 15); assetManager.deleteFromCache(key);
newicon = new ImageIcon(img); 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 { } else {
Texture tex = assetManager.loadTexture(selected);
newicon = ImageUtilities.image2Icon(ImageToAwt.convert(tex.getImage(), false, true, 0)); 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 { } else {
imagePreviewLabel.setIcon(null); imagePreviewLabel.setIcon(null);
infoLabel.setText(""); 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 { class ToggleSelectionModel extends DefaultListSelectionModel {
boolean gestureStarted = false; boolean gestureStarted = false;

@ -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);
}

@ -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
}
}
}

@ -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;
}

@ -33,7 +33,6 @@ package com.jme3.gde.core.scene;
import com.jme3.math.Quaternion; import com.jme3.math.Quaternion;
import com.jme3.math.Vector3f; import com.jme3.math.Vector3f;
import com.jme3.renderer.Camera;
import com.jme3.scene.Spatial; import com.jme3.scene.Spatial;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
@ -49,9 +48,15 @@ public class PreviewRequest {
private CameraRequest cameraRequest; private CameraRequest cameraRequest;
public PreviewRequest(Object requester, Spatial spatial) { 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.requester = requester;
this.spatial = spatial; this.spatial = spatial;
cameraRequest = new CameraRequest(); cameraRequest = new CameraRequest();
cameraRequest.width = width;
cameraRequest.height = height;
} }
/** /**
@ -92,6 +97,7 @@ public class PreviewRequest {
Quaternion rotation = null; Quaternion rotation = null;
Vector3f lookAt = null; Vector3f lookAt = null;
Vector3f up = null; Vector3f up = null;
int width, height;
public void setLocation(Vector3f location) { public void setLocation(Vector3f location) {
this.location = location; this.location = location;
@ -105,5 +111,22 @@ public class PreviewRequest {
public void setRotation(Quaternion rotation) { public void setRotation(Quaternion rotation) {
this.rotation = 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;
}
} }
} }

@ -55,10 +55,10 @@ import java.util.concurrent.ConcurrentLinkedQueue;
* @author normenhansen * @author normenhansen
*/ */
public class ScenePreviewProcessor implements SceneProcessor { public class ScenePreviewProcessor implements SceneProcessor {
private static final int width = 120, height = 120; private static int width = 120, height = 120;
private final ByteBuffer cpuBuf = BufferUtils.createByteBuffer(width * height * 4); private ByteBuffer cpuBuf = BufferUtils.createByteBuffer(width * height * 4);
private final byte[] cpuArray = new byte[width * height * 4]; private byte[] cpuArray = new byte[width * height * 4];
protected Node previewNode = new Node("Preview Node"); protected Node previewNode = new Node("Preview Node");
protected JmeSpatial previewSpat = null; protected JmeSpatial previewSpat = null;
private FrameBuffer offBuffer; private FrameBuffer offBuffer;
@ -68,27 +68,55 @@ public class ScenePreviewProcessor implements SceneProcessor {
private PreviewRequest currentPreviewRequest; private PreviewRequest currentPreviewRequest;
private RenderManager rm; private RenderManager rm;
private PointLight light; private PointLight light;
public void addRequest(PreviewRequest request) { public void addRequest(PreviewRequest request) {
previewQueue.add(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) { private void update(float tpf) {
previewNode.updateLogicalState(tpf); previewNode.updateLogicalState(tpf);
previewNode.updateGeometricState(); previewNode.updateGeometricState();
} }
public void setupPreviewView() { 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 // create a pre-view. a view that is rendered before the main view
offView = SceneApplication.getApplication().getRenderManager().createPreView("Offscreen View", offCamera); if (offView == null) {
offView.setBackgroundColor(ColorRGBA.DarkGray); offView = SceneApplication.getApplication().getRenderManager().createPreView("Offscreen View", offCamera);
offView.setClearFlags(true, true, true); offView.setBackgroundColor(ColorRGBA.DarkGray);
offView.setClearFlags(true, true, true);
offView.addProcessor(this); 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); offBuffer = new FrameBuffer(width, height, 0);
//setup framebuffer's cam //setup framebuffer's cam
@ -103,27 +131,20 @@ public class ScenePreviewProcessor implements SceneProcessor {
//set viewport to render to offscreen framebuffer //set viewport to render to offscreen framebuffer
offView.setOutputFrameBuffer(offBuffer); 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) { public void initialize(RenderManager rm, ViewPort vp) {
this.rm = rm; this.rm = rm;
} }
public void reshape(ViewPort vp, int i, int i1) { public void reshape(ViewPort vp, int i, int i1) {
} }
public boolean isInitialized() { public boolean isInitialized() {
return true; return true;
} }
public void preFrame(float f) { public void preFrame(float f) {
currentPreviewRequest = previewQueue.poll(); currentPreviewRequest = previewQueue.poll();
if (currentPreviewRequest != null) { if (currentPreviewRequest != null) {
@ -141,10 +162,10 @@ public class ScenePreviewProcessor implements SceneProcessor {
} }
update(f); update(f);
} }
public void postQueue(RenderQueue rq) { public void postQueue(RenderQueue rq) {
} }
public void postFrame(FrameBuffer fb) { public void postFrame(FrameBuffer fb) {
if (currentPreviewRequest != null) { if (currentPreviewRequest != null) {
cpuBuf.clear(); cpuBuf.clear();
@ -161,26 +182,26 @@ public class ScenePreviewProcessor implements SceneProcessor {
byte g = cpuArray[i + 1]; byte g = cpuArray[i + 1];
byte r = cpuArray[i + 2]; byte r = cpuArray[i + 2];
byte a = cpuArray[i + 3]; byte a = cpuArray[i + 3];
cpuArray[i + 0] = a; cpuArray[i + 0] = a;
cpuArray[i + 1] = b; cpuArray[i + 1] = b;
cpuArray[i + 2] = g; cpuArray[i + 2] = g;
cpuArray[i + 3] = r; cpuArray[i + 3] = r;
} }
BufferedImage image = new BufferedImage(width, height, BufferedImage image = new BufferedImage(width, height,
BufferedImage.TYPE_4BYTE_ABGR); BufferedImage.TYPE_4BYTE_ABGR);
WritableRaster wr = image.getRaster(); WritableRaster wr = image.getRaster();
DataBufferByte db = (DataBufferByte) wr.getDataBuffer(); DataBufferByte db = (DataBufferByte) wr.getDataBuffer();
System.arraycopy(cpuArray, 0, db.getData(), 0, cpuArray.length); System.arraycopy(cpuArray, 0, db.getData(), 0, cpuArray.length);
currentPreviewRequest.setImage(image); currentPreviewRequest.setImage(image);
previewNode.detachAllChildren(); previewNode.detachAllChildren();
SceneApplication.getApplication().notifySceneListeners(currentPreviewRequest); SceneApplication.getApplication().notifySceneListeners(currentPreviewRequest);
currentPreviewRequest = null; currentPreviewRequest = null;
} }
} }
public void cleanup() { public void cleanup() {
} }
} }

Loading…
Cancel
Save