* Shader now stores shader language in the ShaderSources instead of the Shader itself (everything makes a lot more sense now).
^ Make sure your shader languages are appropriate for each shader type (vert / frag) in your J3MS! * Shaders no longer have the "usable" member and the renderers don't use it either (its useless) git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@9545 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
This commit is contained in:
parent
af7435ffdf
commit
55d75c5abc
@ -590,6 +590,18 @@ public class OGLESShaderRenderer implements Renderer {
|
||||
}
|
||||
}
|
||||
|
||||
protected void bindProgram(Shader shader) {
|
||||
int shaderId = shader.getId();
|
||||
if (context.boundShaderProgram != shaderId) {
|
||||
GLES20.glUseProgram(shaderId);
|
||||
statistics.onShaderUse(shader, true);
|
||||
boundShader = shader;
|
||||
context.boundShaderProgram = shaderId;
|
||||
} else {
|
||||
statistics.onShaderUse(shader, false);
|
||||
}
|
||||
}
|
||||
|
||||
protected void updateUniform(Shader shader, Uniform uniform) {
|
||||
int shaderId = shader.getId();
|
||||
|
||||
@ -698,7 +710,6 @@ public class OGLESShaderRenderer implements Renderer {
|
||||
|
||||
protected void updateShaderUniforms(Shader shader) {
|
||||
ListMap<String, Uniform> uniforms = shader.getUniformMap();
|
||||
// for (Uniform uniform : shader.getUniforms()){
|
||||
for (int i = 0; i < uniforms.size(); i++) {
|
||||
Uniform uniform = uniforms.getValue(i);
|
||||
if (uniform.isUpdateNeeded()) {
|
||||
@ -709,7 +720,6 @@ public class OGLESShaderRenderer implements Renderer {
|
||||
|
||||
protected void resetUniformLocations(Shader shader) {
|
||||
ListMap<String, Uniform> uniforms = shader.getUniformMap();
|
||||
// for (Uniform uniform : shader.getUniforms()){
|
||||
for (int i = 0; i < uniforms.size(); i++) {
|
||||
Uniform uniform = uniforms.getValue(i);
|
||||
uniform.reset(); // e.g check location again
|
||||
@ -736,27 +746,28 @@ public class OGLESShaderRenderer implements Renderer {
|
||||
}
|
||||
}
|
||||
|
||||
public void updateShaderSourceData(ShaderSource source, String language) {
|
||||
public void updateShaderSourceData(ShaderSource source) {
|
||||
int id = source.getId();
|
||||
if (id == -1) {
|
||||
// create id
|
||||
// Create id
|
||||
id = GLES20.glCreateShader(convertShaderType(source.getType()));
|
||||
if (id <= 0) {
|
||||
throw new RendererException("Invalid ID received when trying to create shader.");
|
||||
}
|
||||
source.setId(id);
|
||||
}
|
||||
|
||||
if (!source.getLanguage().equals("GLSL100")) {
|
||||
throw new RendererException("This shader cannot run in OpenGL ES. "
|
||||
+ "Only GLSL 1.0 shaders are supported.");
|
||||
}
|
||||
|
||||
// upload shader source
|
||||
// merge the defines and source code
|
||||
byte[] versionData = new byte[]{};//"#version 140\n".getBytes();
|
||||
// versionData = "#define INSTANCING 1\n".getBytes();
|
||||
byte[] definesCodeData = source.getDefines().getBytes();
|
||||
byte[] sourceCodeData = source.getSource().getBytes();
|
||||
ByteBuffer codeBuf = BufferUtils.createByteBuffer(versionData.length
|
||||
+ definesCodeData.length
|
||||
+ sourceCodeData.length);
|
||||
codeBuf.put(versionData);
|
||||
ByteBuffer codeBuf = BufferUtils.createByteBuffer(definesCodeData.length
|
||||
+ sourceCodeData.length);
|
||||
codeBuf.put(definesCodeData);
|
||||
codeBuf.put(sourceCodeData);
|
||||
codeBuf.flip();
|
||||
@ -791,10 +802,11 @@ public class OGLESShaderRenderer implements Renderer {
|
||||
|
||||
if (compiledOK) {
|
||||
if (infoLog != null) {
|
||||
logger.log(Level.INFO, "compile success: " + source.getName() + ", " + infoLog);
|
||||
logger.log(Level.INFO, "compile success: {0}, {1}", new Object[]{source.getName(), infoLog});
|
||||
} else {
|
||||
logger.log(Level.FINE, "compile success: " + source.getName());
|
||||
logger.log(Level.FINE, "compile success: {0}", source.getName());
|
||||
}
|
||||
source.clearUpdateNeeded();
|
||||
} else {
|
||||
logger.log(Level.WARNING, "Bad compile of:\n{0}",
|
||||
new Object[]{ShaderDebug.formatShaderSource(source.getDefines(), source.getSource(),stringBuf.toString())});
|
||||
@ -804,18 +816,6 @@ public class OGLESShaderRenderer implements Renderer {
|
||||
throw new RendererException("compile error in:" + source + " error: <not provided>");
|
||||
}
|
||||
}
|
||||
|
||||
source.clearUpdateNeeded();
|
||||
// only usable if compiled
|
||||
source.setUsable(compiledOK);
|
||||
if (!compiledOK) {
|
||||
// make sure to dispose id cause all program's
|
||||
// shaders will be cleared later.
|
||||
GLES20.glDeleteShader(id);
|
||||
} else {
|
||||
// register for cleanup since the ID is usable
|
||||
objManager.registerForCleanup(source);
|
||||
}
|
||||
}
|
||||
|
||||
public void updateShaderData(Shader shader) {
|
||||
@ -835,15 +835,7 @@ public class OGLESShaderRenderer implements Renderer {
|
||||
|
||||
for (ShaderSource source : shader.getSources()) {
|
||||
if (source.isUpdateNeeded()) {
|
||||
updateShaderSourceData(source, shader.getLanguage());
|
||||
// shader has been compiled here
|
||||
}
|
||||
|
||||
if (!source.isUsable()) {
|
||||
// it's useless.. just forget about everything..
|
||||
shader.setUsable(false);
|
||||
shader.clearUpdateNeeded();
|
||||
return;
|
||||
updateShaderSourceData(source);
|
||||
}
|
||||
GLES20.glAttachShader(id, source.getId());
|
||||
}
|
||||
@ -871,6 +863,15 @@ public class OGLESShaderRenderer implements Renderer {
|
||||
} else {
|
||||
logger.fine("shader link success");
|
||||
}
|
||||
shader.clearUpdateNeeded();
|
||||
if (needRegister) {
|
||||
// Register shader for clean up if it was created in this method.
|
||||
objManager.registerForCleanup(shader);
|
||||
statistics.onNewShader();
|
||||
} else {
|
||||
// OpenGL spec: uniform locations may change after re-link
|
||||
resetUniformLocations(shader);
|
||||
}
|
||||
} else {
|
||||
if (infoLog != null) {
|
||||
throw new RendererException("Shader link failure, shader:" + shader + " info:" + infoLog);
|
||||
@ -878,34 +879,11 @@ public class OGLESShaderRenderer implements Renderer {
|
||||
throw new RendererException("Shader link failure, shader:" + shader + " info: <not provided>");
|
||||
}
|
||||
}
|
||||
|
||||
shader.clearUpdateNeeded();
|
||||
if (!linkOK) {
|
||||
// failure.. forget about everything
|
||||
shader.resetSources();
|
||||
shader.setUsable(false);
|
||||
deleteShader(shader);
|
||||
} else {
|
||||
shader.setUsable(true);
|
||||
if (needRegister) {
|
||||
objManager.registerForCleanup(shader);
|
||||
statistics.onNewShader();
|
||||
} else {
|
||||
// OpenGL spec: uniform locations may change after re-link
|
||||
resetUniformLocations(shader);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void setShader(Shader shader) {
|
||||
if (shader == null) {
|
||||
if (context.boundShaderProgram > 0) {
|
||||
GLES20.glUseProgram(0);
|
||||
|
||||
statistics.onShaderUse(null, true);
|
||||
context.boundShaderProgram = 0;
|
||||
boundShader = null;
|
||||
}
|
||||
throw new IllegalArgumentException("Shader cannot be null");
|
||||
} else {
|
||||
if (shader.isUpdateNeeded()) {
|
||||
updateShaderData(shader);
|
||||
@ -913,37 +891,11 @@ public class OGLESShaderRenderer implements Renderer {
|
||||
|
||||
// NOTE: might want to check if any of the
|
||||
// sources need an update?
|
||||
if (!shader.isUsable()) {
|
||||
logger.warning("shader is not usable.");
|
||||
return;
|
||||
}
|
||||
|
||||
assert shader.getId() > 0;
|
||||
|
||||
updateShaderUniforms(shader);
|
||||
if (context.boundShaderProgram != shader.getId()) {
|
||||
if (VALIDATE_SHADER) {
|
||||
// check if shader can be used
|
||||
// with current state
|
||||
GLES20.glValidateProgram(shader.getId());
|
||||
GLES20.glGetProgramiv(shader.getId(), GLES20.GL_VALIDATE_STATUS, intBuf1);
|
||||
|
||||
boolean validateOK = intBuf1.get(0) == GLES20.GL_TRUE;
|
||||
if (validateOK) {
|
||||
logger.fine("shader validate success");
|
||||
} else {
|
||||
logger.warning("shader validate failure");
|
||||
}
|
||||
}
|
||||
|
||||
GLES20.glUseProgram(shader.getId());
|
||||
|
||||
statistics.onShaderUse(shader, true);
|
||||
context.boundShaderProgram = shader.getId();
|
||||
boundShader = shader;
|
||||
} else {
|
||||
statistics.onShaderUse(shader, false);
|
||||
}
|
||||
bindProgram(shader);
|
||||
}
|
||||
}
|
||||
|
||||
@ -952,9 +904,8 @@ public class OGLESShaderRenderer implements Renderer {
|
||||
logger.warning("Shader source is not uploaded to GPU, cannot delete.");
|
||||
return;
|
||||
}
|
||||
source.setUsable(false);
|
||||
|
||||
source.clearUpdateNeeded();
|
||||
|
||||
GLES20.glDeleteShader(source.getId());
|
||||
source.resetObject();
|
||||
}
|
||||
@ -964,20 +915,17 @@ public class OGLESShaderRenderer implements Renderer {
|
||||
logger.warning("Shader is not uploaded to GPU, cannot delete.");
|
||||
return;
|
||||
}
|
||||
|
||||
for (ShaderSource source : shader.getSources()) {
|
||||
if (source.getId() != -1) {
|
||||
GLES20.glDetachShader(shader.getId(), source.getId());
|
||||
// the next part is done by the GLObjectManager automatically
|
||||
// glDeleteShader(source.getId());
|
||||
deleteShaderSource(source);
|
||||
}
|
||||
}
|
||||
// kill all references so sources can be collected
|
||||
// if needed.
|
||||
shader.resetSources();
|
||||
|
||||
|
||||
GLES20.glDeleteProgram(shader.getId());
|
||||
|
||||
statistics.onDeleteShader();
|
||||
shader.resetObject();
|
||||
}
|
||||
|
||||
/*********************************************************************\
|
||||
|
@ -8,7 +8,7 @@ MaterialDef Bloom Final {
|
||||
}
|
||||
|
||||
Technique {
|
||||
VertexShader GLSL100: Common/MatDefs/Post/Post15.vert
|
||||
VertexShader GLSL150: Common/MatDefs/Post/Post15.vert
|
||||
FragmentShader GLSL150: Common/MatDefs/Post/bloomFinal15.frag
|
||||
|
||||
WorldParameters {
|
||||
@ -28,9 +28,4 @@ MaterialDef Bloom Final {
|
||||
WorldViewProjectionMatrix
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Technique FixedFunc {
|
||||
}
|
||||
}
|
@ -336,11 +336,6 @@ public class DesktopAssetManager implements AssetManager {
|
||||
return loadAsset(new AssetKey(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a texture.
|
||||
*
|
||||
* @return the texture
|
||||
*/
|
||||
public Texture loadTexture(TextureKey key){
|
||||
return (Texture) loadAsset(key);
|
||||
}
|
||||
@ -365,18 +360,16 @@ public class DesktopAssetManager implements AssetManager {
|
||||
return loadAudio(new AudioKey(name, false));
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a bitmap font with the given name.
|
||||
*
|
||||
* @param name
|
||||
* @return the loaded {@link BitmapFont}
|
||||
*/
|
||||
public BitmapFont loadFont(String name){
|
||||
return (BitmapFont) loadAsset(new AssetKey(name));
|
||||
}
|
||||
|
||||
public InputStream loadGLSLLibrary(AssetKey key){
|
||||
return (InputStream) loadAsset(key);
|
||||
public Spatial loadModel(ModelKey key){
|
||||
return (Spatial) loadAsset(key);
|
||||
}
|
||||
|
||||
public Spatial loadModel(String name){
|
||||
return loadModel(new ModelKey(name));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -389,34 +382,21 @@ public class DesktopAssetManager implements AssetManager {
|
||||
// cache abuse in method
|
||||
// that doesn't use loaders/locators
|
||||
AssetCache cache = handler.getCache(SimpleAssetCache.class);
|
||||
Shader s = (Shader) cache.getFromCache(key);
|
||||
if (s == null){
|
||||
Shader shader = (Shader) cache.getFromCache(key);
|
||||
if (shader == null){
|
||||
String vertName = key.getVertName();
|
||||
String fragName = key.getFragName();
|
||||
|
||||
String vertSource = (String) loadAsset(new AssetKey(vertName));
|
||||
String fragSource = (String) loadAsset(new AssetKey(fragName));
|
||||
|
||||
s = new Shader(key.getLanguage());
|
||||
s.addSource(Shader.ShaderType.Vertex, vertName, vertSource, key.getDefines().getCompiled());
|
||||
s.addSource(Shader.ShaderType.Fragment, fragName, fragSource, key.getDefines().getCompiled());
|
||||
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());
|
||||
|
||||
cache.addToCache(key, s);
|
||||
cache.addToCache(key, shader);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
public Spatial loadModel(ModelKey key){
|
||||
return (Spatial) loadAsset(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a model.
|
||||
*
|
||||
* @param name
|
||||
* @return the loaded model
|
||||
*/
|
||||
public Spatial loadModel(String name){
|
||||
return loadModel(new ModelKey(name));
|
||||
return shader;
|
||||
}
|
||||
}
|
||||
|
@ -32,9 +32,7 @@
|
||||
package com.jme3.material;
|
||||
|
||||
import com.jme3.asset.AssetManager;
|
||||
import com.jme3.export.*;
|
||||
import com.jme3.shader.*;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
@ -43,7 +41,7 @@ import java.util.logging.Logger;
|
||||
/**
|
||||
* Represents a technique instance.
|
||||
*/
|
||||
public class Technique implements Savable {
|
||||
public class Technique /* implements Savable */ {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(Technique.class.getName());
|
||||
private TechniqueDef def;
|
||||
@ -133,6 +131,10 @@ public class Technique implements Savable {
|
||||
}
|
||||
|
||||
void updateUniformParam(String paramName, VarType type, Object value) {
|
||||
if (paramName == null) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
Uniform u = shader.getUniform(paramName);
|
||||
switch (type) {
|
||||
case TextureBuffer:
|
||||
@ -208,7 +210,8 @@ public class Technique implements Savable {
|
||||
ShaderKey key = new ShaderKey(def.getVertexShaderName(),
|
||||
def.getFragmentShaderName(),
|
||||
allDefines,
|
||||
def.getShaderLanguage());
|
||||
def.getVertexShaderLanguage(),
|
||||
def.getFragmentShaderLanguage());
|
||||
shader = manager.loadShader(key);
|
||||
|
||||
// register the world bound uniforms
|
||||
@ -225,6 +228,7 @@ public class Technique implements Savable {
|
||||
needReload = false;
|
||||
}
|
||||
|
||||
/*
|
||||
public void write(JmeExporter ex) throws IOException {
|
||||
OutputCapsule oc = ex.getCapsule(this);
|
||||
oc.write(def, "def", null);
|
||||
@ -240,4 +244,5 @@ public class Technique implements Savable {
|
||||
defines = (DefineList) ic.readSavable("defines", null);
|
||||
shader = (Shader) ic.readSavable("shader", null);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
@ -51,6 +51,11 @@ import java.util.List;
|
||||
*/
|
||||
public class TechniqueDef implements Savable {
|
||||
|
||||
/**
|
||||
* Version #1: Separate shader language for each shader source.
|
||||
*/
|
||||
public static final int SAVABLE_VERSION = 1;
|
||||
|
||||
/**
|
||||
* Describes light rendering mode.
|
||||
*/
|
||||
@ -101,7 +106,9 @@ public class TechniqueDef implements Savable {
|
||||
|
||||
private String vertName;
|
||||
private String fragName;
|
||||
private String shaderLang;
|
||||
private String vertLanguage;
|
||||
private String fragLanguage;
|
||||
|
||||
private DefineList presetDefines;
|
||||
private boolean usesShaders;
|
||||
|
||||
@ -227,13 +234,16 @@ public class TechniqueDef implements Savable {
|
||||
* @param fragmentShader The name of the fragment shader
|
||||
* @param shaderLanguage The shader language
|
||||
*/
|
||||
public void setShaderFile(String vertexShader, String fragmentShader, String shaderLanguage){
|
||||
public void setShaderFile(String vertexShader, String fragmentShader, String vertLanguage, String fragLanguage){
|
||||
this.vertName = vertexShader;
|
||||
this.fragName = fragmentShader;
|
||||
this.shaderLang = shaderLanguage;
|
||||
this.vertLanguage = vertLanguage;
|
||||
this.fragLanguage = fragLanguage;
|
||||
|
||||
Caps langCap = Caps.valueOf(shaderLanguage);
|
||||
requiredCaps.add(langCap);
|
||||
Caps vertCap = Caps.valueOf(vertLanguage);
|
||||
requiredCaps.add(vertCap);
|
||||
Caps fragCap = Caps.valueOf(fragLanguage);
|
||||
requiredCaps.add(fragCap);
|
||||
|
||||
usesShaders = true;
|
||||
}
|
||||
@ -247,9 +257,9 @@ public class TechniqueDef implements Savable {
|
||||
* @see #addShaderParamDefine(java.lang.String, java.lang.String)
|
||||
*/
|
||||
public String getShaderParamDefine(String paramName){
|
||||
if (defineParams == null)
|
||||
if (defineParams == null) {
|
||||
return null;
|
||||
|
||||
}
|
||||
return defineParams.get(paramName);
|
||||
}
|
||||
|
||||
@ -266,9 +276,9 @@ public class TechniqueDef implements Savable {
|
||||
* @param defineName The name of the define parameter, e.g. USE_LIGHTING
|
||||
*/
|
||||
public void addShaderParamDefine(String paramName, String defineName){
|
||||
if (defineParams == null)
|
||||
if (defineParams == null) {
|
||||
defineParams = new HashMap<String, String>();
|
||||
|
||||
}
|
||||
defineParams.put(paramName, defineName);
|
||||
}
|
||||
|
||||
@ -297,9 +307,9 @@ public class TechniqueDef implements Savable {
|
||||
* @param value The value of the define
|
||||
*/
|
||||
public void addShaderPresetDefine(String defineName, VarType type, Object value){
|
||||
if (presetDefines == null)
|
||||
if (presetDefines == null) {
|
||||
presetDefines = new DefineList();
|
||||
|
||||
}
|
||||
presetDefines.set(defineName, type, value);
|
||||
}
|
||||
|
||||
@ -325,14 +335,27 @@ public class TechniqueDef implements Savable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the shader language of the shaders used in this technique.
|
||||
*
|
||||
* @return the shader language of the shaders used in this technique.
|
||||
* @deprecated Use {@link #getVertexShaderLanguage() } instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public String getShaderLanguage() {
|
||||
return shaderLang;
|
||||
return vertLanguage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the language of the fragment shader used in this technique.
|
||||
*/
|
||||
public String getFragmentShaderLanguage() {
|
||||
return fragLanguage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the language of the vertex shader used in this technique.
|
||||
*/
|
||||
public String getVertexShaderLanguage() {
|
||||
return vertLanguage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new world parameter by the given name.
|
||||
*
|
||||
@ -368,12 +391,14 @@ public class TechniqueDef implements Savable {
|
||||
oc.write(name, "name", null);
|
||||
oc.write(vertName, "vertName", null);
|
||||
oc.write(fragName, "fragName", null);
|
||||
oc.write(shaderLang, "shaderLang", null);
|
||||
oc.write(vertLanguage, "vertLanguage", null);
|
||||
oc.write(vertLanguage, "fragLanguage", null);
|
||||
oc.write(presetDefines, "presetDefines", null);
|
||||
oc.write(lightMode, "lightMode", LightMode.Disable);
|
||||
oc.write(shadowMode, "shadowMode", ShadowMode.Disable);
|
||||
oc.write(renderState, "renderState", null);
|
||||
oc.write(usesShaders, "usesShaders", false);
|
||||
|
||||
// TODO: Finish this when Map<String, String> export is available
|
||||
// oc.write(defineParams, "defineParams", null);
|
||||
// TODO: Finish this when List<Enum> export is available
|
||||
@ -385,12 +410,21 @@ public class TechniqueDef implements Savable {
|
||||
name = ic.readString("name", null);
|
||||
vertName = ic.readString("vertName", null);
|
||||
fragName = ic.readString("fragName", null);
|
||||
shaderLang = ic.readString("shaderLang", null);
|
||||
presetDefines = (DefineList) ic.readSavable("presetDefines", null);
|
||||
lightMode = ic.readEnum("lightMode", LightMode.class, LightMode.Disable);
|
||||
shadowMode = ic.readEnum("shadowMode", ShadowMode.class, ShadowMode.Disable);
|
||||
renderState = (RenderState) ic.readSavable("renderState", null);
|
||||
usesShaders = ic.readBoolean("usesShaders", false);
|
||||
|
||||
if (ic.getSavableVersion(TechniqueDef.class) == 0) {
|
||||
// Old version
|
||||
vertLanguage = ic.readString("shaderLang", null);
|
||||
fragLanguage = vertLanguage;
|
||||
} else {
|
||||
// New version
|
||||
vertLanguage = ic.readString("vertLanguage", null);
|
||||
fragLanguage = ic.readString("fragLanguage", null);;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -32,37 +32,33 @@
|
||||
|
||||
package com.jme3.shader;
|
||||
|
||||
import com.jme3.export.*;
|
||||
import com.jme3.renderer.Renderer;
|
||||
import com.jme3.scene.VertexBuffer;
|
||||
import com.jme3.util.IntMap;
|
||||
import com.jme3.util.IntMap.Entry;
|
||||
import com.jme3.util.ListMap;
|
||||
import com.jme3.util.NativeObject;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
|
||||
public final class Shader extends NativeObject implements Savable {
|
||||
public final class Shader extends NativeObject {
|
||||
|
||||
/**
|
||||
*
|
||||
* @deprecated shader language now specified per shader source. See
|
||||
* {@link ShaderSource#setLanguage(String)
|
||||
*/
|
||||
@Deprecated
|
||||
private String language;
|
||||
|
||||
|
||||
/**
|
||||
* True if the shader is fully compiled & linked.
|
||||
* (e.g no GL error will be invoked if used).
|
||||
* A list of all shader sources currently attached.
|
||||
*/
|
||||
private boolean usable = false;
|
||||
|
||||
/**
|
||||
* A list of all shaders currently attached.
|
||||
*/
|
||||
private ArrayList<ShaderSource> shaderList;
|
||||
private ArrayList<ShaderSource> shaderSourceList;
|
||||
|
||||
/**
|
||||
* Maps uniform name to the uniform variable.
|
||||
*/
|
||||
// private HashMap<String, Uniform> uniforms;
|
||||
private ListMap<String, Uniform> uniforms;
|
||||
|
||||
/**
|
||||
@ -94,50 +90,32 @@ public final class Shader extends NativeObject implements Savable {
|
||||
* Shader source describes a shader object in OpenGL. Each shader source
|
||||
* is assigned a certain pipeline which it controls (described by it's type).
|
||||
*/
|
||||
public static class ShaderSource extends NativeObject implements Savable {
|
||||
public static class ShaderSource extends NativeObject {
|
||||
|
||||
ShaderType shaderType;
|
||||
|
||||
boolean usable = false;
|
||||
String name = null;
|
||||
String source = null;
|
||||
String defines = null;
|
||||
ShaderType sourceType;
|
||||
String language;
|
||||
String name;
|
||||
String source;
|
||||
String defines;
|
||||
|
||||
public ShaderSource(ShaderType type){
|
||||
super(ShaderSource.class);
|
||||
this.shaderType = type;
|
||||
if (type == null)
|
||||
this.sourceType = type;
|
||||
if (type == null) {
|
||||
throw new NullPointerException("The shader type must be specified");
|
||||
}
|
||||
}
|
||||
|
||||
protected ShaderSource(ShaderSource ss){
|
||||
super(ShaderSource.class, ss.id);
|
||||
this.shaderType = ss.shaderType;
|
||||
usable = false;
|
||||
name = ss.name;
|
||||
// forget source & defines
|
||||
// No data needs to be copied.
|
||||
// (This is a destructable clone)
|
||||
}
|
||||
|
||||
public ShaderSource(){
|
||||
super(ShaderSource.class);
|
||||
}
|
||||
|
||||
public void write(JmeExporter ex) throws IOException{
|
||||
OutputCapsule oc = ex.getCapsule(this);
|
||||
oc.write(shaderType, "shaderType", null);
|
||||
oc.write(name, "name", null);
|
||||
oc.write(source, "source", null);
|
||||
oc.write(defines, "defines", null);
|
||||
}
|
||||
|
||||
public void read(JmeImporter im) throws IOException{
|
||||
InputCapsule ic = im.getCapsule(this);
|
||||
shaderType = ic.readEnum("shaderType", ShaderType.class, null);
|
||||
name = ic.readString("name", null);
|
||||
source = ic.readString("source", null);
|
||||
defines = ic.readString("defines", null);
|
||||
}
|
||||
|
||||
public void setName(String name){
|
||||
this.name = name;
|
||||
}
|
||||
@ -147,21 +125,33 @@ public final class Shader extends NativeObject implements Savable {
|
||||
}
|
||||
|
||||
public ShaderType getType() {
|
||||
return shaderType;
|
||||
return sourceType;
|
||||
}
|
||||
|
||||
public String getLanguage() {
|
||||
return language;
|
||||
}
|
||||
|
||||
public void setLanguage(String language) {
|
||||
if (language == null) {
|
||||
throw new NullPointerException("Shader language cannot be null");
|
||||
}
|
||||
this.language = language;
|
||||
setUpdateNeeded();
|
||||
}
|
||||
|
||||
public void setSource(String source){
|
||||
if (source == null)
|
||||
if (source == null) {
|
||||
throw new NullPointerException("Shader source cannot be null");
|
||||
|
||||
}
|
||||
this.source = source;
|
||||
setUpdateNeeded();
|
||||
}
|
||||
|
||||
public void setDefines(String defines){
|
||||
if (defines == null)
|
||||
if (defines == null) {
|
||||
throw new NullPointerException("Shader defines cannot be null");
|
||||
|
||||
}
|
||||
this.defines = defines;
|
||||
setUpdateNeeded();
|
||||
}
|
||||
@ -174,14 +164,6 @@ public final class Shader extends NativeObject implements Savable {
|
||||
return defines;
|
||||
}
|
||||
|
||||
public boolean isUsable(){
|
||||
return usable;
|
||||
}
|
||||
|
||||
public void setUsable(boolean usable){
|
||||
this.usable = usable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(){
|
||||
String nameTxt = "";
|
||||
@ -192,12 +174,11 @@ public final class Shader extends NativeObject implements Savable {
|
||||
|
||||
|
||||
return getClass().getSimpleName() + "["+nameTxt+"type="
|
||||
+ shaderType.name()+"]";
|
||||
+ sourceType.name()+", language=" + language + "]";
|
||||
}
|
||||
|
||||
public void resetObject(){
|
||||
id = -1;
|
||||
usable = false;
|
||||
setUpdateNeeded();
|
||||
}
|
||||
|
||||
@ -211,110 +192,103 @@ public final class Shader extends NativeObject implements Savable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an empty shader.
|
||||
* @deprecated Shader sources are now associated with the shader
|
||||
* language.
|
||||
*/
|
||||
@Deprecated
|
||||
public Shader(String language){
|
||||
super(Shader.class);
|
||||
this.language = language;
|
||||
shaderList = new ArrayList<ShaderSource>();
|
||||
// uniforms = new HashMap<String, Uniform>();
|
||||
uniforms = new ListMap<String, Uniform>();
|
||||
attribs = new IntMap<Attribute>();
|
||||
initialize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Do not use this constructor. Serialization purposes only.
|
||||
* Initializes the shader for use, must be called after the
|
||||
* constructor without arguments is used.
|
||||
*/
|
||||
public void initialize() {
|
||||
shaderSourceList = new ArrayList<ShaderSource>();
|
||||
uniforms = new ListMap<String, Uniform>();
|
||||
attribs = new IntMap<Attribute>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new shader, {@link #initialize() } must be called
|
||||
* after this constructor for the shader to be usable.
|
||||
*/
|
||||
public Shader(){
|
||||
super(Shader.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Do not use this constructor. Used for destructable clones only.
|
||||
*/
|
||||
protected Shader(Shader s){
|
||||
super(Shader.class, s.id);
|
||||
shaderList = new ArrayList<ShaderSource>();
|
||||
//uniforms = new ListMap<String, Uniform>();
|
||||
//attribs = new IntMap<Attribute>();
|
||||
|
||||
// NOTE: Because ShaderSources are registered separately with
|
||||
// the GLObjectManager
|
||||
for (ShaderSource source : s.shaderList){
|
||||
shaderList.add( (ShaderSource)source.createDestructableClone() );
|
||||
// Shader sources cannot be shared, therefore they must
|
||||
// be destroyed together with the parent shader.
|
||||
shaderSourceList = new ArrayList<ShaderSource>();
|
||||
for (ShaderSource source : s.shaderSourceList){
|
||||
shaderSourceList.add( (ShaderSource)source.createDestructableClone() );
|
||||
}
|
||||
}
|
||||
|
||||
public void write(JmeExporter ex) throws IOException{
|
||||
OutputCapsule oc = ex.getCapsule(this);
|
||||
oc.write(language, "language", null);
|
||||
oc.writeSavableArrayList(shaderList, "shaderList", null);
|
||||
oc.writeIntSavableMap(attribs, "attribs", null);
|
||||
oc.writeStringSavableMap(uniforms, "uniforms", null);
|
||||
}
|
||||
|
||||
public void read(JmeImporter im) throws IOException{
|
||||
InputCapsule ic = im.getCapsule(this);
|
||||
language = ic.readString("language", null);
|
||||
shaderList = ic.readSavableArrayList("shaderList", null);
|
||||
attribs = (IntMap<Attribute>) ic.readIntSavableMap("attribs", null);
|
||||
|
||||
HashMap<String, Uniform> uniMap = (HashMap<String, Uniform>) ic.readStringSavableMap("uniforms", null);
|
||||
uniforms = new ListMap<String, Uniform>(uniMap);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a deep clone of the shader, where the sources are available
|
||||
* but have not been compiled yet. Does not copy the uniforms or attribs.
|
||||
* @return
|
||||
* @deprecated Use the method that takes a language argument instead.
|
||||
* {@link #addSource(com.jme3.shader.Shader.ShaderType, java.lang.String, java.lang.String, java.lang.String, java.lang.String) }
|
||||
*/
|
||||
// public Shader createDeepClone(String defines){
|
||||
// Shader newShader = new Shader(language);
|
||||
// for (ShaderSource source : shaderList){
|
||||
// if (!source.getDefines().equals(defines)){
|
||||
// // need to clone the shadersource so
|
||||
// // the correct defines can be placed
|
||||
// ShaderSource newSource = new ShaderSource(source.getType());
|
||||
// newSource.setSource(source.getSource());
|
||||
// newSource.setDefines(defines);
|
||||
// newShader.addSource(newSource);
|
||||
// }else{
|
||||
// // no need to clone source, also saves
|
||||
// // having to compile the shadersource
|
||||
// newShader.addSource(source);
|
||||
// }
|
||||
// }
|
||||
// return newShader;
|
||||
// }
|
||||
|
||||
/**
|
||||
* Adds source code to a certain pipeline.
|
||||
*
|
||||
* @param type The pipeline to control
|
||||
* @param source The shader source code (in GLSL).
|
||||
*/
|
||||
public void addSource(ShaderType type, String name, String source, String defines){
|
||||
ShaderSource shader = new ShaderSource(type);
|
||||
shader.setSource(source);
|
||||
shader.setName(name);
|
||||
if (defines != null)
|
||||
shader.setDefines(defines);
|
||||
|
||||
shaderList.add(shader);
|
||||
setUpdateNeeded();
|
||||
@Deprecated
|
||||
public void addSource(ShaderType type, String name, String source, String defines) {
|
||||
addSource(type, name, source, defines, this.language);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @deprecated Use the method that takes a language argument instead.
|
||||
* {@link #addSource(com.jme3.shader.Shader.ShaderType, java.lang.String, java.lang.String, java.lang.String, java.lang.String) }
|
||||
*/
|
||||
@Deprecated
|
||||
public void addSource(ShaderType type, String source, String defines){
|
||||
addSource(type, null, source, defines);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use the method that takes a language argument instead.
|
||||
* {@link #addSource(com.jme3.shader.Shader.ShaderType, java.lang.String, java.lang.String, java.lang.String, java.lang.String) }
|
||||
*/
|
||||
@Deprecated
|
||||
public void addSource(ShaderType type, String source){
|
||||
addSource(type, source, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an existing shader source to this shader.
|
||||
* @param source
|
||||
* @deprecated Shader sources may not be shared.
|
||||
* {@link #addSource(com.jme3.shader.Shader.ShaderType, java.lang.String, java.lang.String, java.lang.String, java.lang.String) }
|
||||
*/
|
||||
@Deprecated
|
||||
private void addSource(ShaderSource source){
|
||||
shaderList.add(source);
|
||||
shaderSourceList.add(source);
|
||||
setUpdateNeeded();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds source code to a certain pipeline.
|
||||
*
|
||||
* @param type The pipeline to control
|
||||
* @param source The shader source code (in GLSL).
|
||||
* @param defines Preprocessor defines (placed at the beginning of the shader)
|
||||
* @param language The shader source language, currently accepted is GLSL###
|
||||
* where ### is the version, e.g. GLSL100 = GLSL 1.0, GLSL330 = GLSL 3.3, etc.
|
||||
*/
|
||||
public void addSource(ShaderType type, String name, String source, String defines, String language){
|
||||
ShaderSource shaderSource = new ShaderSource(type);
|
||||
shaderSource.setSource(source);
|
||||
shaderSource.setName(name);
|
||||
shaderSource.setLanguage(language);
|
||||
if (defines != null) {
|
||||
shaderSource.setDefines(defines);
|
||||
}
|
||||
shaderSourceList.add(shaderSource);
|
||||
setUpdateNeeded();
|
||||
}
|
||||
|
||||
@ -343,69 +317,73 @@ public final class Shader extends NativeObject implements Savable {
|
||||
return attrib;
|
||||
}
|
||||
|
||||
// public Collection<Uniform> getUniforms(){
|
||||
// return uniforms.values();
|
||||
// }
|
||||
|
||||
public ListMap<String, Uniform> getUniformMap(){
|
||||
return uniforms;
|
||||
}
|
||||
|
||||
// public Collection<Attribute> getAttributes() {
|
||||
// return attribs.
|
||||
// }
|
||||
|
||||
public Collection<ShaderSource> getSources(){
|
||||
return shaderList;
|
||||
return shaderSourceList;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Shaders no longer have a language variable,
|
||||
* use {@link ShaderSource#getLanguage() } instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public String getLanguage(){
|
||||
return language;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(){
|
||||
return getClass().getSimpleName() + "[language="+language
|
||||
+ ", numSources="+shaderList.size()
|
||||
+ ", numUniforms="+uniforms.size()
|
||||
+ ", shaderSources="+getSources()+"]";
|
||||
public String toString() {
|
||||
return getClass().getSimpleName() +
|
||||
"[numSources=" + shaderSourceList.size() +
|
||||
", numUniforms=" + uniforms.size() +
|
||||
", shaderSources=" + getSources() + "]";
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears all sources. Assuming that they have already been detached and
|
||||
* removed on the GL side.
|
||||
* @deprecated This method is not needed since deleting
|
||||
* a shader causes the sources to delete as well, thus its not required
|
||||
* for them to be GC'd to be removed from GL.
|
||||
*/
|
||||
@Deprecated
|
||||
public void resetSources(){
|
||||
shaderList.clear();
|
||||
shaderSourceList.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this program and all it's shaders have been compiled,
|
||||
* linked and validated successfuly.
|
||||
* @deprecated Unusable shaders cause the renderer to crash,
|
||||
* therefore this field no longer serves any purpose.
|
||||
*/
|
||||
@Deprecated
|
||||
public boolean isUsable(){
|
||||
return usable;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets if the program can be used. Should only be called by the Renderer.
|
||||
* @param usable
|
||||
* @deprecated Unusable shaders cause the renderer to crash,
|
||||
* therefore this field no longer serves any purpose.
|
||||
*/
|
||||
@Deprecated
|
||||
public void setUsable(boolean usable){
|
||||
this.usable = usable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Usually called when the shader itself changes or during any
|
||||
* time when the var locations need to be refreshed.
|
||||
* time when the variable locations need to be refreshed.
|
||||
*/
|
||||
public void resetLocations(){
|
||||
// NOTE: Shader sources will be reset seperately from the shader itself.
|
||||
for (Uniform uniform : uniforms.values()){
|
||||
uniform.reset(); // fixes issue with re-initialization
|
||||
public void resetLocations() {
|
||||
if (uniforms != null) {
|
||||
// NOTE: Shader sources will be reset seperately from the shader itself.
|
||||
for (Uniform uniform : uniforms.values()) {
|
||||
uniform.reset(); // fixes issue with re-initialization
|
||||
}
|
||||
}
|
||||
for (Entry<Attribute> entry : attribs){
|
||||
entry.getValue().location = -2;
|
||||
if (attribs != null) {
|
||||
for (Entry<Attribute> entry : attribs) {
|
||||
entry.getValue().location = ShaderVariable.LOC_UNKNOWN;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -422,12 +400,9 @@ public final class Shader extends NativeObject implements Savable {
|
||||
@Override
|
||||
public void resetObject() {
|
||||
this.id = -1;
|
||||
this.usable = false;
|
||||
|
||||
for (ShaderSource source : shaderList){
|
||||
for (ShaderSource source : shaderSourceList){
|
||||
source.resetObject();
|
||||
}
|
||||
|
||||
setUpdateNeeded();
|
||||
}
|
||||
|
||||
|
@ -43,16 +43,18 @@ public class ShaderKey extends AssetKey<Shader> {
|
||||
|
||||
protected String fragName;
|
||||
protected DefineList defines;
|
||||
protected String language;
|
||||
protected String vertLanguage;
|
||||
protected String fragLanguage;
|
||||
|
||||
public ShaderKey(){
|
||||
}
|
||||
|
||||
public ShaderKey(String vertName, String fragName, DefineList defines, String lang){
|
||||
public ShaderKey(String vertName, String fragName, DefineList defines, String vertLanguage, String fragLanguage){
|
||||
super(vertName);
|
||||
this.fragName = fragName;
|
||||
this.defines = defines;
|
||||
this.language = lang;
|
||||
this.vertLanguage = vertLanguage;
|
||||
this.fragLanguage = fragLanguage;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -71,7 +73,6 @@ public class ShaderKey extends AssetKey<Shader> {
|
||||
|
||||
final ShaderKey other = (ShaderKey) obj;
|
||||
if (name.equals(other.name) && fragName.equals(other.fragName)){
|
||||
// return true;
|
||||
if (defines != null && other.defines != null)
|
||||
return defines.getCompiled().equals(other.defines.getCompiled());
|
||||
else if (defines != null || other.defines != null)
|
||||
@ -103,8 +104,20 @@ public class ShaderKey extends AssetKey<Shader> {
|
||||
return fragName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #getVertexShaderLanguage() } instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public String getLanguage() {
|
||||
return language;
|
||||
return vertLanguage;
|
||||
}
|
||||
|
||||
public String getVertexShaderLanguage() {
|
||||
return vertLanguage;
|
||||
}
|
||||
|
||||
public String getFragmentShaderLanguage() {
|
||||
return fragLanguage;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -112,7 +125,7 @@ public class ShaderKey extends AssetKey<Shader> {
|
||||
super.write(ex);
|
||||
OutputCapsule oc = ex.getCapsule(this);
|
||||
oc.write(fragName, "fragment_name", null);
|
||||
oc.write(language, "language", null);
|
||||
oc.write(vertLanguage, "language", null);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -120,7 +133,7 @@ public class ShaderKey extends AssetKey<Shader> {
|
||||
super.read(im);
|
||||
InputCapsule ic = im.getCapsule(this);
|
||||
fragName = ic.readString("fragment_name", null);
|
||||
language = ic.readString("language", null);
|
||||
vertLanguage = ic.readString("language", null);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -32,15 +32,15 @@
|
||||
|
||||
package com.jme3.shader;
|
||||
|
||||
import com.jme3.export.*;
|
||||
import java.io.IOException;
|
||||
|
||||
public class ShaderVariable implements Savable {
|
||||
public class ShaderVariable {
|
||||
|
||||
public static final int LOC_UNKNOWN = -2,
|
||||
LOC_NOT_DEFINED = -1;
|
||||
|
||||
// if -2, location not known
|
||||
// if -1, not defined in shader
|
||||
// if >= 0, uniform defined and available.
|
||||
protected int location = -2;
|
||||
protected int location = LOC_UNKNOWN;
|
||||
|
||||
/**
|
||||
* Name of the uniform as was declared in the shader.
|
||||
@ -54,15 +54,6 @@ public class ShaderVariable implements Savable {
|
||||
*/
|
||||
protected boolean updateNeeded = true;;
|
||||
|
||||
public void write(JmeExporter ex) throws IOException{
|
||||
OutputCapsule oc = ex.getCapsule(this);
|
||||
oc.write(name, "name", null);
|
||||
}
|
||||
|
||||
public void read(JmeImporter im) throws IOException{
|
||||
InputCapsule ic = im.getCapsule(this);
|
||||
name = ic.readString("name", null);
|
||||
}
|
||||
|
||||
public void setLocation(int location){
|
||||
this.location = location;
|
||||
|
@ -53,7 +53,10 @@ import com.jme3.texture.FrameBuffer.RenderBuffer;
|
||||
import com.jme3.texture.Image;
|
||||
import com.jme3.texture.Texture;
|
||||
import com.jme3.texture.Texture.WrapAxis;
|
||||
import com.jme3.util.*;
|
||||
import com.jme3.util.BufferUtils;
|
||||
import com.jme3.util.ListMap;
|
||||
import com.jme3.util.NativeObjectManager;
|
||||
import com.jme3.util.SafeArrayList;
|
||||
import java.nio.*;
|
||||
import java.util.EnumSet;
|
||||
import java.util.List;
|
||||
@ -61,7 +64,6 @@ import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import jme3tools.converters.MipMapGenerator;
|
||||
import jme3tools.shader.ShaderDebug;
|
||||
import org.lwjgl.opengl.*;
|
||||
import static org.lwjgl.opengl.ARBTextureMultisample.*;
|
||||
import static org.lwjgl.opengl.EXTFramebufferBlit.*;
|
||||
import static org.lwjgl.opengl.EXTFramebufferMultisample.*;
|
||||
@ -72,6 +74,7 @@ import static org.lwjgl.opengl.GL13.*;
|
||||
import static org.lwjgl.opengl.GL14.*;
|
||||
import static org.lwjgl.opengl.GL15.*;
|
||||
import static org.lwjgl.opengl.GL20.*;
|
||||
import org.lwjgl.opengl.*;
|
||||
//import static org.lwjgl.opengl.ARBDrawInstanced.*;
|
||||
|
||||
public class LwjglRenderer implements Renderer {
|
||||
@ -889,7 +892,6 @@ public class LwjglRenderer implements Renderer {
|
||||
|
||||
protected void updateShaderUniforms(Shader shader) {
|
||||
ListMap<String, Uniform> uniforms = shader.getUniformMap();
|
||||
// for (Uniform uniform : shader.getUniforms()){
|
||||
for (int i = 0; i < uniforms.size(); i++) {
|
||||
Uniform uniform = uniforms.getValue(i);
|
||||
if (uniform.isUpdateNeeded()) {
|
||||
@ -900,7 +902,6 @@ public class LwjglRenderer implements Renderer {
|
||||
|
||||
protected void resetUniformLocations(Shader shader) {
|
||||
ListMap<String, Uniform> uniforms = shader.getUniformMap();
|
||||
// for (Uniform uniform : shader.getUniforms()){
|
||||
for (int i = 0; i < uniforms.size(); i++) {
|
||||
Uniform uniform = uniforms.getValue(i);
|
||||
uniform.reset(); // e.g check location again
|
||||
@ -927,10 +928,10 @@ public class LwjglRenderer implements Renderer {
|
||||
}
|
||||
}
|
||||
|
||||
public void updateShaderSourceData(ShaderSource source, String language) {
|
||||
public void updateShaderSourceData(ShaderSource source) {
|
||||
int id = source.getId();
|
||||
if (id == -1) {
|
||||
// create id
|
||||
// Create id
|
||||
id = glCreateShader(convertShaderType(source.getType()));
|
||||
if (id <= 0) {
|
||||
throw new RendererException("Invalid ID received when trying to create shader.");
|
||||
@ -941,9 +942,9 @@ public class LwjglRenderer implements Renderer {
|
||||
throw new RendererException("Cannot recompile shader source");
|
||||
}
|
||||
|
||||
// upload shader source
|
||||
// merge the defines and source code
|
||||
|
||||
// Upload shader source.
|
||||
// Merge the defines and source code.
|
||||
String language = source.getLanguage();
|
||||
stringBuf.setLength(0);
|
||||
if (language.startsWith("GLSL")) {
|
||||
int version = Integer.parseInt(language.substring(4));
|
||||
@ -999,6 +1000,7 @@ public class LwjglRenderer implements Renderer {
|
||||
} else {
|
||||
logger.log(Level.FINE, "{0} compile success", source.getName());
|
||||
}
|
||||
source.clearUpdateNeeded();
|
||||
} else {
|
||||
logger.log(Level.WARNING, "Bad compile of:\n{0}",
|
||||
new Object[]{ShaderDebug.formatShaderSource(source.getDefines(), source.getSource(), stringBuf.toString())});
|
||||
@ -1008,21 +1010,6 @@ public class LwjglRenderer implements Renderer {
|
||||
throw new RendererException("compile error in:" + source + " error: <not provided>");
|
||||
}
|
||||
}
|
||||
|
||||
source.clearUpdateNeeded();
|
||||
// only usable if compiled
|
||||
source.setUsable(compiledOK);
|
||||
if (!compiledOK) {
|
||||
// make sure to dispose id cause all program's
|
||||
// shaders will be cleared later.
|
||||
glDeleteShader(id);
|
||||
} else {
|
||||
// register for cleanup since the ID is usable
|
||||
// NOTE: From now on cleanup is handled
|
||||
// by the parent shader object so no need
|
||||
// to register.
|
||||
//objManager.registerForCleanup(source);
|
||||
}
|
||||
}
|
||||
|
||||
public void updateShaderData(Shader shader) {
|
||||
@ -1041,15 +1028,7 @@ public class LwjglRenderer implements Renderer {
|
||||
|
||||
for (ShaderSource source : shader.getSources()) {
|
||||
if (source.isUpdateNeeded()) {
|
||||
updateShaderSourceData(source, shader.getLanguage());
|
||||
// shader has been compiled here
|
||||
}
|
||||
|
||||
if (!source.isUsable()) {
|
||||
// it's useless.. just forget about everything..
|
||||
shader.setUsable(false);
|
||||
shader.clearUpdateNeeded();
|
||||
return;
|
||||
updateShaderSourceData(source);
|
||||
}
|
||||
glAttachShader(id, source.getId());
|
||||
}
|
||||
@ -1057,13 +1036,16 @@ public class LwjglRenderer implements Renderer {
|
||||
if (caps.contains(Caps.OpenGL30)) {
|
||||
// Check if GLSL version is 1.5 for shader
|
||||
GL30.glBindFragDataLocation(id, 0, "outFragColor");
|
||||
// For MRT
|
||||
for(int i = 0 ; i < maxMRTFBOAttachs ; i++) {
|
||||
GL30.glBindFragDataLocation(id, i, "outFragData[" + i + "]");
|
||||
}
|
||||
}
|
||||
|
||||
// link shaders to program
|
||||
// Link shaders to program
|
||||
glLinkProgram(id);
|
||||
|
||||
// Check link status
|
||||
glGetProgram(id, GL_LINK_STATUS, intBuf1);
|
||||
boolean linkOK = intBuf1.get(0) == GL_TRUE;
|
||||
String infoLog = null;
|
||||
@ -1089,6 +1071,15 @@ public class LwjglRenderer implements Renderer {
|
||||
} else {
|
||||
logger.fine("shader link success");
|
||||
}
|
||||
shader.clearUpdateNeeded();
|
||||
if (needRegister) {
|
||||
// Register shader for clean up if it was created in this method.
|
||||
objManager.registerForCleanup(shader);
|
||||
statistics.onNewShader();
|
||||
} else {
|
||||
// OpenGL spec: uniform locations may change after re-link
|
||||
resetUniformLocations(shader);
|
||||
}
|
||||
} else {
|
||||
if (infoLog != null) {
|
||||
throw new RendererException("Shader link failure, shader:" + shader + " info:" + infoLog);
|
||||
@ -1096,46 +1087,19 @@ public class LwjglRenderer implements Renderer {
|
||||
throw new RendererException("Shader link failure, shader:" + shader + " info: <not provided>");
|
||||
}
|
||||
}
|
||||
|
||||
shader.clearUpdateNeeded();
|
||||
if (!linkOK) {
|
||||
// failure.. forget about everything
|
||||
shader.resetSources();
|
||||
shader.setUsable(false);
|
||||
deleteShader(shader);
|
||||
} else {
|
||||
shader.setUsable(true);
|
||||
if (needRegister) {
|
||||
objManager.registerForCleanup(shader);
|
||||
statistics.onNewShader();
|
||||
} else {
|
||||
// OpenGL spec: uniform locations may change after re-link
|
||||
resetUniformLocations(shader);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setShader(Shader shader) {
|
||||
if (shader == null) {
|
||||
throw new IllegalArgumentException("shader cannot be null");
|
||||
// if (context.boundShaderProgram > 0) {
|
||||
// glUseProgram(0);
|
||||
// statistics.onShaderUse(null, true);
|
||||
// context.boundShaderProgram = 0;
|
||||
// boundShader = null;
|
||||
// }
|
||||
throw new IllegalArgumentException("Shader cannot be null");
|
||||
} else {
|
||||
if (shader.isUpdateNeeded()) {
|
||||
updateShaderData(shader);
|
||||
}
|
||||
|
||||
|
||||
// NOTE: might want to check if any of the
|
||||
// sources need an update?
|
||||
|
||||
if (!shader.isUsable()) {
|
||||
return;
|
||||
}
|
||||
|
||||
assert shader.getId() > 0;
|
||||
|
||||
updateShaderUniforms(shader);
|
||||
@ -1148,7 +1112,6 @@ public class LwjglRenderer implements Renderer {
|
||||
logger.warning("Shader source is not uploaded to GPU, cannot delete.");
|
||||
return;
|
||||
}
|
||||
source.setUsable(false);
|
||||
source.clearUpdateNeeded();
|
||||
glDeleteShader(source.getId());
|
||||
source.resetObject();
|
||||
@ -1167,12 +1130,9 @@ public class LwjglRenderer implements Renderer {
|
||||
}
|
||||
}
|
||||
|
||||
// kill all references so sources can be collected
|
||||
// if needed.
|
||||
shader.resetSources();
|
||||
glDeleteProgram(shader.getId());
|
||||
|
||||
statistics.onDeleteShader();
|
||||
shader.resetObject();
|
||||
}
|
||||
|
||||
/*********************************************************************\
|
||||
@ -2116,46 +2076,6 @@ public class LwjglRenderer implements Renderer {
|
||||
throw new UnsupportedOperationException("Unknown buffer format.");
|
||||
}
|
||||
}
|
||||
// }else{
|
||||
// if (created || vb.hasDataSizeChanged()){
|
||||
// glBufferData(target, vb.getData().capacity() * vb.getFormat().getComponentSize(), usage);
|
||||
// }
|
||||
//
|
||||
// ByteBuffer buf = glMapBuffer(target,
|
||||
// GL_WRITE_ONLY,
|
||||
// vb.getMappedData());
|
||||
//
|
||||
// if (buf != vb.getMappedData()){
|
||||
// buf = buf.order(ByteOrder.nativeOrder());
|
||||
// vb.setMappedData(buf);
|
||||
// }
|
||||
//
|
||||
// buf.clear();
|
||||
//
|
||||
// switch (vb.getFormat()){
|
||||
// case Byte:
|
||||
// case UnsignedByte:
|
||||
// buf.put( (ByteBuffer) vb.getData() );
|
||||
// break;
|
||||
// case Short:
|
||||
// case UnsignedShort:
|
||||
// buf.asShortBuffer().put( (ShortBuffer) vb.getData() );
|
||||
// break;
|
||||
// case Int:
|
||||
// case UnsignedInt:
|
||||
// buf.asIntBuffer().put( (IntBuffer) vb.getData() );
|
||||
// break;
|
||||
// case Float:
|
||||
// buf.asFloatBuffer().put( (FloatBuffer) vb.getData() );
|
||||
// break;
|
||||
// case Double:
|
||||
// break;
|
||||
// default:
|
||||
// throw new RuntimeException("Unknown buffer format.");
|
||||
// }
|
||||
//
|
||||
// glUnmapBuffer(target);
|
||||
// }
|
||||
|
||||
vb.clearUpdateNeeded();
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user