From 7ce251e222bdb7dff12b781f9274d6a4549497b3 Mon Sep 17 00:00:00 2001 From: Nehon Date: Mon, 19 Jan 2015 20:54:24 +0100 Subject: [PATCH] SDK, the ShaderNodes editor should not go into an error frenzy when the shader compilation fail anymore. The MaterialPreviewRenderer now uses something similar as the MaterialDebugAppState. The material is preloaded and not refreshed if the compilation failed. --- .../materialdefinition/editor/MatPanel.java | 1 - .../materials/MaterialPreviewRenderer.java | 94 +++++++++++++++---- 2 files changed, 74 insertions(+), 21 deletions(-) diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/MatPanel.java b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/MatPanel.java index b578d5ee0..88cb63286 100644 --- a/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/MatPanel.java +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materialdefinition/editor/MatPanel.java @@ -4,7 +4,6 @@ */ package com.jme3.gde.materialdefinition.editor; -import com.jme3.gde.core.assets.ProjectAssetManager; import com.jme3.gde.materials.MaterialPreviewRenderer; import com.jme3.material.Material; import java.awt.Component; diff --git a/sdk/jme3-materialeditor/src/com/jme3/gde/materials/MaterialPreviewRenderer.java b/sdk/jme3-materialeditor/src/com/jme3/gde/materials/MaterialPreviewRenderer.java index 84a63b5a6..b92de49c2 100644 --- a/sdk/jme3-materialeditor/src/com/jme3/gde/materials/MaterialPreviewRenderer.java +++ b/sdk/jme3-materialeditor/src/com/jme3/gde/materials/MaterialPreviewRenderer.java @@ -4,21 +4,26 @@ */ package com.jme3.gde.materials; +import com.jme3.asset.DesktopAssetManager; import com.jme3.asset.MaterialKey; 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.material.MatParam; import com.jme3.material.Material; import com.jme3.math.FastMath; import com.jme3.math.Quaternion; import com.jme3.math.Vector3f; +import com.jme3.renderer.RendererException; import com.jme3.scene.Geometry; import com.jme3.scene.shape.Box; import com.jme3.scene.shape.Quad; import com.jme3.scene.shape.Sphere; +import com.jme3.util.MaterialDebugAppState; import com.jme3.util.TangentBinormalGenerator; +import java.util.concurrent.Callable; import java.util.logging.Level; import java.util.logging.Logger; import javax.swing.ImageIcon; @@ -75,36 +80,85 @@ public class MaterialPreviewRenderer implements SceneListener { public void showMaterial(ProjectAssetManager assetManager, String materialFileName) { if (!init) { init(); + } + MaterialKey key = new MaterialKey(assetManager.getRelativeAssetPath(materialFileName)); + assetManager.deleteFromCache(key); + Material mat = (Material) assetManager.loadAsset(key); + if (mat != null) { + showMaterial(mat); } - try { - MaterialKey key = new MaterialKey(assetManager.getRelativeAssetPath(materialFileName)); - assetManager.deleteFromCache(key); - Material mat = (Material) assetManager.loadAsset(key); - if (mat != null) { - currentMaterial = mat; - showMaterial(mat); - } - } catch (Exception e) { - } + } - public void showMaterial(Material m) { + public void showMaterial(final Material m) { if (!init) { init(); } - currentGeom.setMaterial(m); - try { - if (currentGeom.getMaterial() != null) { - PreviewRequest request = new PreviewRequest(this, currentGeom, label.getWidth(), label.getHeight()); - request.getCameraRequest().setLocation(new Vector3f(0, 0, 7)); - request.getCameraRequest().setLookAt(new Vector3f(0, 0, 0), Vector3f.UNIT_Y); - SceneApplication.getApplication().createPreview(request); + final DesktopAssetManager assetManager = (DesktopAssetManager) SceneApplication.getApplication().getAssetManager(); + SceneApplication.getApplication().enqueue(new Callable() { + + public Material call() throws Exception { + final Material mat = reloadMaterial(m, assetManager); + if (mat != null) { + java.awt.EventQueue.invokeLater(new Runnable() { + public void run() { + currentMaterial = mat; + currentGeom.setMaterial(mat); + try { + if (currentGeom.getMaterial() != null) { + PreviewRequest request = new PreviewRequest(MaterialPreviewRenderer.this, currentGeom, label.getWidth(), label.getHeight()); + request.getCameraRequest().setLocation(new Vector3f(0, 0, 7)); + request.getCameraRequest().setLookAt(new Vector3f(0, 0, 0), Vector3f.UNIT_Y); + SceneApplication.getApplication().createPreview(request); + } + } catch (Exception e) { + Logger.getLogger(MaterialPreviewRenderer.class.getName()).log(Level.SEVERE, "Error rendering material" + e.getMessage()); + } + } + }); + + } + return mat; } - } catch (Exception e) { - Logger.getLogger(MaterialPreviewRenderer.class.getName()).log(Level.SEVERE, "Error rendering material" + e.getMessage()); + }); + + } + + public Material reloadMaterial(Material mat, DesktopAssetManager assetManager) { + //clear the entire cache, there might be more clever things to do, like clearing only the matdef, and the associated shaders. + + assetManager.clearCache(); + + //creating a dummy mat with the mat def of the mat to reload + Material dummy = new Material(mat.getMaterialDef()); + + for (MatParam matParam : mat.getParams()) { + dummy.setParam(matParam.getName(), matParam.getVarType(), matParam.getValue()); + } + + dummy.getAdditionalRenderState().set(mat.getAdditionalRenderState()); + + //creating a dummy geom and assigning the dummy material to it + Geometry dummyGeom = new Geometry("dummyGeom", new Box(1f, 1f, 1f)); + dummyGeom.setMaterial(dummy); + + try { + //preloading the dummyGeom, this call will compile the shader again + SceneApplication.getApplication().getRenderManager().preloadScene(dummyGeom); + } catch (RendererException e) { + //compilation error, the shader code will be output to the console + //the following code will output the error + //System.err.println(e.getMessage()); + Logger.getLogger(MaterialDebugAppState.class.getName()).log(Level.SEVERE, e.getMessage()); + return null; } + + //Logger.getLogger(MaterialDebugAppState.class.getName()).log(Level.INFO, "Material succesfully reloaded"); + //System.out.println("Material succesfully reloaded"); + return dummy; } + public void switchDisplay(DisplayType type) { switch (type) { case Box: