diff --git a/gradle.properties b/gradle.properties index 4d8b56aa7..00429d65a 100644 --- a/gradle.properties +++ b/gradle.properties @@ -22,4 +22,4 @@ bulletFolder = bullet-2.82-r2704 bulletZipFile = bullet.zip # Path for downloading NetBeans Base -netbeansUrl = http://download.netbeans.org/netbeans/8.0.2/final/zip/netbeans-8.0.2-201411181905-javase.zip \ No newline at end of file +netbeansUrl = http://download.netbeans.org/netbeans/8.0.2/final/zip/netbeans-8.0.2-201411181905-javase.zip diff --git a/jme3-core/src/main/java/com/jme3/asset/DesktopAssetManager.java b/jme3-core/src/main/java/com/jme3/asset/DesktopAssetManager.java index bbf4f9472..4364f3b60 100644 --- a/jme3-core/src/main/java/com/jme3/asset/DesktopAssetManager.java +++ b/jme3-core/src/main/java/com/jme3/asset/DesktopAssetManager.java @@ -450,16 +450,11 @@ public class DesktopAssetManager implements AssetManager { } shader = shaderGenerator.generateShader(); } else { - String vertName = key.getVertName(); - String fragName = key.getFragName(); - - String vertSource = (String) loadAsset(new AssetKey(vertName)); - String fragSource = (String) loadAsset(new AssetKey(fragName)); - shader = new Shader(); shader.initialize(); - shader.addSource(Shader.ShaderType.Vertex, vertName, vertSource, key.getDefines().getCompiled(), key.getVertexShaderLanguage()); - shader.addSource(Shader.ShaderType.Fragment, fragName, fragSource, key.getDefines().getCompiled(), key.getFragmentShaderLanguage()); + for (Shader.ShaderType shaderType : key.getUsedShaderPrograms()) { + shader.addSource(shaderType,key.getShaderProgramName(shaderType),(String) loadAsset(new AssetKey(key.getShaderProgramName(shaderType))),key.getDefines().getCompiled(),key.getShaderProgramLanguage(shaderType)); + } } cache.addToCache(key, shader); diff --git a/jme3-core/src/main/java/com/jme3/material/Technique.java b/jme3-core/src/main/java/com/jme3/material/Technique.java index ba2bc72f9..8321991bf 100644 --- a/jme3-core/src/main/java/com/jme3/material/Technique.java +++ b/jme3-core/src/main/java/com/jme3/material/Technique.java @@ -190,11 +190,7 @@ public class Technique /* implements Savable */ { private void loadShader(AssetManager manager,EnumSet rendererCaps) { - ShaderKey key = new ShaderKey(def.getVertexShaderName(), - def.getFragmentShaderName(), - getAllDefines(), - def.getVertexShaderLanguage(), - def.getFragmentShaderLanguage()); + ShaderKey key = new ShaderKey(getAllDefines(),def.getShaderProgramLanguages(),def.getShaderProgramNames()); if (getDef().isUsingShaderNodes()) { manager.getShaderGenerator(rendererCaps).initialize(this); diff --git a/jme3-core/src/main/java/com/jme3/material/TechniqueDef.java b/jme3-core/src/main/java/com/jme3/material/TechniqueDef.java index 1336442fa..07bcd930e 100644 --- a/jme3-core/src/main/java/com/jme3/material/TechniqueDef.java +++ b/jme3-core/src/main/java/com/jme3/material/TechniqueDef.java @@ -33,16 +33,10 @@ package com.jme3.material; import com.jme3.export.*; import com.jme3.renderer.Caps; -import com.jme3.renderer.Renderer; -import com.jme3.shader.DefineList; -import com.jme3.shader.ShaderNode; -import com.jme3.shader.UniformBinding; -import com.jme3.shader.VarType; +import com.jme3.shader.*; + import java.io.IOException; -import java.util.ArrayList; -import java.util.EnumSet; -import java.util.HashMap; -import java.util.List; +import java.util.*; /** * Describes a technique definition. @@ -100,10 +94,8 @@ public class TechniqueDef implements Savable { private EnumSet requiredCaps = EnumSet.noneOf(Caps.class); private String name; - private String vertName; - private String fragName; - private String vertLanguage; - private String fragLanguage; + private EnumMap shaderLanguage; + private EnumMap shaderName; private DefineList presetDefines; private boolean usesShaders; @@ -129,6 +121,7 @@ public class TechniqueDef implements Savable { * for default techniques. */ public TechniqueDef(String name){ + this(); this.name = name == null ? "Default" : name; } @@ -136,6 +129,8 @@ public class TechniqueDef implements Savable { * Serialization only. Do not use. */ public TechniqueDef(){ + shaderLanguage=new EnumMap(Shader.ShaderType.class); + shaderName=new EnumMap(Shader.ShaderType.class); } /** @@ -244,11 +239,10 @@ public class TechniqueDef implements Savable { * @param fragLanguage The fragment shader language */ public void setShaderFile(String vertexShader, String fragmentShader, String vertLanguage, String fragLanguage){ - this.vertName = vertexShader; - this.fragName = fragmentShader; - this.vertLanguage = vertLanguage; - this.fragLanguage = fragLanguage; - + this.shaderLanguage.put(Shader.ShaderType.Vertex,shaderLanguage.get(vertLanguage)); + this.shaderName.put(Shader.ShaderType.Vertex,shaderName.get(vertexShader)); + this.shaderLanguage.put(Shader.ShaderType.Fragment,shaderLanguage.get(fragLanguage)); + this.shaderName.put(Shader.ShaderType.Fragment,shaderName.get(fragmentShader)); Caps vertCap = Caps.valueOf(vertLanguage); requiredCaps.add(vertCap); Caps fragCap = Caps.valueOf(fragLanguage); @@ -257,6 +251,26 @@ public class TechniqueDef implements Savable { usesShaders = true; } + + /** + * Sets the shaders that this technique definition will use. + * + * @param shaderName EnumMap containing all shader names for this stage + * @param shaderLanguage EnumMap containing all shader languages for this stage + */ + public void setShaderFile(EnumMap shaderName, EnumMap shaderLanguage) { + for (Shader.ShaderType shaderType : shaderName.keySet()) { + this.shaderLanguage.put(shaderType,shaderLanguage.get(shaderType)); + this.shaderName.put(shaderType,shaderName.get(shaderType)); + if(shaderType.equals(Shader.ShaderType.Geometry)){ + requiredCaps.add(Caps.GeometryShader); + }else if(shaderType.equals(Shader.ShaderType.TessellationControl)){ + requiredCaps.add(Caps.TesselationShader); + } + } + usesShaders=true; + } + /** * Returns the define name which the given material parameter influences. * @@ -329,7 +343,7 @@ public class TechniqueDef implements Savable { * @return the name of the fragment shader to be used. */ public String getFragmentShaderName() { - return fragName; + return shaderName.get(Shader.ShaderType.Fragment); } @@ -340,7 +354,7 @@ public class TechniqueDef implements Savable { * @return the name of the vertex shader to be used. */ public String getVertexShaderName() { - return vertName; + return shaderName.get(Shader.ShaderType.Vertex); } /** @@ -348,21 +362,34 @@ public class TechniqueDef implements Savable { */ @Deprecated public String getShaderLanguage() { - return vertLanguage; + return shaderLanguage.get(Shader.ShaderType.Vertex); } /** * Returns the language of the fragment shader used in this technique. */ public String getFragmentShaderLanguage() { - return fragLanguage; + return shaderLanguage.get(Shader.ShaderType.Fragment); } /** * Returns the language of the vertex shader used in this technique. */ public String getVertexShaderLanguage() { - return vertLanguage; + return shaderLanguage.get(Shader.ShaderType.Vertex); + } + + /**Returns the language for each shader program + * @param shaderType + */ + public String getShaderProgramLanguage(Shader.ShaderType shaderType){ + return shaderLanguage.get(shaderType); + } + /**Returns the name for each shader program + * @param shaderType + */ + public String getShaderProgramName(Shader.ShaderType shaderType){ + return shaderName.get(shaderType); } /** @@ -406,10 +433,18 @@ public class TechniqueDef implements Savable { public void write(JmeExporter ex) throws IOException{ OutputCapsule oc = ex.getCapsule(this); oc.write(name, "name", null); - oc.write(vertName, "vertName", null); - oc.write(fragName, "fragName", null); - oc.write(vertLanguage, "vertLanguage", null); - oc.write(vertLanguage, "fragLanguage", null); + + oc.write(shaderName.get(Shader.ShaderType.Vertex), "vertName", null); + oc.write(shaderName.get(Shader.ShaderType.Fragment), "fragName", null); + oc.write(shaderName.get(Shader.ShaderType.Geometry), "geomName", null); + oc.write(shaderName.get(Shader.ShaderType.TessellationControl), "tsctrlName", null); + oc.write(shaderName.get(Shader.ShaderType.TessellationEvaluation), "tsevalName", null); + oc.write(shaderLanguage.get(Shader.ShaderType.Vertex), "vertLanguage", null); + oc.write(shaderLanguage.get(Shader.ShaderType.Fragment), "fragLanguage", null); + oc.write(shaderLanguage.get(Shader.ShaderType.Geometry), "geomLanguage", null); + oc.write(shaderLanguage.get(Shader.ShaderType.TessellationControl), "tsctrlLanguage", null); + oc.write(shaderLanguage.get(Shader.ShaderType.TessellationEvaluation), "tsevalLanguage", null); + oc.write(presetDefines, "presetDefines", null); oc.write(lightMode, "lightMode", LightMode.Disable); oc.write(shadowMode, "shadowMode", ShadowMode.Disable); @@ -428,8 +463,11 @@ public class TechniqueDef implements Savable { public void read(JmeImporter im) throws IOException{ InputCapsule ic = im.getCapsule(this); name = ic.readString("name", null); - vertName = ic.readString("vertName", null); - fragName = ic.readString("fragName", null); + shaderName.put(Shader.ShaderType.Vertex,ic.readString("vertName", null)); + shaderName.put(Shader.ShaderType.Fragment,ic.readString("fragName", null)); + shaderName.put(Shader.ShaderType.Geometry,ic.readString("geomName", null)); + shaderName.put(Shader.ShaderType.TessellationControl,ic.readString("tsctrlName", null)); + shaderName.put(Shader.ShaderType.TessellationEvaluation,ic.readString("tsevalName", null)); presetDefines = (DefineList) ic.readSavable("presetDefines", null); lightMode = ic.readEnum("lightMode", LightMode.class, LightMode.Disable); shadowMode = ic.readEnum("shadowMode", ShadowMode.class, ShadowMode.Disable); @@ -438,12 +476,15 @@ public class TechniqueDef implements Savable { if (ic.getSavableVersion(TechniqueDef.class) == 0) { // Old version - vertLanguage = ic.readString("shaderLang", null); - fragLanguage = vertLanguage; + shaderLanguage.put(Shader.ShaderType.Vertex,ic.readString("shaderLang", null)); + shaderLanguage.put(Shader.ShaderType.Fragment,shaderLanguage.get(Shader.ShaderType.Vertex)); } else { // New version - vertLanguage = ic.readString("vertLanguage", null); - fragLanguage = ic.readString("fragLanguage", null);; + shaderLanguage.put(Shader.ShaderType.Vertex,ic.readString("vertLanguage", null)); + shaderLanguage.put(Shader.ShaderType.Fragment,ic.readString("fragLanguage", null)); + shaderLanguage.put(Shader.ShaderType.Geometry,ic.readString("geomLanguage", null)); + shaderLanguage.put(Shader.ShaderType.TessellationControl,ic.readString("tsctrlLanguage", null)); + shaderLanguage.put(Shader.ShaderType.TessellationEvaluation,ic.readString("tsevalLanguage", null)); } usesNodes = ic.readBoolean("usesNodes", false); @@ -461,6 +502,22 @@ public class TechniqueDef implements Savable { usesShaders = true; } + /** + * Returns the Enum containing the ShaderProgramNames; + * @return + */ + public EnumMap getShaderProgramNames() { + return shaderName; + } + + /** + * Returns the Enum containing the ShaderProgramLanguages; + * @return + */ + public EnumMap getShaderProgramLanguages() { + return shaderLanguage; + } + public ShaderGenerationInfo getShaderGenerationInfo() { return shaderGenerationInfo; } @@ -469,8 +526,9 @@ public class TechniqueDef implements Savable { this.shaderGenerationInfo = shaderGenerationInfo; } + //todo: make toString return something usefull @Override public String toString() { - return "TechniqueDef{" + "requiredCaps=" + requiredCaps + ", name=" + name + ", vertName=" + vertName + ", fragName=" + fragName + ", vertLanguage=" + vertLanguage + ", fragLanguage=" + fragLanguage + ", presetDefines=" + presetDefines + ", usesShaders=" + usesShaders + ", usesNodes=" + usesNodes + ", shaderNodes=" + shaderNodes + ", shaderGenerationInfo=" + shaderGenerationInfo + ", renderState=" + renderState + ", forcedRenderState=" + forcedRenderState + ", lightMode=" + lightMode + ", shadowMode=" + shadowMode + ", defineParams=" + defineParams + ", worldBinds=" + worldBinds + '}'; + return "TechniqueDef{" + "requiredCaps=" + requiredCaps + ", name=" + name /*+ ", vertName=" + vertName + ", fragName=" + fragName + ", vertLanguage=" + vertLanguage + ", fragLanguage=" + fragLanguage */+ ", presetDefines=" + presetDefines + ", usesShaders=" + usesShaders + ", usesNodes=" + usesNodes + ", shaderNodes=" + shaderNodes + ", shaderGenerationInfo=" + shaderGenerationInfo + ", renderState=" + renderState + ", forcedRenderState=" + forcedRenderState + ", lightMode=" + lightMode + ", shadowMode=" + shadowMode + ", defineParams=" + defineParams + ", worldBinds=" + worldBinds + '}'; } } diff --git a/jme3-core/src/main/java/com/jme3/renderer/Caps.java b/jme3-core/src/main/java/com/jme3/renderer/Caps.java index b43e38bd6..f0d42c8f2 100644 --- a/jme3-core/src/main/java/com/jme3/renderer/Caps.java +++ b/jme3-core/src/main/java/com/jme3/renderer/Caps.java @@ -120,7 +120,14 @@ public enum Caps { * Supports OpenGL 3.2 */ OpenGL32, - + /** + * Supports OpenGL 3.3 + */ + OpenGL33, + /** + * Supports OpenGL 4.0 + */ + OpenGL40, /** * Do not use. * @@ -163,7 +170,10 @@ public enum Caps { * Supports GLSL 3.3 */ GLSL330, - + /** + * Supports GLSL 4.0 + */ + GLSL400, /** * Supports reading from textures inside the vertex shader. */ @@ -173,7 +183,10 @@ public enum Caps { * Supports geometry shader. */ GeometryShader, - + /** + * Supports Tesselation shader + */ + TesselationShader, /** * Supports texture arrays */ diff --git a/jme3-core/src/main/java/com/jme3/renderer/opengl/GL3.java b/jme3-core/src/main/java/com/jme3/renderer/opengl/GL3.java index 91b14488f..50eb065ab 100644 --- a/jme3-core/src/main/java/com/jme3/renderer/opengl/GL3.java +++ b/jme3-core/src/main/java/com/jme3/renderer/opengl/GL3.java @@ -41,7 +41,7 @@ import java.nio.IntBuffer; public interface GL3 extends GL2 { public static final int GL_DEPTH_STENCIL_ATTACHMENT = 0x821A; - + public static final int GL_GEOMETRY_SHADER=0x8DD9; public void glBindFragDataLocation(int param1, int param2, String param3); /// GL3+ public void glBindVertexArray(int param1); /// GL3+ public void glGenVertexArrays(IntBuffer param1); /// GL3+ diff --git a/jme3-core/src/main/java/com/jme3/renderer/opengl/GL4.java b/jme3-core/src/main/java/com/jme3/renderer/opengl/GL4.java new file mode 100644 index 000000000..9ce4e835f --- /dev/null +++ b/jme3-core/src/main/java/com/jme3/renderer/opengl/GL4.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2009-2014 jMonkeyEngine + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'jMonkeyEngine' nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package com.jme3.renderer.opengl; + +import java.nio.IntBuffer; + +/** + * GL functions only available on vanilla desktop OpenGL 3.0. + * + * @author Kirill Vainer + */ +public interface GL4 extends GL3 { + public static final int GL_TESS_CONTROL_SHADER=0x8E87; + public static final int GL_TESS_EVALUATION_SHADER=0x8E88; + public static final int GL_PATCHES=0xE; + public void glPatchParameter(int count); +} diff --git a/jme3-core/src/main/java/com/jme3/renderer/opengl/GLRenderer.java b/jme3-core/src/main/java/com/jme3/renderer/opengl/GLRenderer.java index cc7acb390..395b7e485 100644 --- a/jme3-core/src/main/java/com/jme3/renderer/opengl/GLRenderer.java +++ b/jme3-core/src/main/java/com/jme3/renderer/opengl/GLRenderer.java @@ -107,6 +107,7 @@ public class GLRenderer implements Renderer { private final GL gl; private final GL2 gl2; private final GL3 gl3; + private final GL4 gl4; private final GLExt glext; private final GLFbo glfbo; private final TextureUtil texUtil; @@ -115,6 +116,7 @@ public class GLRenderer implements Renderer { this.gl = gl; this.gl2 = gl instanceof GL2 ? (GL2)gl : null; this.gl3 = gl instanceof GL3 ? (GL3)gl : null; + this.gl4 = gl instanceof GL4 ? (GL4)gl : null; this.glfbo = glfbo; this.glext = glfbo instanceof GLExt ? (GLExt)glfbo : null; this.texUtil = new TextureUtil(gl, gl2, glext, context); @@ -183,6 +185,12 @@ public class GLRenderer implements Renderer { caps.add(Caps.OpenGL31); if (oglVer >= 320) { caps.add(Caps.OpenGL32); + }if(oglVer>=330){ + caps.add(Caps.OpenGL33); + caps.add(Caps.GeometryShader); + }if(oglVer>=400){ + caps.add(Caps.OpenGL40); + caps.add(Caps.TesselationShader); } } } @@ -199,7 +207,9 @@ public class GLRenderer implements Renderer { // so that future OpenGL revisions wont break jme3 // fall through intentional case 400: + caps.add(Caps.GLSL400); case 330: + caps.add(Caps.GLSL330); case 150: caps.add(Caps.GLSL150); case 140: @@ -271,7 +281,7 @@ public class GLRenderer implements Renderer { boolean hasFloatTexture = false; - hasFloatTexture = hasExtension("GL_OES_texture_half_float") && + hasFloatTexture = hasExtension("GL_OES_texture_half_float") && hasExtension("GL_OES_texture_float"); if (!hasFloatTexture) { @@ -1009,6 +1019,12 @@ public class GLRenderer implements Renderer { return GL.GL_FRAGMENT_SHADER; case Vertex: return GL.GL_VERTEX_SHADER; + case Geometry: + return GL3.GL_GEOMETRY_SHADER; + case TessellationControl: + return GL4.GL_TESS_CONTROL_SHADER; + case TessellationEvaluation: + return GL4.GL_TESS_EVALUATION_SHADER; default: throw new UnsupportedOperationException("Unrecognized shader type."); } @@ -2520,6 +2536,8 @@ public class GLRenderer implements Renderer { return GL.GL_TRIANGLE_FAN; case TriangleStrip: return GL.GL_TRIANGLE_STRIP; + case Patch: + return GL4.GL_PATCHES; default: throw new UnsupportedOperationException("Unrecognized mesh mode: " + mode); } @@ -2670,7 +2688,9 @@ public class GLRenderer implements Renderer { gl.glLineWidth(mesh.getLineWidth()); context.lineWidth = mesh.getLineWidth(); } - + if(gl4!=null && mesh.getMode().equals(Mode.Patch)){ + gl4.glPatchParameter(mesh.getPatchVertexCount()); + } statistics.onMeshDrawn(mesh, lod, count); // if (ctxCaps.GL_ARB_vertex_array_object){ // renderMeshVertexArray(mesh, lod, count); diff --git a/jme3-core/src/main/java/com/jme3/scene/Mesh.java b/jme3-core/src/main/java/com/jme3/scene/Mesh.java index 5d0e8dcec..a0f8e1fe6 100644 --- a/jme3-core/src/main/java/com/jme3/scene/Mesh.java +++ b/jme3-core/src/main/java/com/jme3/scene/Mesh.java @@ -134,8 +134,12 @@ public class Mesh implements Savable, Cloneable { * {@link Mesh#setElementLengths(int[]) element lengths} must * be specified for this mode. */ - Hybrid(false); - + Hybrid(false), + /** + * Used for Tesselation only. Requires to set the number of vertices + * for each patch (default is 3 for triangle tesselation) + */ + Patch(true); private boolean listMode = false; private Mode(boolean listMode){ @@ -175,6 +179,7 @@ public class Mesh implements Savable, Cloneable { private int vertCount = -1; private int elementCount = -1; private int instanceCount = -1; + private int patchVertexCount=3; //only used for tesselation private int maxNumWeights = -1; // only if using skeletal animation private int[] elementLengths; @@ -728,6 +733,8 @@ public class Mesh implements Savable, Cloneable { return bufSize; case LineStrip: return bufSize - 1; + case Patch: + return bufSize/patchVertexCount; default: throw new UnsupportedOperationException(); } @@ -1362,6 +1369,21 @@ public class Mesh implements Savable, Cloneable { getBuffer(Type.HWBoneIndex) != null; } + /** + * Sets the count of vertices used for each tessellation patch + * @param patchVertexCount + */ + public void setPatchVertexCount(int patchVertexCount) { + this.patchVertexCount = patchVertexCount; + } + + /** + * Gets the amout of vertices used for each patch; + * @return + */ + public int getPatchVertexCount() { + return patchVertexCount; + } public void write(JmeExporter ex) throws IOException { OutputCapsule out = ex.getCapsule(this); diff --git a/jme3-core/src/main/java/com/jme3/shader/Shader.java b/jme3-core/src/main/java/com/jme3/shader/Shader.java index 2925fe0f2..eb084f178 100644 --- a/jme3-core/src/main/java/com/jme3/shader/Shader.java +++ b/jme3-core/src/main/java/com/jme3/shader/Shader.java @@ -74,7 +74,15 @@ public final class Shader extends NativeObject { /** * Control geometry assembly. (e.g compile a triangle list from input data) */ - Geometry; + Geometry, + /** + * Controls tesselation factor (e.g how often a input patch should be subdivided) + */ + TessellationControl, + /** + * Controls tesselation transform (e.g similar to the vertex shader, but required to mix inputs manual) + */ + TessellationEvaluation; } /** diff --git a/jme3-core/src/main/java/com/jme3/shader/ShaderKey.java b/jme3-core/src/main/java/com/jme3/shader/ShaderKey.java index f6cb81508..721d6cdb4 100644 --- a/jme3-core/src/main/java/com/jme3/shader/ShaderKey.java +++ b/jme3-core/src/main/java/com/jme3/shader/ShaderKey.java @@ -37,25 +37,31 @@ import com.jme3.export.JmeExporter; import com.jme3.export.JmeImporter; import com.jme3.export.OutputCapsule; import java.io.IOException; +import java.util.EnumMap; +import java.util.Set; public class ShaderKey extends AssetKey { - protected String fragName; + protected EnumMap shaderLanguage; + protected EnumMap shaderName; protected DefineList defines; - protected String vertLanguage; - protected String fragLanguage; protected int cachedHashedCode = 0; protected boolean usesShaderNodes = false; public ShaderKey(){ + shaderLanguage=new EnumMap(Shader.ShaderType.class); + shaderName=new EnumMap(Shader.ShaderType.class); } - public ShaderKey(String vertName, String fragName, DefineList defines, String vertLanguage, String fragLanguage){ - super(vertName); - this.fragName = fragName; + public ShaderKey(DefineList defines, EnumMap shaderLanguage,EnumMap shaderName){ + super(shaderName.get(Shader.ShaderType.Vertex)); + this.shaderLanguage=new EnumMap(Shader.ShaderType.class); + this.shaderName=new EnumMap(Shader.ShaderType.class); this.defines = defines; - this.vertLanguage = vertLanguage; - this.fragLanguage = fragLanguage; + for (Shader.ShaderType shaderType : shaderName.keySet()) { + this.shaderName.put(shaderType,shaderName.get(shaderType)); + this.shaderLanguage.put(shaderType,shaderLanguage.get(shaderType)); + } } @Override @@ -68,13 +74,15 @@ public class ShaderKey extends AssetKey { @Override public String toString(){ - return "V="+name + " F=" + fragName + (defines != null ? defines : ""); + //todo: + return "V="+name+";"; } + //todo: make equals and hashCode work @Override public boolean equals(Object obj) { final ShaderKey other = (ShaderKey) obj; - if (name.equals(other.name) && fragName.equals(other.fragName)){ + if (name.equals(other.name) && shaderName.get(Shader.ShaderType.Fragment).equals(other.shaderName.get(Shader.ShaderType.Fragment))){ if (defines != null && other.defines != null) { return defines.equals(other.defines); } else if (defines != null || other.defines != null) { @@ -91,7 +99,10 @@ public class ShaderKey extends AssetKey { if (cachedHashedCode == 0) { int hash = 7; hash = 41 * hash + name.hashCode(); - hash = 41 * hash + fragName.hashCode(); + hash = 41 * hash + shaderName.get(Shader.ShaderType.Fragment).hashCode(); + hash = shaderName.get(Shader.ShaderType.Geometry) == null ? hash : 41 * hash + shaderName.get(Shader.ShaderType.Geometry).hashCode(); + hash = shaderName.get(Shader.ShaderType.TessellationControl) == null ? hash : 41 * hash + shaderName.get(Shader.ShaderType.TessellationControl).hashCode(); + hash = shaderName.get(Shader.ShaderType.TessellationEvaluation) == null ? hash : 41 * hash + shaderName.get(Shader.ShaderType.TessellationEvaluation).hashCode(); hash = 41 * hash + (defines != null ? defines.hashCode() : 0); cachedHashedCode = hash; } @@ -103,11 +114,11 @@ public class ShaderKey extends AssetKey { } public String getVertName(){ - return name; + return shaderName.get(Shader.ShaderType.Vertex); } public String getFragName() { - return fragName; + return shaderName.get(Shader.ShaderType.Fragment); } /** @@ -115,15 +126,15 @@ public class ShaderKey extends AssetKey { */ @Deprecated public String getLanguage() { - return vertLanguage; + return shaderLanguage.get(Shader.ShaderType.Vertex); } public String getVertexShaderLanguage() { - return vertLanguage; + return shaderLanguage.get(Shader.ShaderType.Vertex); } public String getFragmentShaderLanguage() { - return fragLanguage; + return shaderLanguage.get(Shader.ShaderType.Vertex); } public boolean isUsesShaderNodes() { @@ -134,22 +145,48 @@ public class ShaderKey extends AssetKey { this.usesShaderNodes = usesShaderNodes; } + public Set getUsedShaderPrograms(){ + return shaderName.keySet(); + } + + public String getShaderProgramLanguage(Shader.ShaderType shaderType){ + return shaderLanguage.get(shaderType); + } + + public String getShaderProgramName(Shader.ShaderType shaderType){ + return shaderName.get(shaderType); + } + @Override public void write(JmeExporter ex) throws IOException{ super.write(ex); OutputCapsule oc = ex.getCapsule(this); - oc.write(fragName, "fragment_name", null); - oc.write(vertLanguage, "language", null); - oc.write(fragLanguage, "frag_language", null); + oc.write(shaderName.get(Shader.ShaderType.Fragment), "fragment_name", null); + oc.write(shaderName.get(Shader.ShaderType.Geometry), "geometry_name", null); + oc.write(shaderName.get(Shader.ShaderType.TessellationControl), "tessControl_name", null); + oc.write(shaderName.get(Shader.ShaderType.TessellationEvaluation), "tessEval_name", null); + oc.write(shaderLanguage.get(Shader.ShaderType.Vertex), "language", null); + oc.write(shaderLanguage.get(Shader.ShaderType.Fragment), "frag_language", null); + oc.write(shaderLanguage.get(Shader.ShaderType.Geometry), "geom_language", null); + oc.write(shaderLanguage.get(Shader.ShaderType.TessellationControl), "tsctrl_language", null); + oc.write(shaderLanguage.get(Shader.ShaderType.TessellationEvaluation), "tseval_language", null); + } @Override public void read(JmeImporter im) throws IOException{ super.read(im); InputCapsule ic = im.getCapsule(this); - fragName = ic.readString("fragment_name", null); - vertLanguage = ic.readString("language", null); - fragLanguage = ic.readString("frag_language", null); + shaderName.put(Shader.ShaderType.Vertex,name); + shaderName.put(Shader.ShaderType.Fragment,ic.readString("fragment_name", null)); + shaderName.put(Shader.ShaderType.Geometry,ic.readString("geometry_name", null)); + shaderName.put(Shader.ShaderType.TessellationControl,ic.readString("tessControl_name", null)); + shaderName.put(Shader.ShaderType.TessellationEvaluation,ic.readString("tessEval_name", null)); + shaderLanguage.put(Shader.ShaderType.Vertex,ic.readString("language", null)); + shaderLanguage.put(Shader.ShaderType.Fragment,ic.readString("frag_language", null)); + shaderLanguage.put(Shader.ShaderType.Geometry,ic.readString("geom_language", null)); + shaderLanguage.put(Shader.ShaderType.TessellationControl,ic.readString("tsctrl_language", null)); + shaderLanguage.put(Shader.ShaderType.TessellationEvaluation,ic.readString("tseval_language", null)); } } diff --git a/jme3-core/src/main/resources/com/jme3/asset/Desktop.cfg b/jme3-core/src/main/resources/com/jme3/asset/Desktop.cfg index e64570831..df72654a1 100644 --- a/jme3-core/src/main/resources/com/jme3/asset/Desktop.cfg +++ b/jme3-core/src/main/resources/com/jme3/asset/Desktop.cfg @@ -2,4 +2,26 @@ INCLUDE com/jme3/asset/General.cfg # Desktop-specific loaders LOADER com.jme3.texture.plugins.AWTLoader : jpg, bmp, gif, png, jpeg -LOADER com.jme3.audio.plugins.OGGLoader : ogg \ No newline at end of file +LOADER com.jme3.audio.plugins.OGGLoader : oggLOADER com.jme3.audio.plugins.WAVLoader : wav +LOADER com.jme3.audio.plugins.OGGLoader : ogg +LOADER com.jme3.cursors.plugins.CursorLoader : ani, cur, ico +LOADER com.jme3.material.plugins.J3MLoader : j3m +LOADER com.jme3.material.plugins.J3MLoader : j3md +LOADER com.jme3.material.plugins.ShaderNodeDefinitionLoader : j3sn +LOADER com.jme3.font.plugins.BitmapFontLoader : fnt +LOADER com.jme3.texture.plugins.DDSLoader : dds +LOADER com.jme3.texture.plugins.PFMLoader : pfm +LOADER com.jme3.texture.plugins.HDRLoader : hdr +LOADER com.jme3.texture.plugins.TGALoader : tga +LOADER com.jme3.export.binary.BinaryImporter : j3o +LOADER com.jme3.export.binary.BinaryImporter : j3f +LOADER com.jme3.scene.plugins.OBJLoader : obj +LOADER com.jme3.scene.plugins.MTLLoader : mtl +LOADER com.jme3.scene.plugins.ogre.MeshLoader : meshxml, mesh.xml +LOADER com.jme3.scene.plugins.ogre.SkeletonLoader : skeletonxml, skeleton.xml +LOADER com.jme3.scene.plugins.ogre.MaterialLoader : material +LOADER com.jme3.scene.plugins.ogre.SceneLoader : scene +LOADER com.jme3.scene.plugins.blender.BlenderModelLoader : blend +LOADER com.jme3.shader.plugins.GLSLLoader : vert, frag,geom,tsctrl,tseval, glsl, glsllib +LOADER com.jme3.scene.plugins.fbx.SceneLoader : fbx +LOADER com.jme3.scene.plugins.fbx.SceneWithAnimationLoader : fba diff --git a/jme3-core/src/plugins/java/com/jme3/material/plugins/J3MLoader.java b/jme3-core/src/plugins/java/com/jme3/material/plugins/J3MLoader.java index 48159df39..449802161 100644 --- a/jme3-core/src/plugins/java/com/jme3/material/plugins/J3MLoader.java +++ b/jme3-core/src/plugins/java/com/jme3/material/plugins/J3MLoader.java @@ -40,6 +40,7 @@ import com.jme3.material.TechniqueDef.ShadowMode; import com.jme3.math.ColorRGBA; import com.jme3.math.Vector2f; import com.jme3.math.Vector3f; +import com.jme3.shader.Shader; import com.jme3.shader.VarType; import com.jme3.texture.Texture; import com.jme3.texture.Texture.WrapMode; @@ -48,8 +49,10 @@ import com.jme3.texture.image.ColorSpace; import com.jme3.util.PlaceholderAssets; import com.jme3.util.blockparser.BlockLanguageParser; import com.jme3.util.blockparser.Statement; + import java.io.IOException; import java.io.InputStream; +import java.util.EnumMap; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; @@ -68,16 +71,15 @@ public class J3MLoader implements AssetLoader { private Material material; private TechniqueDef technique; private RenderState renderState; - - private String vertLanguage; - private String fragLanguage; - - private String vertName; - private String fragName; - + + private EnumMap shaderLanguage; + private EnumMap shaderName; + private static final String whitespacePattern = "\\p{javaWhitespace}+"; - public J3MLoader(){ + public J3MLoader() { + shaderLanguage = new EnumMap(Shader.ShaderType.class); + shaderName = new EnumMap(Shader.ShaderType.class); } @@ -91,16 +93,19 @@ public class J3MLoader implements AssetLoader { if (typeAndLang.length != 2) { throw new IOException("Shader statement syntax incorrect: " + statement); } - - if (typeAndLang[0].equals("VertexShader")) { - vertName = split[1].trim(); - vertLanguage = typeAndLang[1]; - } else if (typeAndLang[0].equals("FragmentShader")) { - fragName = split[1].trim(); - fragLanguage = typeAndLang[1]; + + for (Shader.ShaderType shaderType : Shader.ShaderType.values()) { + if (typeAndLang[0].equals(shaderType.toString() + "Shader")) { + readShaderDefinition(shaderType, split[1].trim(), typeAndLang[1]); + } } } + private void readShaderDefinition(Shader.ShaderType shaderType, String name, String language) { + shaderName.put(shaderType, name); + shaderLanguage.put(shaderType, language); + } + // LightMode private void readLightMode(String statement) throws IOException{ String[] split = statement.split(whitespacePattern); @@ -403,7 +408,10 @@ public class J3MLoader implements AssetLoader { private void readTechniqueStatement(Statement statement) throws IOException{ String[] split = statement.getLine().split("[ \\{]"); if (split[0].equals("VertexShader") || - split[0].equals("FragmentShader")){ + split[0].equals("FragmentShader") || + split[0].equals("GeometryShader") || + split[0].equals("TessellationControlShader") || + split[0].equals("TessellationEvaluationShader")) { readShaderStatement(statement.getLine()); }else if (split[0].equals("LightMode")){ readLightMode(statement.getLine()); @@ -467,16 +475,14 @@ public class J3MLoader implements AssetLoader { technique.setShaderFile(technique.hashCode() + "", technique.hashCode() + "", "GLSL100", "GLSL100"); } - if (vertName != null && fragName != null){ - technique.setShaderFile(vertName, fragName, vertLanguage, fragLanguage); + if (shaderName.containsKey(Shader.ShaderType.Vertex) && shaderName.containsKey(Shader.ShaderType.Fragment)) { + technique.setShaderFile(shaderName, shaderLanguage); } materialDef.addTechniqueDef(technique); technique = null; - vertName = null; - fragName = null; - vertLanguage = null; - fragLanguage = null; + shaderLanguage.clear(); + shaderName.clear(); } private void loadFromRoot(List roots) throws IOException{ @@ -594,9 +600,9 @@ public class J3MLoader implements AssetLoader { protected void initNodesLoader() { if (!isUseNodes) { - isUseNodes = fragName == null && vertName == null; - if (isUseNodes) { - if(nodesLoaderDelegate == null){ + isUseNodes = shaderName.get(Shader.ShaderType.Vertex) == null && shaderName.get(Shader.ShaderType.Fragment) == null; + if (isUseNodes) { + if (nodesLoaderDelegate == null) { nodesLoaderDelegate = new ShaderNodeLoaderDelegate(); }else{ nodesLoaderDelegate.clear(); diff --git a/jme3-core/src/tools/java/jme3tools/shadercheck/ShaderCheck.java b/jme3-core/src/tools/java/jme3tools/shadercheck/ShaderCheck.java index ddd2993e8..c77fa2b2e 100644 --- a/jme3-core/src/tools/java/jme3tools/shadercheck/ShaderCheck.java +++ b/jme3-core/src/tools/java/jme3tools/shadercheck/ShaderCheck.java @@ -30,7 +30,7 @@ public class ShaderCheck { assetManager.registerLocator("/", ClasspathLocator.class); assetManager.registerLoader(J3MLoader.class, "j3m"); assetManager.registerLoader(J3MLoader.class, "j3md"); - assetManager.registerLoader(GLSLLoader.class, "vert", "frag", "glsllib"); + assetManager.registerLoader(GLSLLoader.class, "vert", "frag","geom","tsctrl","tseval","glsllib"); } private static void checkMatDef(String matdefName){ @@ -38,11 +38,8 @@ public class ShaderCheck { for (TechniqueDef techDef : def.getDefaultTechniques()){ DefineList dl = new DefineList(); dl.addFrom(techDef.getShaderPresetDefines()); - ShaderKey shaderKey = new ShaderKey(techDef.getVertexShaderName(), - techDef.getFragmentShaderName(), - dl, - techDef.getVertexShaderLanguage(), - techDef.getFragmentShaderLanguage()); + ShaderKey shaderKey = new ShaderKey(dl,techDef.getShaderProgramLanguages(),techDef.getShaderProgramNames()); + Shader shader = assetManager.loadShader(shaderKey); for (Validator validator : validators){ diff --git a/jme3-examples/src/main/java/jme3test/material/TestGeometryShader.java b/jme3-examples/src/main/java/jme3test/material/TestGeometryShader.java new file mode 100644 index 000000000..04c8223f1 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/material/TestGeometryShader.java @@ -0,0 +1,42 @@ +package jme3test.material; + +import com.jme3.app.SimpleApplication; +import com.jme3.bounding.BoundingBox; +import com.jme3.material.Material; +import com.jme3.math.Vector3f; +import com.jme3.scene.Geometry; +import com.jme3.scene.Mesh; +import com.jme3.scene.VertexBuffer; +import com.jme3.scene.shape.Sphere; +import com.jme3.util.BufferUtils; + +/** + * Created by michael on 23.02.15. + */ +public class TestGeometryShader extends SimpleApplication { + @Override + public void simpleInitApp() { + Mesh mesh = new Mesh(); + mesh.setBuffer(VertexBuffer.Type.Index, 1, BufferUtils.createIntBuffer(new int[]{1})); + mesh.setBuffer(VertexBuffer.Type.Position, 3, BufferUtils.createFloatBuffer(new float[]{0, 0, 0})); + mesh.setMode(Mesh.Mode.Points); + mesh.setBound(new BoundingBox(new Vector3f(0, 0, 0), 10, 10, 10)); + mesh.updateCounts(); + Geometry geometry = new Geometry("Test", mesh); + geometry.updateGeometricState(); + geometry.setMaterial(new Material(assetManager, "Materials/Geom/SimpleGeom.j3md")); + //geometry.getMaterial().getAdditionalRenderState().setFaceCullMode(RenderState.FaceCullMode.Off); + //geometry.setMaterial(assetManager.loadMaterial("Materials/Geom/SimpleTess.j3md")); + rootNode.attachChild(geometry); + + Geometry geometry1 = new Geometry("T1", new Sphere(10, 10, 1)); + geometry1.setMaterial(new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md")); + rootNode.attachChild(geometry1); + + } + + public static void main(String[] args) { + TestGeometryShader app = new TestGeometryShader(); + app.start(); + } +} diff --git a/jme3-examples/src/main/java/jme3test/material/TestTessellationShader.java b/jme3-examples/src/main/java/jme3test/material/TestTessellationShader.java new file mode 100644 index 000000000..f7557ca83 --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/material/TestTessellationShader.java @@ -0,0 +1,68 @@ +package jme3test.material; + +import com.jme3.app.SimpleApplication; +import com.jme3.input.KeyInput; +import com.jme3.input.controls.AnalogListener; +import com.jme3.input.controls.KeyTrigger; +import com.jme3.material.Material; +import com.jme3.scene.Geometry; +import com.jme3.scene.Mesh; +import com.jme3.scene.VertexBuffer; +import com.jme3.scene.shape.Quad; +import com.jme3.util.BufferUtils; + +import java.util.concurrent.Callable; + +/** + * Created by michael on 28.02.15. + */ +public class TestTessellationShader extends SimpleApplication { + Material tessellationMaterial; + int tessFactor=5; + @Override + public void simpleInitApp() { + tessellationMaterial = new Material(getAssetManager(), "Materials/Tess/SimpleTess.j3md"); + tessellationMaterial.setInt("TessellationFactor", tessFactor); + tessellationMaterial.getAdditionalRenderState().setWireframe(true); + Quad quad = new Quad(10, 10); + quad.clearBuffer(VertexBuffer.Type.Index); + quad.setBuffer(VertexBuffer.Type.Index, 4, BufferUtils.createIntBuffer(0, 1, 2, 3)); + quad.setMode(Mesh.Mode.Patch); + quad.setPatchVertexCount(4); + Geometry geometry = new Geometry("tessTest", quad); + geometry.setMaterial(tessellationMaterial); + rootNode.attachChild(geometry); + + getInputManager().addMapping("TessUp", new KeyTrigger(KeyInput.KEY_A)); + getInputManager().addMapping("TessDo", new KeyTrigger(KeyInput.KEY_Y)); + getInputManager().addListener(new AnalogListener() { + @Override + public void onAnalog(String name, float value, float tpf) { + if(name.equals("TessUp")){ + tessFactor++; + enqueue(new Callable() { + @Override + public Boolean call() throws Exception { + tessellationMaterial.setInt("TessellationFactor",tessFactor); + return true; + } + }); + } + if(name.equals("TessDo")){ + tessFactor--; + enqueue(new Callable() { + @Override + public Boolean call() throws Exception { + tessellationMaterial.setInt("TessellationFactor",tessFactor); + return true; + } + }); + } + } + },"TessUp","TessDo"); + } + + public static void main(String[] args) { + new TestTessellationShader().start(); + } +} diff --git a/jme3-lwjgl/src/main/java/com/jme3/renderer/lwjgl/LwjglGL.java b/jme3-lwjgl/src/main/java/com/jme3/renderer/lwjgl/LwjglGL.java index b213fdded..82b8ee72b 100644 --- a/jme3-lwjgl/src/main/java/com/jme3/renderer/lwjgl/LwjglGL.java +++ b/jme3-lwjgl/src/main/java/com/jme3/renderer/lwjgl/LwjglGL.java @@ -9,14 +9,11 @@ import java.nio.ByteBuffer; import java.nio.FloatBuffer; import java.nio.IntBuffer; import java.nio.ShortBuffer; -import org.lwjgl.opengl.GL11; -import org.lwjgl.opengl.GL12; -import org.lwjgl.opengl.GL13; -import org.lwjgl.opengl.GL15; -import org.lwjgl.opengl.GL20; -import org.lwjgl.opengl.GL30; - -public class LwjglGL implements GL, GL2, GL3 { + +import com.jme3.renderer.opengl.GL4; +import org.lwjgl.opengl.*; + +public class LwjglGL implements GL, GL2, GL3,GL4 { private static void checkLimit(Buffer buffer) { if (buffer == null) { @@ -442,4 +439,9 @@ public class LwjglGL implements GL, GL2, GL3 { checkLimit(param1); GL30.glGenVertexArrays(param1); } + + @Override + public void glPatchParameter(int count) { + GL40.glPatchParameteri(GL40.GL_PATCH_VERTICES,count); + } } diff --git a/jme3-testdata/src/main/resources/Materials/Geom/SimpleGeom.frag b/jme3-testdata/src/main/resources/Materials/Geom/SimpleGeom.frag new file mode 100644 index 000000000..636af0c7e --- /dev/null +++ b/jme3-testdata/src/main/resources/Materials/Geom/SimpleGeom.frag @@ -0,0 +1,3 @@ +void main(){ + gl_FragColor=vec4(1.0,0.0,1.0,0.5); +} \ No newline at end of file diff --git a/jme3-testdata/src/main/resources/Materials/Geom/SimpleGeom.geom b/jme3-testdata/src/main/resources/Materials/Geom/SimpleGeom.geom new file mode 100644 index 000000000..e0c5d7b9e --- /dev/null +++ b/jme3-testdata/src/main/resources/Materials/Geom/SimpleGeom.geom @@ -0,0 +1,19 @@ +layout (points) in; +layout (line_strip) out; +layout (max_vertices = 11) out; + +uniform mat4 g_WorldViewProjectionMatrix; +const float PI = 3.1415926; +void main(){ + for (int i = 0; i <= 10; i++) { + + float ang = PI * 2.0 / 10.0 * i; + vec4 offset = vec4(cos(ang) * 5, -sin(ang) * 5, 0.0, 0.0); + gl_Position = g_WorldViewProjectionMatrix*vec4(gl_in[0].gl_Position.xyz + offset.xyz,1.0); + + EmitVertex(); + } + + EndPrimitive(); +} + diff --git a/jme3-testdata/src/main/resources/Materials/Geom/SimpleGeom.j3m b/jme3-testdata/src/main/resources/Materials/Geom/SimpleGeom.j3m new file mode 100644 index 000000000..25ac6a523 --- /dev/null +++ b/jme3-testdata/src/main/resources/Materials/Geom/SimpleGeom.j3m @@ -0,0 +1,4 @@ +Material Pong Rock : Materials/Geom/SimpleGeom.j3md { + MaterialParameters { + } +} \ No newline at end of file diff --git a/jme3-testdata/src/main/resources/Materials/Geom/SimpleGeom.j3md b/jme3-testdata/src/main/resources/Materials/Geom/SimpleGeom.j3md new file mode 100644 index 000000000..4ae79e3ed --- /dev/null +++ b/jme3-testdata/src/main/resources/Materials/Geom/SimpleGeom.j3md @@ -0,0 +1,17 @@ +MaterialDef SimpleGeom { + + MaterialParameters { + + } + + Technique { + VertexShader GLSL330: Materials/Geom/SimpleGeom.vert + GeometryShader GLSL330: Materials/Geom/SimpleGeom.geom + FragmentShader GLSL330: Materials/Geom/SimpleGeom.frag + + WorldParameters { + WorldViewProjectionMatrix + } + } + +} \ No newline at end of file diff --git a/jme3-testdata/src/main/resources/Materials/Geom/SimpleGeom.vert b/jme3-testdata/src/main/resources/Materials/Geom/SimpleGeom.vert new file mode 100644 index 000000000..f82ebb79b --- /dev/null +++ b/jme3-testdata/src/main/resources/Materials/Geom/SimpleGeom.vert @@ -0,0 +1,5 @@ +attribute vec3 inPosition; + +void main(){ + gl_Position=vec4(inPosition,1); +} \ No newline at end of file diff --git a/jme3-testdata/src/main/resources/Materials/Tess/SimpleTess.frag b/jme3-testdata/src/main/resources/Materials/Tess/SimpleTess.frag new file mode 100644 index 000000000..636af0c7e --- /dev/null +++ b/jme3-testdata/src/main/resources/Materials/Tess/SimpleTess.frag @@ -0,0 +1,3 @@ +void main(){ + gl_FragColor=vec4(1.0,0.0,1.0,0.5); +} \ No newline at end of file diff --git a/jme3-testdata/src/main/resources/Materials/Tess/SimpleTess.j3m b/jme3-testdata/src/main/resources/Materials/Tess/SimpleTess.j3m new file mode 100644 index 000000000..599a8c61c --- /dev/null +++ b/jme3-testdata/src/main/resources/Materials/Tess/SimpleTess.j3m @@ -0,0 +1,4 @@ +Material Pong Rock : Materials/Tess/SimpleTess.j3md { + MaterialParameters { + } +} \ No newline at end of file diff --git a/jme3-testdata/src/main/resources/Materials/Tess/SimpleTess.j3md b/jme3-testdata/src/main/resources/Materials/Tess/SimpleTess.j3md new file mode 100644 index 000000000..81813493d --- /dev/null +++ b/jme3-testdata/src/main/resources/Materials/Tess/SimpleTess.j3md @@ -0,0 +1,19 @@ +MaterialDef SimpleGeom { + + MaterialParameters { + Texture2D NormalDisplacementMap + Int TessellationFactor + } + + Technique { + VertexShader GLSL400: Materials/Tess/SimpleTess.vert + TessellationEvaluationShader GLSL400: Materials/Tess/SimpleTess.tseval + TessellationControlShader GLSL400: Materials/Tess/SimpleTess.tsctrl + FragmentShader GLSL400: Materials/Tess/SimpleTess.frag + + WorldParameters { + WorldViewProjectionMatrix + } + } + +} \ No newline at end of file diff --git a/jme3-testdata/src/main/resources/Materials/Tess/SimpleTess.tsctrl b/jme3-testdata/src/main/resources/Materials/Tess/SimpleTess.tsctrl new file mode 100644 index 000000000..445276e42 --- /dev/null +++ b/jme3-testdata/src/main/resources/Materials/Tess/SimpleTess.tsctrl @@ -0,0 +1,13 @@ +layout (quads,equal_spacing,cw) in; + +uniform mat4 g_WorldViewProjectionMatrix; + +void main(){ + vec3 p0 = mix(gl_in[0].gl_Position.xyz, gl_in[3].gl_Position.xyz, gl_TessCoord.x); + // interpolate in horizontal direction between vert. 1 and 2 + vec3 p1 = mix(gl_in[1].gl_Position.xyz, gl_in[2].gl_Position.xyz, gl_TessCoord.x); + // interpolate in vert direction + vec3 tePosition = mix(p0, p1, gl_TessCoord.y); + gl_Position = g_WorldViewProjectionMatrix * vec4(tePosition, 1); +} + diff --git a/jme3-testdata/src/main/resources/Materials/Tess/SimpleTess.tseval b/jme3-testdata/src/main/resources/Materials/Tess/SimpleTess.tseval new file mode 100644 index 000000000..3f7074642 --- /dev/null +++ b/jme3-testdata/src/main/resources/Materials/Tess/SimpleTess.tseval @@ -0,0 +1,17 @@ +layout(vertices=4) out; +out gl_PerVertex{ + vec4 gl_Position; +}gl_out[]; +uniform int m_TessellationFactor; +void main(){ + if (gl_InvocationID == 0){ + gl_TessLevelOuter[0]=m_TessellationFactor; + gl_TessLevelOuter[1]=m_TessellationFactor; + gl_TessLevelOuter[2]=m_TessellationFactor; + gl_TessLevelOuter[3]=m_TessellationFactor; + + gl_TessLevelInner[0]=m_TessellationFactor; + gl_TessLevelInner[1]=m_TessellationFactor; + } + gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position; +} \ No newline at end of file diff --git a/jme3-testdata/src/main/resources/Materials/Tess/SimpleTess.vert b/jme3-testdata/src/main/resources/Materials/Tess/SimpleTess.vert new file mode 100644 index 000000000..f82ebb79b --- /dev/null +++ b/jme3-testdata/src/main/resources/Materials/Tess/SimpleTess.vert @@ -0,0 +1,5 @@ +attribute vec3 inPosition; + +void main(){ + gl_Position=vec4(inPosition,1); +} \ No newline at end of file