Merge pull request #220 from zzuegg/master
Geometry shader and Tessellation shader support
This commit is contained in:
commit
273f3a6e62
@ -450,16 +450,11 @@ public class DesktopAssetManager implements AssetManager {
|
|||||||
}
|
}
|
||||||
shader = shaderGenerator.generateShader();
|
shader = shaderGenerator.generateShader();
|
||||||
} else {
|
} 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 = new Shader();
|
||||||
shader.initialize();
|
shader.initialize();
|
||||||
shader.addSource(Shader.ShaderType.Vertex, vertName, vertSource, key.getDefines().getCompiled(), key.getVertexShaderLanguage());
|
for (Shader.ShaderType shaderType : key.getUsedShaderPrograms()) {
|
||||||
shader.addSource(Shader.ShaderType.Fragment, fragName, fragSource, key.getDefines().getCompiled(), key.getFragmentShaderLanguage());
|
shader.addSource(shaderType,key.getShaderProgramName(shaderType),(String) loadAsset(new AssetKey(key.getShaderProgramName(shaderType))),key.getDefines().getCompiled(),key.getShaderProgramLanguage(shaderType));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cache.addToCache(key, shader);
|
cache.addToCache(key, shader);
|
||||||
|
@ -190,11 +190,7 @@ public class Technique /* implements Savable */ {
|
|||||||
|
|
||||||
private void loadShader(AssetManager manager,EnumSet<Caps> rendererCaps) {
|
private void loadShader(AssetManager manager,EnumSet<Caps> rendererCaps) {
|
||||||
|
|
||||||
ShaderKey key = new ShaderKey(def.getVertexShaderName(),
|
ShaderKey key = new ShaderKey(getAllDefines(),def.getShaderProgramLanguages(),def.getShaderProgramNames());
|
||||||
def.getFragmentShaderName(),
|
|
||||||
getAllDefines(),
|
|
||||||
def.getVertexShaderLanguage(),
|
|
||||||
def.getFragmentShaderLanguage());
|
|
||||||
|
|
||||||
if (getDef().isUsingShaderNodes()) {
|
if (getDef().isUsingShaderNodes()) {
|
||||||
manager.getShaderGenerator(rendererCaps).initialize(this);
|
manager.getShaderGenerator(rendererCaps).initialize(this);
|
||||||
|
@ -33,16 +33,10 @@ package com.jme3.material;
|
|||||||
|
|
||||||
import com.jme3.export.*;
|
import com.jme3.export.*;
|
||||||
import com.jme3.renderer.Caps;
|
import com.jme3.renderer.Caps;
|
||||||
import com.jme3.renderer.Renderer;
|
import com.jme3.shader.*;
|
||||||
import com.jme3.shader.DefineList;
|
|
||||||
import com.jme3.shader.ShaderNode;
|
|
||||||
import com.jme3.shader.UniformBinding;
|
|
||||||
import com.jme3.shader.VarType;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.EnumSet;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Describes a technique definition.
|
* Describes a technique definition.
|
||||||
@ -100,10 +94,8 @@ public class TechniqueDef implements Savable {
|
|||||||
private EnumSet<Caps> requiredCaps = EnumSet.noneOf(Caps.class);
|
private EnumSet<Caps> requiredCaps = EnumSet.noneOf(Caps.class);
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
private String vertName;
|
private EnumMap<Shader.ShaderType,String> shaderLanguage;
|
||||||
private String fragName;
|
private EnumMap<Shader.ShaderType,String> shaderName;
|
||||||
private String vertLanguage;
|
|
||||||
private String fragLanguage;
|
|
||||||
|
|
||||||
private DefineList presetDefines;
|
private DefineList presetDefines;
|
||||||
private boolean usesShaders;
|
private boolean usesShaders;
|
||||||
@ -129,6 +121,7 @@ public class TechniqueDef implements Savable {
|
|||||||
* for default techniques.
|
* for default techniques.
|
||||||
*/
|
*/
|
||||||
public TechniqueDef(String name){
|
public TechniqueDef(String name){
|
||||||
|
this();
|
||||||
this.name = name == null ? "Default" : name;
|
this.name = name == null ? "Default" : name;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -136,6 +129,8 @@ public class TechniqueDef implements Savable {
|
|||||||
* Serialization only. Do not use.
|
* Serialization only. Do not use.
|
||||||
*/
|
*/
|
||||||
public TechniqueDef(){
|
public TechniqueDef(){
|
||||||
|
shaderLanguage=new EnumMap<Shader.ShaderType, String>(Shader.ShaderType.class);
|
||||||
|
shaderName=new EnumMap<Shader.ShaderType, String>(Shader.ShaderType.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -244,11 +239,10 @@ public class TechniqueDef implements Savable {
|
|||||||
* @param fragLanguage The fragment shader language
|
* @param fragLanguage The fragment shader language
|
||||||
*/
|
*/
|
||||||
public void setShaderFile(String vertexShader, String fragmentShader, String vertLanguage, String fragLanguage){
|
public void setShaderFile(String vertexShader, String fragmentShader, String vertLanguage, String fragLanguage){
|
||||||
this.vertName = vertexShader;
|
this.shaderLanguage.put(Shader.ShaderType.Vertex,shaderLanguage.get(vertLanguage));
|
||||||
this.fragName = fragmentShader;
|
this.shaderName.put(Shader.ShaderType.Vertex,shaderName.get(vertexShader));
|
||||||
this.vertLanguage = vertLanguage;
|
this.shaderLanguage.put(Shader.ShaderType.Fragment,shaderLanguage.get(fragLanguage));
|
||||||
this.fragLanguage = fragLanguage;
|
this.shaderName.put(Shader.ShaderType.Fragment,shaderName.get(fragmentShader));
|
||||||
|
|
||||||
Caps vertCap = Caps.valueOf(vertLanguage);
|
Caps vertCap = Caps.valueOf(vertLanguage);
|
||||||
requiredCaps.add(vertCap);
|
requiredCaps.add(vertCap);
|
||||||
Caps fragCap = Caps.valueOf(fragLanguage);
|
Caps fragCap = Caps.valueOf(fragLanguage);
|
||||||
@ -257,6 +251,26 @@ public class TechniqueDef implements Savable {
|
|||||||
usesShaders = true;
|
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<Shader.ShaderType, String> shaderName, EnumMap<Shader.ShaderType, String> 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.
|
* 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.
|
* @return the name of the fragment shader to be used.
|
||||||
*/
|
*/
|
||||||
public String getFragmentShaderName() {
|
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.
|
* @return the name of the vertex shader to be used.
|
||||||
*/
|
*/
|
||||||
public String getVertexShaderName() {
|
public String getVertexShaderName() {
|
||||||
return vertName;
|
return shaderName.get(Shader.ShaderType.Vertex);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -348,21 +362,34 @@ public class TechniqueDef implements Savable {
|
|||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public String getShaderLanguage() {
|
public String getShaderLanguage() {
|
||||||
return vertLanguage;
|
return shaderLanguage.get(Shader.ShaderType.Vertex);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the language of the fragment shader used in this technique.
|
* Returns the language of the fragment shader used in this technique.
|
||||||
*/
|
*/
|
||||||
public String getFragmentShaderLanguage() {
|
public String getFragmentShaderLanguage() {
|
||||||
return fragLanguage;
|
return shaderLanguage.get(Shader.ShaderType.Fragment);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the language of the vertex shader used in this technique.
|
* Returns the language of the vertex shader used in this technique.
|
||||||
*/
|
*/
|
||||||
public String getVertexShaderLanguage() {
|
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{
|
public void write(JmeExporter ex) throws IOException{
|
||||||
OutputCapsule oc = ex.getCapsule(this);
|
OutputCapsule oc = ex.getCapsule(this);
|
||||||
oc.write(name, "name", null);
|
oc.write(name, "name", null);
|
||||||
oc.write(vertName, "vertName", null);
|
|
||||||
oc.write(fragName, "fragName", null);
|
oc.write(shaderName.get(Shader.ShaderType.Vertex), "vertName", null);
|
||||||
oc.write(vertLanguage, "vertLanguage", null);
|
oc.write(shaderName.get(Shader.ShaderType.Fragment), "fragName", null);
|
||||||
oc.write(vertLanguage, "fragLanguage", 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(presetDefines, "presetDefines", null);
|
||||||
oc.write(lightMode, "lightMode", LightMode.Disable);
|
oc.write(lightMode, "lightMode", LightMode.Disable);
|
||||||
oc.write(shadowMode, "shadowMode", ShadowMode.Disable);
|
oc.write(shadowMode, "shadowMode", ShadowMode.Disable);
|
||||||
@ -428,8 +463,11 @@ public class TechniqueDef implements Savable {
|
|||||||
public void read(JmeImporter im) throws IOException{
|
public void read(JmeImporter im) throws IOException{
|
||||||
InputCapsule ic = im.getCapsule(this);
|
InputCapsule ic = im.getCapsule(this);
|
||||||
name = ic.readString("name", null);
|
name = ic.readString("name", null);
|
||||||
vertName = ic.readString("vertName", null);
|
shaderName.put(Shader.ShaderType.Vertex,ic.readString("vertName", null));
|
||||||
fragName = ic.readString("fragName", 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);
|
presetDefines = (DefineList) ic.readSavable("presetDefines", null);
|
||||||
lightMode = ic.readEnum("lightMode", LightMode.class, LightMode.Disable);
|
lightMode = ic.readEnum("lightMode", LightMode.class, LightMode.Disable);
|
||||||
shadowMode = ic.readEnum("shadowMode", ShadowMode.class, ShadowMode.Disable);
|
shadowMode = ic.readEnum("shadowMode", ShadowMode.class, ShadowMode.Disable);
|
||||||
@ -438,12 +476,15 @@ public class TechniqueDef implements Savable {
|
|||||||
|
|
||||||
if (ic.getSavableVersion(TechniqueDef.class) == 0) {
|
if (ic.getSavableVersion(TechniqueDef.class) == 0) {
|
||||||
// Old version
|
// Old version
|
||||||
vertLanguage = ic.readString("shaderLang", null);
|
shaderLanguage.put(Shader.ShaderType.Vertex,ic.readString("shaderLang", null));
|
||||||
fragLanguage = vertLanguage;
|
shaderLanguage.put(Shader.ShaderType.Fragment,shaderLanguage.get(Shader.ShaderType.Vertex));
|
||||||
} else {
|
} else {
|
||||||
// New version
|
// New version
|
||||||
vertLanguage = ic.readString("vertLanguage", null);
|
shaderLanguage.put(Shader.ShaderType.Vertex,ic.readString("vertLanguage", null));
|
||||||
fragLanguage = ic.readString("fragLanguage", 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);
|
usesNodes = ic.readBoolean("usesNodes", false);
|
||||||
@ -461,6 +502,22 @@ public class TechniqueDef implements Savable {
|
|||||||
usesShaders = true;
|
usesShaders = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the Enum containing the ShaderProgramNames;
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public EnumMap<Shader.ShaderType, String> getShaderProgramNames() {
|
||||||
|
return shaderName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the Enum containing the ShaderProgramLanguages;
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public EnumMap<Shader.ShaderType, String> getShaderProgramLanguages() {
|
||||||
|
return shaderLanguage;
|
||||||
|
}
|
||||||
|
|
||||||
public ShaderGenerationInfo getShaderGenerationInfo() {
|
public ShaderGenerationInfo getShaderGenerationInfo() {
|
||||||
return shaderGenerationInfo;
|
return shaderGenerationInfo;
|
||||||
}
|
}
|
||||||
@ -469,8 +526,9 @@ public class TechniqueDef implements Savable {
|
|||||||
this.shaderGenerationInfo = shaderGenerationInfo;
|
this.shaderGenerationInfo = shaderGenerationInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//todo: make toString return something usefull
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
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 + '}';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -120,7 +120,14 @@ public enum Caps {
|
|||||||
* Supports OpenGL 3.2
|
* Supports OpenGL 3.2
|
||||||
*/
|
*/
|
||||||
OpenGL32,
|
OpenGL32,
|
||||||
|
/**
|
||||||
|
* Supports OpenGL 3.3
|
||||||
|
*/
|
||||||
|
OpenGL33,
|
||||||
|
/**
|
||||||
|
* Supports OpenGL 4.0
|
||||||
|
*/
|
||||||
|
OpenGL40,
|
||||||
/**
|
/**
|
||||||
* Do not use.
|
* Do not use.
|
||||||
*
|
*
|
||||||
@ -163,7 +170,10 @@ public enum Caps {
|
|||||||
* Supports GLSL 3.3
|
* Supports GLSL 3.3
|
||||||
*/
|
*/
|
||||||
GLSL330,
|
GLSL330,
|
||||||
|
/**
|
||||||
|
* Supports GLSL 4.0
|
||||||
|
*/
|
||||||
|
GLSL400,
|
||||||
/**
|
/**
|
||||||
* Supports reading from textures inside the vertex shader.
|
* Supports reading from textures inside the vertex shader.
|
||||||
*/
|
*/
|
||||||
@ -173,7 +183,10 @@ public enum Caps {
|
|||||||
* Supports geometry shader.
|
* Supports geometry shader.
|
||||||
*/
|
*/
|
||||||
GeometryShader,
|
GeometryShader,
|
||||||
|
/**
|
||||||
|
* Supports Tesselation shader
|
||||||
|
*/
|
||||||
|
TesselationShader,
|
||||||
/**
|
/**
|
||||||
* Supports texture arrays
|
* Supports texture arrays
|
||||||
*/
|
*/
|
||||||
|
@ -41,7 +41,7 @@ import java.nio.IntBuffer;
|
|||||||
public interface GL3 extends GL2 {
|
public interface GL3 extends GL2 {
|
||||||
|
|
||||||
public static final int GL_DEPTH_STENCIL_ATTACHMENT = 0x821A;
|
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 glBindFragDataLocation(int param1, int param2, String param3); /// GL3+
|
||||||
public void glBindVertexArray(int param1); /// GL3+
|
public void glBindVertexArray(int param1); /// GL3+
|
||||||
public void glGenVertexArrays(IntBuffer param1); /// GL3+
|
public void glGenVertexArrays(IntBuffer param1); /// GL3+
|
||||||
|
46
jme3-core/src/main/java/com/jme3/renderer/opengl/GL4.java
Normal file
46
jme3-core/src/main/java/com/jme3/renderer/opengl/GL4.java
Normal file
@ -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);
|
||||||
|
}
|
@ -107,6 +107,7 @@ public class GLRenderer implements Renderer {
|
|||||||
private final GL gl;
|
private final GL gl;
|
||||||
private final GL2 gl2;
|
private final GL2 gl2;
|
||||||
private final GL3 gl3;
|
private final GL3 gl3;
|
||||||
|
private final GL4 gl4;
|
||||||
private final GLExt glext;
|
private final GLExt glext;
|
||||||
private final GLFbo glfbo;
|
private final GLFbo glfbo;
|
||||||
private final TextureUtil texUtil;
|
private final TextureUtil texUtil;
|
||||||
@ -115,6 +116,7 @@ public class GLRenderer implements Renderer {
|
|||||||
this.gl = gl;
|
this.gl = gl;
|
||||||
this.gl2 = gl instanceof GL2 ? (GL2)gl : null;
|
this.gl2 = gl instanceof GL2 ? (GL2)gl : null;
|
||||||
this.gl3 = gl instanceof GL3 ? (GL3)gl : null;
|
this.gl3 = gl instanceof GL3 ? (GL3)gl : null;
|
||||||
|
this.gl4 = gl instanceof GL4 ? (GL4)gl : null;
|
||||||
this.glfbo = glfbo;
|
this.glfbo = glfbo;
|
||||||
this.glext = glfbo instanceof GLExt ? (GLExt)glfbo : null;
|
this.glext = glfbo instanceof GLExt ? (GLExt)glfbo : null;
|
||||||
this.texUtil = new TextureUtil(gl, gl2, glext, context);
|
this.texUtil = new TextureUtil(gl, gl2, glext, context);
|
||||||
@ -183,6 +185,12 @@ public class GLRenderer implements Renderer {
|
|||||||
caps.add(Caps.OpenGL31);
|
caps.add(Caps.OpenGL31);
|
||||||
if (oglVer >= 320) {
|
if (oglVer >= 320) {
|
||||||
caps.add(Caps.OpenGL32);
|
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
|
// so that future OpenGL revisions wont break jme3
|
||||||
// fall through intentional
|
// fall through intentional
|
||||||
case 400:
|
case 400:
|
||||||
|
caps.add(Caps.GLSL400);
|
||||||
case 330:
|
case 330:
|
||||||
|
caps.add(Caps.GLSL330);
|
||||||
case 150:
|
case 150:
|
||||||
caps.add(Caps.GLSL150);
|
caps.add(Caps.GLSL150);
|
||||||
case 140:
|
case 140:
|
||||||
@ -1009,6 +1019,12 @@ public class GLRenderer implements Renderer {
|
|||||||
return GL.GL_FRAGMENT_SHADER;
|
return GL.GL_FRAGMENT_SHADER;
|
||||||
case Vertex:
|
case Vertex:
|
||||||
return GL.GL_VERTEX_SHADER;
|
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:
|
default:
|
||||||
throw new UnsupportedOperationException("Unrecognized shader type.");
|
throw new UnsupportedOperationException("Unrecognized shader type.");
|
||||||
}
|
}
|
||||||
@ -2520,6 +2536,8 @@ public class GLRenderer implements Renderer {
|
|||||||
return GL.GL_TRIANGLE_FAN;
|
return GL.GL_TRIANGLE_FAN;
|
||||||
case TriangleStrip:
|
case TriangleStrip:
|
||||||
return GL.GL_TRIANGLE_STRIP;
|
return GL.GL_TRIANGLE_STRIP;
|
||||||
|
case Patch:
|
||||||
|
return GL4.GL_PATCHES;
|
||||||
default:
|
default:
|
||||||
throw new UnsupportedOperationException("Unrecognized mesh mode: " + mode);
|
throw new UnsupportedOperationException("Unrecognized mesh mode: " + mode);
|
||||||
}
|
}
|
||||||
@ -2670,7 +2688,9 @@ public class GLRenderer implements Renderer {
|
|||||||
gl.glLineWidth(mesh.getLineWidth());
|
gl.glLineWidth(mesh.getLineWidth());
|
||||||
context.lineWidth = mesh.getLineWidth();
|
context.lineWidth = mesh.getLineWidth();
|
||||||
}
|
}
|
||||||
|
if(gl4!=null && mesh.getMode().equals(Mode.Patch)){
|
||||||
|
gl4.glPatchParameter(mesh.getPatchVertexCount());
|
||||||
|
}
|
||||||
statistics.onMeshDrawn(mesh, lod, count);
|
statistics.onMeshDrawn(mesh, lod, count);
|
||||||
// if (ctxCaps.GL_ARB_vertex_array_object){
|
// if (ctxCaps.GL_ARB_vertex_array_object){
|
||||||
// renderMeshVertexArray(mesh, lod, count);
|
// renderMeshVertexArray(mesh, lod, count);
|
||||||
|
@ -134,8 +134,12 @@ public class Mesh implements Savable, Cloneable {
|
|||||||
* {@link Mesh#setElementLengths(int[]) element lengths} must
|
* {@link Mesh#setElementLengths(int[]) element lengths} must
|
||||||
* be specified for this mode.
|
* 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 boolean listMode = false;
|
||||||
|
|
||||||
private Mode(boolean listMode){
|
private Mode(boolean listMode){
|
||||||
@ -175,6 +179,7 @@ public class Mesh implements Savable, Cloneable {
|
|||||||
private int vertCount = -1;
|
private int vertCount = -1;
|
||||||
private int elementCount = -1;
|
private int elementCount = -1;
|
||||||
private int instanceCount = -1;
|
private int instanceCount = -1;
|
||||||
|
private int patchVertexCount=3; //only used for tesselation
|
||||||
private int maxNumWeights = -1; // only if using skeletal animation
|
private int maxNumWeights = -1; // only if using skeletal animation
|
||||||
|
|
||||||
private int[] elementLengths;
|
private int[] elementLengths;
|
||||||
@ -728,6 +733,8 @@ public class Mesh implements Savable, Cloneable {
|
|||||||
return bufSize;
|
return bufSize;
|
||||||
case LineStrip:
|
case LineStrip:
|
||||||
return bufSize - 1;
|
return bufSize - 1;
|
||||||
|
case Patch:
|
||||||
|
return bufSize/patchVertexCount;
|
||||||
default:
|
default:
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
@ -1362,6 +1369,21 @@ public class Mesh implements Savable, Cloneable {
|
|||||||
getBuffer(Type.HWBoneIndex) != null;
|
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 {
|
public void write(JmeExporter ex) throws IOException {
|
||||||
OutputCapsule out = ex.getCapsule(this);
|
OutputCapsule out = ex.getCapsule(this);
|
||||||
|
@ -74,7 +74,15 @@ public final class Shader extends NativeObject {
|
|||||||
/**
|
/**
|
||||||
* Control geometry assembly. (e.g compile a triangle list from input data)
|
* 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -37,25 +37,31 @@ import com.jme3.export.JmeExporter;
|
|||||||
import com.jme3.export.JmeImporter;
|
import com.jme3.export.JmeImporter;
|
||||||
import com.jme3.export.OutputCapsule;
|
import com.jme3.export.OutputCapsule;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.EnumMap;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
public class ShaderKey extends AssetKey<Shader> {
|
public class ShaderKey extends AssetKey<Shader> {
|
||||||
|
|
||||||
protected String fragName;
|
protected EnumMap<Shader.ShaderType,String> shaderLanguage;
|
||||||
|
protected EnumMap<Shader.ShaderType,String> shaderName;
|
||||||
protected DefineList defines;
|
protected DefineList defines;
|
||||||
protected String vertLanguage;
|
|
||||||
protected String fragLanguage;
|
|
||||||
protected int cachedHashedCode = 0;
|
protected int cachedHashedCode = 0;
|
||||||
protected boolean usesShaderNodes = false;
|
protected boolean usesShaderNodes = false;
|
||||||
|
|
||||||
public ShaderKey(){
|
public ShaderKey(){
|
||||||
|
shaderLanguage=new EnumMap<Shader.ShaderType, String>(Shader.ShaderType.class);
|
||||||
|
shaderName=new EnumMap<Shader.ShaderType, String>(Shader.ShaderType.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ShaderKey(String vertName, String fragName, DefineList defines, String vertLanguage, String fragLanguage){
|
public ShaderKey(DefineList defines, EnumMap<Shader.ShaderType,String> shaderLanguage,EnumMap<Shader.ShaderType,String> shaderName){
|
||||||
super(vertName);
|
super(shaderName.get(Shader.ShaderType.Vertex));
|
||||||
this.fragName = fragName;
|
this.shaderLanguage=new EnumMap<Shader.ShaderType, String>(Shader.ShaderType.class);
|
||||||
|
this.shaderName=new EnumMap<Shader.ShaderType, String>(Shader.ShaderType.class);
|
||||||
this.defines = defines;
|
this.defines = defines;
|
||||||
this.vertLanguage = vertLanguage;
|
for (Shader.ShaderType shaderType : shaderName.keySet()) {
|
||||||
this.fragLanguage = fragLanguage;
|
this.shaderName.put(shaderType,shaderName.get(shaderType));
|
||||||
|
this.shaderLanguage.put(shaderType,shaderLanguage.get(shaderType));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -68,13 +74,15 @@ public class ShaderKey extends AssetKey<Shader> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString(){
|
public String toString(){
|
||||||
return "V="+name + " F=" + fragName + (defines != null ? defines : "");
|
//todo:
|
||||||
|
return "V="+name+";";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//todo: make equals and hashCode work
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object obj) {
|
public boolean equals(Object obj) {
|
||||||
final ShaderKey other = (ShaderKey) 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) {
|
if (defines != null && other.defines != null) {
|
||||||
return defines.equals(other.defines);
|
return defines.equals(other.defines);
|
||||||
} else if (defines != null || other.defines != null) {
|
} else if (defines != null || other.defines != null) {
|
||||||
@ -91,7 +99,10 @@ public class ShaderKey extends AssetKey<Shader> {
|
|||||||
if (cachedHashedCode == 0) {
|
if (cachedHashedCode == 0) {
|
||||||
int hash = 7;
|
int hash = 7;
|
||||||
hash = 41 * hash + name.hashCode();
|
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);
|
hash = 41 * hash + (defines != null ? defines.hashCode() : 0);
|
||||||
cachedHashedCode = hash;
|
cachedHashedCode = hash;
|
||||||
}
|
}
|
||||||
@ -103,11 +114,11 @@ public class ShaderKey extends AssetKey<Shader> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public String getVertName(){
|
public String getVertName(){
|
||||||
return name;
|
return shaderName.get(Shader.ShaderType.Vertex);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getFragName() {
|
public String getFragName() {
|
||||||
return fragName;
|
return shaderName.get(Shader.ShaderType.Fragment);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -115,15 +126,15 @@ public class ShaderKey extends AssetKey<Shader> {
|
|||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public String getLanguage() {
|
public String getLanguage() {
|
||||||
return vertLanguage;
|
return shaderLanguage.get(Shader.ShaderType.Vertex);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getVertexShaderLanguage() {
|
public String getVertexShaderLanguage() {
|
||||||
return vertLanguage;
|
return shaderLanguage.get(Shader.ShaderType.Vertex);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getFragmentShaderLanguage() {
|
public String getFragmentShaderLanguage() {
|
||||||
return fragLanguage;
|
return shaderLanguage.get(Shader.ShaderType.Vertex);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isUsesShaderNodes() {
|
public boolean isUsesShaderNodes() {
|
||||||
@ -134,22 +145,48 @@ public class ShaderKey extends AssetKey<Shader> {
|
|||||||
this.usesShaderNodes = usesShaderNodes;
|
this.usesShaderNodes = usesShaderNodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Set<Shader.ShaderType> 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
|
@Override
|
||||||
public void write(JmeExporter ex) throws IOException{
|
public void write(JmeExporter ex) throws IOException{
|
||||||
super.write(ex);
|
super.write(ex);
|
||||||
OutputCapsule oc = ex.getCapsule(this);
|
OutputCapsule oc = ex.getCapsule(this);
|
||||||
oc.write(fragName, "fragment_name", null);
|
oc.write(shaderName.get(Shader.ShaderType.Fragment), "fragment_name", null);
|
||||||
oc.write(vertLanguage, "language", null);
|
oc.write(shaderName.get(Shader.ShaderType.Geometry), "geometry_name", null);
|
||||||
oc.write(fragLanguage, "frag_language", 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
|
@Override
|
||||||
public void read(JmeImporter im) throws IOException{
|
public void read(JmeImporter im) throws IOException{
|
||||||
super.read(im);
|
super.read(im);
|
||||||
InputCapsule ic = im.getCapsule(this);
|
InputCapsule ic = im.getCapsule(this);
|
||||||
fragName = ic.readString("fragment_name", null);
|
shaderName.put(Shader.ShaderType.Vertex,name);
|
||||||
vertLanguage = ic.readString("language", null);
|
shaderName.put(Shader.ShaderType.Fragment,ic.readString("fragment_name", null));
|
||||||
fragLanguage = ic.readString("frag_language", 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));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -2,4 +2,26 @@ INCLUDE com/jme3/asset/General.cfg
|
|||||||
|
|
||||||
# Desktop-specific loaders
|
# Desktop-specific loaders
|
||||||
LOADER com.jme3.texture.plugins.AWTLoader : jpg, bmp, gif, png, jpeg
|
LOADER com.jme3.texture.plugins.AWTLoader : jpg, bmp, gif, png, jpeg
|
||||||
|
LOADER com.jme3.audio.plugins.OGGLoader : oggLOADER com.jme3.audio.plugins.WAVLoader : wav
|
||||||
LOADER com.jme3.audio.plugins.OGGLoader : ogg
|
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
|
||||||
|
@ -40,6 +40,7 @@ import com.jme3.material.TechniqueDef.ShadowMode;
|
|||||||
import com.jme3.math.ColorRGBA;
|
import com.jme3.math.ColorRGBA;
|
||||||
import com.jme3.math.Vector2f;
|
import com.jme3.math.Vector2f;
|
||||||
import com.jme3.math.Vector3f;
|
import com.jme3.math.Vector3f;
|
||||||
|
import com.jme3.shader.Shader;
|
||||||
import com.jme3.shader.VarType;
|
import com.jme3.shader.VarType;
|
||||||
import com.jme3.texture.Texture;
|
import com.jme3.texture.Texture;
|
||||||
import com.jme3.texture.Texture.WrapMode;
|
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.PlaceholderAssets;
|
||||||
import com.jme3.util.blockparser.BlockLanguageParser;
|
import com.jme3.util.blockparser.BlockLanguageParser;
|
||||||
import com.jme3.util.blockparser.Statement;
|
import com.jme3.util.blockparser.Statement;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.util.EnumMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
@ -69,15 +72,14 @@ public class J3MLoader implements AssetLoader {
|
|||||||
private TechniqueDef technique;
|
private TechniqueDef technique;
|
||||||
private RenderState renderState;
|
private RenderState renderState;
|
||||||
|
|
||||||
private String vertLanguage;
|
private EnumMap<Shader.ShaderType, String> shaderLanguage;
|
||||||
private String fragLanguage;
|
private EnumMap<Shader.ShaderType, String> shaderName;
|
||||||
|
|
||||||
private String vertName;
|
|
||||||
private String fragName;
|
|
||||||
|
|
||||||
private static final String whitespacePattern = "\\p{javaWhitespace}+";
|
private static final String whitespacePattern = "\\p{javaWhitespace}+";
|
||||||
|
|
||||||
public J3MLoader(){
|
public J3MLoader() {
|
||||||
|
shaderLanguage = new EnumMap<Shader.ShaderType, String>(Shader.ShaderType.class);
|
||||||
|
shaderName = new EnumMap<Shader.ShaderType, String>(Shader.ShaderType.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -92,15 +94,18 @@ public class J3MLoader implements AssetLoader {
|
|||||||
throw new IOException("Shader statement syntax incorrect: " + statement);
|
throw new IOException("Shader statement syntax incorrect: " + statement);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeAndLang[0].equals("VertexShader")) {
|
for (Shader.ShaderType shaderType : Shader.ShaderType.values()) {
|
||||||
vertName = split[1].trim();
|
if (typeAndLang[0].equals(shaderType.toString() + "Shader")) {
|
||||||
vertLanguage = typeAndLang[1];
|
readShaderDefinition(shaderType, split[1].trim(), typeAndLang[1]);
|
||||||
} else if (typeAndLang[0].equals("FragmentShader")) {
|
}
|
||||||
fragName = split[1].trim();
|
|
||||||
fragLanguage = typeAndLang[1];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void readShaderDefinition(Shader.ShaderType shaderType, String name, String language) {
|
||||||
|
shaderName.put(shaderType, name);
|
||||||
|
shaderLanguage.put(shaderType, language);
|
||||||
|
}
|
||||||
|
|
||||||
// LightMode <MODE>
|
// LightMode <MODE>
|
||||||
private void readLightMode(String statement) throws IOException{
|
private void readLightMode(String statement) throws IOException{
|
||||||
String[] split = statement.split(whitespacePattern);
|
String[] split = statement.split(whitespacePattern);
|
||||||
@ -403,7 +408,10 @@ public class J3MLoader implements AssetLoader {
|
|||||||
private void readTechniqueStatement(Statement statement) throws IOException{
|
private void readTechniqueStatement(Statement statement) throws IOException{
|
||||||
String[] split = statement.getLine().split("[ \\{]");
|
String[] split = statement.getLine().split("[ \\{]");
|
||||||
if (split[0].equals("VertexShader") ||
|
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());
|
readShaderStatement(statement.getLine());
|
||||||
}else if (split[0].equals("LightMode")){
|
}else if (split[0].equals("LightMode")){
|
||||||
readLightMode(statement.getLine());
|
readLightMode(statement.getLine());
|
||||||
@ -467,16 +475,14 @@ public class J3MLoader implements AssetLoader {
|
|||||||
technique.setShaderFile(technique.hashCode() + "", technique.hashCode() + "", "GLSL100", "GLSL100");
|
technique.setShaderFile(technique.hashCode() + "", technique.hashCode() + "", "GLSL100", "GLSL100");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vertName != null && fragName != null){
|
if (shaderName.containsKey(Shader.ShaderType.Vertex) && shaderName.containsKey(Shader.ShaderType.Fragment)) {
|
||||||
technique.setShaderFile(vertName, fragName, vertLanguage, fragLanguage);
|
technique.setShaderFile(shaderName, shaderLanguage);
|
||||||
}
|
}
|
||||||
|
|
||||||
materialDef.addTechniqueDef(technique);
|
materialDef.addTechniqueDef(technique);
|
||||||
technique = null;
|
technique = null;
|
||||||
vertName = null;
|
shaderLanguage.clear();
|
||||||
fragName = null;
|
shaderName.clear();
|
||||||
vertLanguage = null;
|
|
||||||
fragLanguage = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loadFromRoot(List<Statement> roots) throws IOException{
|
private void loadFromRoot(List<Statement> roots) throws IOException{
|
||||||
@ -594,9 +600,9 @@ public class J3MLoader implements AssetLoader {
|
|||||||
|
|
||||||
protected void initNodesLoader() {
|
protected void initNodesLoader() {
|
||||||
if (!isUseNodes) {
|
if (!isUseNodes) {
|
||||||
isUseNodes = fragName == null && vertName == null;
|
isUseNodes = shaderName.get(Shader.ShaderType.Vertex) == null && shaderName.get(Shader.ShaderType.Fragment) == null;
|
||||||
if (isUseNodes) {
|
if (isUseNodes) {
|
||||||
if(nodesLoaderDelegate == null){
|
if (nodesLoaderDelegate == null) {
|
||||||
nodesLoaderDelegate = new ShaderNodeLoaderDelegate();
|
nodesLoaderDelegate = new ShaderNodeLoaderDelegate();
|
||||||
}else{
|
}else{
|
||||||
nodesLoaderDelegate.clear();
|
nodesLoaderDelegate.clear();
|
||||||
|
@ -30,7 +30,7 @@ public class ShaderCheck {
|
|||||||
assetManager.registerLocator("/", ClasspathLocator.class);
|
assetManager.registerLocator("/", ClasspathLocator.class);
|
||||||
assetManager.registerLoader(J3MLoader.class, "j3m");
|
assetManager.registerLoader(J3MLoader.class, "j3m");
|
||||||
assetManager.registerLoader(J3MLoader.class, "j3md");
|
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){
|
private static void checkMatDef(String matdefName){
|
||||||
@ -38,11 +38,8 @@ public class ShaderCheck {
|
|||||||
for (TechniqueDef techDef : def.getDefaultTechniques()){
|
for (TechniqueDef techDef : def.getDefaultTechniques()){
|
||||||
DefineList dl = new DefineList();
|
DefineList dl = new DefineList();
|
||||||
dl.addFrom(techDef.getShaderPresetDefines());
|
dl.addFrom(techDef.getShaderPresetDefines());
|
||||||
ShaderKey shaderKey = new ShaderKey(techDef.getVertexShaderName(),
|
ShaderKey shaderKey = new ShaderKey(dl,techDef.getShaderProgramLanguages(),techDef.getShaderProgramNames());
|
||||||
techDef.getFragmentShaderName(),
|
|
||||||
dl,
|
|
||||||
techDef.getVertexShaderLanguage(),
|
|
||||||
techDef.getFragmentShaderLanguage());
|
|
||||||
Shader shader = assetManager.loadShader(shaderKey);
|
Shader shader = assetManager.loadShader(shaderKey);
|
||||||
|
|
||||||
for (Validator validator : validators){
|
for (Validator validator : validators){
|
||||||
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
@ -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<Boolean>() {
|
||||||
|
@Override
|
||||||
|
public Boolean call() throws Exception {
|
||||||
|
tessellationMaterial.setInt("TessellationFactor",tessFactor);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if(name.equals("TessDo")){
|
||||||
|
tessFactor--;
|
||||||
|
enqueue(new Callable<Boolean>() {
|
||||||
|
@Override
|
||||||
|
public Boolean call() throws Exception {
|
||||||
|
tessellationMaterial.setInt("TessellationFactor",tessFactor);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},"TessUp","TessDo");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
new TestTessellationShader().start();
|
||||||
|
}
|
||||||
|
}
|
@ -9,14 +9,11 @@ import java.nio.ByteBuffer;
|
|||||||
import java.nio.FloatBuffer;
|
import java.nio.FloatBuffer;
|
||||||
import java.nio.IntBuffer;
|
import java.nio.IntBuffer;
|
||||||
import java.nio.ShortBuffer;
|
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) {
|
private static void checkLimit(Buffer buffer) {
|
||||||
if (buffer == null) {
|
if (buffer == null) {
|
||||||
@ -442,4 +439,9 @@ public class LwjglGL implements GL, GL2, GL3 {
|
|||||||
checkLimit(param1);
|
checkLimit(param1);
|
||||||
GL30.glGenVertexArrays(param1);
|
GL30.glGenVertexArrays(param1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void glPatchParameter(int count) {
|
||||||
|
GL40.glPatchParameteri(GL40.GL_PATCH_VERTICES,count);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,3 @@
|
|||||||
|
void main(){
|
||||||
|
gl_FragColor=vec4(1.0,0.0,1.0,0.5);
|
||||||
|
}
|
@ -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();
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,4 @@
|
|||||||
|
Material Pong Rock : Materials/Geom/SimpleGeom.j3md {
|
||||||
|
MaterialParameters {
|
||||||
|
}
|
||||||
|
}
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,5 @@
|
|||||||
|
attribute vec3 inPosition;
|
||||||
|
|
||||||
|
void main(){
|
||||||
|
gl_Position=vec4(inPosition,1);
|
||||||
|
}
|
@ -0,0 +1,3 @@
|
|||||||
|
void main(){
|
||||||
|
gl_FragColor=vec4(1.0,0.0,1.0,0.5);
|
||||||
|
}
|
@ -0,0 +1,4 @@
|
|||||||
|
Material Pong Rock : Materials/Tess/SimpleTess.j3md {
|
||||||
|
MaterialParameters {
|
||||||
|
}
|
||||||
|
}
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -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);
|
||||||
|
}
|
||||||
|
|
@ -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;
|
||||||
|
}
|
@ -0,0 +1,5 @@
|
|||||||
|
attribute vec3 inPosition;
|
||||||
|
|
||||||
|
void main(){
|
||||||
|
gl_Position=vec4(inPosition,1);
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user