* 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) {
|
protected void updateUniform(Shader shader, Uniform uniform) {
|
||||||
int shaderId = shader.getId();
|
int shaderId = shader.getId();
|
||||||
|
|
||||||
@ -698,7 +710,6 @@ public class OGLESShaderRenderer implements Renderer {
|
|||||||
|
|
||||||
protected void updateShaderUniforms(Shader shader) {
|
protected void updateShaderUniforms(Shader shader) {
|
||||||
ListMap<String, Uniform> uniforms = shader.getUniformMap();
|
ListMap<String, Uniform> uniforms = shader.getUniformMap();
|
||||||
// for (Uniform uniform : shader.getUniforms()){
|
|
||||||
for (int i = 0; i < uniforms.size(); i++) {
|
for (int i = 0; i < uniforms.size(); i++) {
|
||||||
Uniform uniform = uniforms.getValue(i);
|
Uniform uniform = uniforms.getValue(i);
|
||||||
if (uniform.isUpdateNeeded()) {
|
if (uniform.isUpdateNeeded()) {
|
||||||
@ -709,7 +720,6 @@ public class OGLESShaderRenderer implements Renderer {
|
|||||||
|
|
||||||
protected void resetUniformLocations(Shader shader) {
|
protected void resetUniformLocations(Shader shader) {
|
||||||
ListMap<String, Uniform> uniforms = shader.getUniformMap();
|
ListMap<String, Uniform> uniforms = shader.getUniformMap();
|
||||||
// for (Uniform uniform : shader.getUniforms()){
|
|
||||||
for (int i = 0; i < uniforms.size(); i++) {
|
for (int i = 0; i < uniforms.size(); i++) {
|
||||||
Uniform uniform = uniforms.getValue(i);
|
Uniform uniform = uniforms.getValue(i);
|
||||||
uniform.reset(); // e.g check location again
|
uniform.reset(); // e.g check location again
|
||||||
@ -736,10 +746,10 @@ public class OGLESShaderRenderer implements Renderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateShaderSourceData(ShaderSource source, String language) {
|
public void updateShaderSourceData(ShaderSource source) {
|
||||||
int id = source.getId();
|
int id = source.getId();
|
||||||
if (id == -1) {
|
if (id == -1) {
|
||||||
// create id
|
// Create id
|
||||||
id = GLES20.glCreateShader(convertShaderType(source.getType()));
|
id = GLES20.glCreateShader(convertShaderType(source.getType()));
|
||||||
if (id <= 0) {
|
if (id <= 0) {
|
||||||
throw new RendererException("Invalid ID received when trying to create shader.");
|
throw new RendererException("Invalid ID received when trying to create shader.");
|
||||||
@ -747,16 +757,17 @@ public class OGLESShaderRenderer implements Renderer {
|
|||||||
source.setId(id);
|
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
|
// upload shader source
|
||||||
// merge the defines and source code
|
// 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[] definesCodeData = source.getDefines().getBytes();
|
||||||
byte[] sourceCodeData = source.getSource().getBytes();
|
byte[] sourceCodeData = source.getSource().getBytes();
|
||||||
ByteBuffer codeBuf = BufferUtils.createByteBuffer(versionData.length
|
ByteBuffer codeBuf = BufferUtils.createByteBuffer(definesCodeData.length
|
||||||
+ definesCodeData.length
|
|
||||||
+ sourceCodeData.length);
|
+ sourceCodeData.length);
|
||||||
codeBuf.put(versionData);
|
|
||||||
codeBuf.put(definesCodeData);
|
codeBuf.put(definesCodeData);
|
||||||
codeBuf.put(sourceCodeData);
|
codeBuf.put(sourceCodeData);
|
||||||
codeBuf.flip();
|
codeBuf.flip();
|
||||||
@ -791,10 +802,11 @@ public class OGLESShaderRenderer implements Renderer {
|
|||||||
|
|
||||||
if (compiledOK) {
|
if (compiledOK) {
|
||||||
if (infoLog != null) {
|
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 {
|
} else {
|
||||||
logger.log(Level.FINE, "compile success: " + source.getName());
|
logger.log(Level.FINE, "compile success: {0}", source.getName());
|
||||||
}
|
}
|
||||||
|
source.clearUpdateNeeded();
|
||||||
} else {
|
} else {
|
||||||
logger.log(Level.WARNING, "Bad compile of:\n{0}",
|
logger.log(Level.WARNING, "Bad compile of:\n{0}",
|
||||||
new Object[]{ShaderDebug.formatShaderSource(source.getDefines(), source.getSource(),stringBuf.toString())});
|
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>");
|
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) {
|
public void updateShaderData(Shader shader) {
|
||||||
@ -835,15 +835,7 @@ public class OGLESShaderRenderer implements Renderer {
|
|||||||
|
|
||||||
for (ShaderSource source : shader.getSources()) {
|
for (ShaderSource source : shader.getSources()) {
|
||||||
if (source.isUpdateNeeded()) {
|
if (source.isUpdateNeeded()) {
|
||||||
updateShaderSourceData(source, shader.getLanguage());
|
updateShaderSourceData(source);
|
||||||
// shader has been compiled here
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!source.isUsable()) {
|
|
||||||
// it's useless.. just forget about everything..
|
|
||||||
shader.setUsable(false);
|
|
||||||
shader.clearUpdateNeeded();
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
GLES20.glAttachShader(id, source.getId());
|
GLES20.glAttachShader(id, source.getId());
|
||||||
}
|
}
|
||||||
@ -871,6 +863,15 @@ public class OGLESShaderRenderer implements Renderer {
|
|||||||
} else {
|
} else {
|
||||||
logger.fine("shader link success");
|
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 {
|
} else {
|
||||||
if (infoLog != null) {
|
if (infoLog != null) {
|
||||||
throw new RendererException("Shader link failure, shader:" + shader + " info:" + infoLog);
|
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>");
|
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) {
|
public void setShader(Shader shader) {
|
||||||
if (shader == null) {
|
if (shader == null) {
|
||||||
if (context.boundShaderProgram > 0) {
|
throw new IllegalArgumentException("Shader cannot be null");
|
||||||
GLES20.glUseProgram(0);
|
|
||||||
|
|
||||||
statistics.onShaderUse(null, true);
|
|
||||||
context.boundShaderProgram = 0;
|
|
||||||
boundShader = null;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if (shader.isUpdateNeeded()) {
|
if (shader.isUpdateNeeded()) {
|
||||||
updateShaderData(shader);
|
updateShaderData(shader);
|
||||||
@ -913,37 +891,11 @@ public class OGLESShaderRenderer implements Renderer {
|
|||||||
|
|
||||||
// NOTE: might want to check if any of the
|
// NOTE: might want to check if any of the
|
||||||
// sources need an update?
|
// sources need an update?
|
||||||
if (!shader.isUsable()) {
|
|
||||||
logger.warning("shader is not usable.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
assert shader.getId() > 0;
|
assert shader.getId() > 0;
|
||||||
|
|
||||||
updateShaderUniforms(shader);
|
updateShaderUniforms(shader);
|
||||||
if (context.boundShaderProgram != shader.getId()) {
|
bindProgram(shader);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -952,9 +904,8 @@ public class OGLESShaderRenderer implements Renderer {
|
|||||||
logger.warning("Shader source is not uploaded to GPU, cannot delete.");
|
logger.warning("Shader source is not uploaded to GPU, cannot delete.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
source.setUsable(false);
|
|
||||||
source.clearUpdateNeeded();
|
|
||||||
|
|
||||||
|
source.clearUpdateNeeded();
|
||||||
GLES20.glDeleteShader(source.getId());
|
GLES20.glDeleteShader(source.getId());
|
||||||
source.resetObject();
|
source.resetObject();
|
||||||
}
|
}
|
||||||
@ -964,20 +915,17 @@ public class OGLESShaderRenderer implements Renderer {
|
|||||||
logger.warning("Shader is not uploaded to GPU, cannot delete.");
|
logger.warning("Shader is not uploaded to GPU, cannot delete.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (ShaderSource source : shader.getSources()) {
|
for (ShaderSource source : shader.getSources()) {
|
||||||
if (source.getId() != -1) {
|
if (source.getId() != -1) {
|
||||||
GLES20.glDetachShader(shader.getId(), source.getId());
|
GLES20.glDetachShader(shader.getId(), source.getId());
|
||||||
// the next part is done by the GLObjectManager automatically
|
deleteShaderSource(source);
|
||||||
// glDeleteShader(source.getId());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// kill all references so sources can be collected
|
|
||||||
// if needed.
|
|
||||||
shader.resetSources();
|
|
||||||
|
|
||||||
GLES20.glDeleteProgram(shader.getId());
|
GLES20.glDeleteProgram(shader.getId());
|
||||||
|
|
||||||
statistics.onDeleteShader();
|
statistics.onDeleteShader();
|
||||||
|
shader.resetObject();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************************************************************\
|
/*********************************************************************\
|
||||||
|
@ -8,7 +8,7 @@ MaterialDef Bloom Final {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Technique {
|
Technique {
|
||||||
VertexShader GLSL100: Common/MatDefs/Post/Post15.vert
|
VertexShader GLSL150: Common/MatDefs/Post/Post15.vert
|
||||||
FragmentShader GLSL150: Common/MatDefs/Post/bloomFinal15.frag
|
FragmentShader GLSL150: Common/MatDefs/Post/bloomFinal15.frag
|
||||||
|
|
||||||
WorldParameters {
|
WorldParameters {
|
||||||
@ -28,9 +28,4 @@ MaterialDef Bloom Final {
|
|||||||
WorldViewProjectionMatrix
|
WorldViewProjectionMatrix
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Technique FixedFunc {
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -336,11 +336,6 @@ public class DesktopAssetManager implements AssetManager {
|
|||||||
return loadAsset(new AssetKey(name));
|
return loadAsset(new AssetKey(name));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Loads a texture.
|
|
||||||
*
|
|
||||||
* @return the texture
|
|
||||||
*/
|
|
||||||
public Texture loadTexture(TextureKey key){
|
public Texture loadTexture(TextureKey key){
|
||||||
return (Texture) loadAsset(key);
|
return (Texture) loadAsset(key);
|
||||||
}
|
}
|
||||||
@ -365,18 +360,16 @@ public class DesktopAssetManager implements AssetManager {
|
|||||||
return loadAudio(new AudioKey(name, false));
|
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){
|
public BitmapFont loadFont(String name){
|
||||||
return (BitmapFont) loadAsset(new AssetKey(name));
|
return (BitmapFont) loadAsset(new AssetKey(name));
|
||||||
}
|
}
|
||||||
|
|
||||||
public InputStream loadGLSLLibrary(AssetKey key){
|
public Spatial loadModel(ModelKey key){
|
||||||
return (InputStream) loadAsset(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
|
// cache abuse in method
|
||||||
// that doesn't use loaders/locators
|
// that doesn't use loaders/locators
|
||||||
AssetCache cache = handler.getCache(SimpleAssetCache.class);
|
AssetCache cache = handler.getCache(SimpleAssetCache.class);
|
||||||
Shader s = (Shader) cache.getFromCache(key);
|
Shader shader = (Shader) cache.getFromCache(key);
|
||||||
if (s == null){
|
if (shader == null){
|
||||||
String vertName = key.getVertName();
|
String vertName = key.getVertName();
|
||||||
String fragName = key.getFragName();
|
String fragName = key.getFragName();
|
||||||
|
|
||||||
String vertSource = (String) loadAsset(new AssetKey(vertName));
|
String vertSource = (String) loadAsset(new AssetKey(vertName));
|
||||||
String fragSource = (String) loadAsset(new AssetKey(fragName));
|
String fragSource = (String) loadAsset(new AssetKey(fragName));
|
||||||
|
|
||||||
s = new Shader(key.getLanguage());
|
shader = new Shader();
|
||||||
s.addSource(Shader.ShaderType.Vertex, vertName, vertSource, key.getDefines().getCompiled());
|
shader.initialize();
|
||||||
s.addSource(Shader.ShaderType.Fragment, fragName, fragSource, key.getDefines().getCompiled());
|
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;
|
return shader;
|
||||||
}
|
|
||||||
|
|
||||||
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));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,9 +32,7 @@
|
|||||||
package com.jme3.material;
|
package com.jme3.material;
|
||||||
|
|
||||||
import com.jme3.asset.AssetManager;
|
import com.jme3.asset.AssetManager;
|
||||||
import com.jme3.export.*;
|
|
||||||
import com.jme3.shader.*;
|
import com.jme3.shader.*;
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -43,7 +41,7 @@ import java.util.logging.Logger;
|
|||||||
/**
|
/**
|
||||||
* Represents a technique instance.
|
* 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 static final Logger logger = Logger.getLogger(Technique.class.getName());
|
||||||
private TechniqueDef def;
|
private TechniqueDef def;
|
||||||
@ -133,6 +131,10 @@ public class Technique implements Savable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void updateUniformParam(String paramName, VarType type, Object value) {
|
void updateUniformParam(String paramName, VarType type, Object value) {
|
||||||
|
if (paramName == null) {
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
}
|
||||||
|
|
||||||
Uniform u = shader.getUniform(paramName);
|
Uniform u = shader.getUniform(paramName);
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case TextureBuffer:
|
case TextureBuffer:
|
||||||
@ -208,7 +210,8 @@ public class Technique implements Savable {
|
|||||||
ShaderKey key = new ShaderKey(def.getVertexShaderName(),
|
ShaderKey key = new ShaderKey(def.getVertexShaderName(),
|
||||||
def.getFragmentShaderName(),
|
def.getFragmentShaderName(),
|
||||||
allDefines,
|
allDefines,
|
||||||
def.getShaderLanguage());
|
def.getVertexShaderLanguage(),
|
||||||
|
def.getFragmentShaderLanguage());
|
||||||
shader = manager.loadShader(key);
|
shader = manager.loadShader(key);
|
||||||
|
|
||||||
// register the world bound uniforms
|
// register the world bound uniforms
|
||||||
@ -225,6 +228,7 @@ public class Technique implements Savable {
|
|||||||
needReload = false;
|
needReload = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
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(def, "def", null);
|
oc.write(def, "def", null);
|
||||||
@ -240,4 +244,5 @@ public class Technique implements Savable {
|
|||||||
defines = (DefineList) ic.readSavable("defines", null);
|
defines = (DefineList) ic.readSavable("defines", null);
|
||||||
shader = (Shader) ic.readSavable("shader", null);
|
shader = (Shader) ic.readSavable("shader", null);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
@ -51,6 +51,11 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
public class TechniqueDef implements Savable {
|
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.
|
* Describes light rendering mode.
|
||||||
*/
|
*/
|
||||||
@ -101,7 +106,9 @@ public class TechniqueDef implements Savable {
|
|||||||
|
|
||||||
private String vertName;
|
private String vertName;
|
||||||
private String fragName;
|
private String fragName;
|
||||||
private String shaderLang;
|
private String vertLanguage;
|
||||||
|
private String fragLanguage;
|
||||||
|
|
||||||
private DefineList presetDefines;
|
private DefineList presetDefines;
|
||||||
private boolean usesShaders;
|
private boolean usesShaders;
|
||||||
|
|
||||||
@ -227,13 +234,16 @@ public class TechniqueDef implements Savable {
|
|||||||
* @param fragmentShader The name of the fragment shader
|
* @param fragmentShader The name of the fragment shader
|
||||||
* @param shaderLanguage The shader language
|
* @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.vertName = vertexShader;
|
||||||
this.fragName = fragmentShader;
|
this.fragName = fragmentShader;
|
||||||
this.shaderLang = shaderLanguage;
|
this.vertLanguage = vertLanguage;
|
||||||
|
this.fragLanguage = fragLanguage;
|
||||||
|
|
||||||
Caps langCap = Caps.valueOf(shaderLanguage);
|
Caps vertCap = Caps.valueOf(vertLanguage);
|
||||||
requiredCaps.add(langCap);
|
requiredCaps.add(vertCap);
|
||||||
|
Caps fragCap = Caps.valueOf(fragLanguage);
|
||||||
|
requiredCaps.add(fragCap);
|
||||||
|
|
||||||
usesShaders = true;
|
usesShaders = true;
|
||||||
}
|
}
|
||||||
@ -247,9 +257,9 @@ public class TechniqueDef implements Savable {
|
|||||||
* @see #addShaderParamDefine(java.lang.String, java.lang.String)
|
* @see #addShaderParamDefine(java.lang.String, java.lang.String)
|
||||||
*/
|
*/
|
||||||
public String getShaderParamDefine(String paramName){
|
public String getShaderParamDefine(String paramName){
|
||||||
if (defineParams == null)
|
if (defineParams == null) {
|
||||||
return null;
|
return null;
|
||||||
|
}
|
||||||
return defineParams.get(paramName);
|
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
|
* @param defineName The name of the define parameter, e.g. USE_LIGHTING
|
||||||
*/
|
*/
|
||||||
public void addShaderParamDefine(String paramName, String defineName){
|
public void addShaderParamDefine(String paramName, String defineName){
|
||||||
if (defineParams == null)
|
if (defineParams == null) {
|
||||||
defineParams = new HashMap<String, String>();
|
defineParams = new HashMap<String, String>();
|
||||||
|
}
|
||||||
defineParams.put(paramName, defineName);
|
defineParams.put(paramName, defineName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -297,9 +307,9 @@ public class TechniqueDef implements Savable {
|
|||||||
* @param value The value of the define
|
* @param value The value of the define
|
||||||
*/
|
*/
|
||||||
public void addShaderPresetDefine(String defineName, VarType type, Object value){
|
public void addShaderPresetDefine(String defineName, VarType type, Object value){
|
||||||
if (presetDefines == null)
|
if (presetDefines == null) {
|
||||||
presetDefines = new DefineList();
|
presetDefines = new DefineList();
|
||||||
|
}
|
||||||
presetDefines.set(defineName, type, value);
|
presetDefines.set(defineName, type, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -325,12 +335,25 @@ public class TechniqueDef implements Savable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the shader language of the shaders used in this technique.
|
* @deprecated Use {@link #getVertexShaderLanguage() } instead.
|
||||||
*
|
|
||||||
* @return the shader language of the shaders used in this technique.
|
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public String getShaderLanguage() {
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -368,12 +391,14 @@ public class TechniqueDef implements Savable {
|
|||||||
oc.write(name, "name", null);
|
oc.write(name, "name", null);
|
||||||
oc.write(vertName, "vertName", null);
|
oc.write(vertName, "vertName", null);
|
||||||
oc.write(fragName, "fragName", 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(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);
|
||||||
oc.write(renderState, "renderState", null);
|
oc.write(renderState, "renderState", null);
|
||||||
oc.write(usesShaders, "usesShaders", false);
|
oc.write(usesShaders, "usesShaders", false);
|
||||||
|
|
||||||
// TODO: Finish this when Map<String, String> export is available
|
// TODO: Finish this when Map<String, String> export is available
|
||||||
// oc.write(defineParams, "defineParams", null);
|
// oc.write(defineParams, "defineParams", null);
|
||||||
// TODO: Finish this when List<Enum> export is available
|
// TODO: Finish this when List<Enum> export is available
|
||||||
@ -385,12 +410,21 @@ public class TechniqueDef implements Savable {
|
|||||||
name = ic.readString("name", null);
|
name = ic.readString("name", null);
|
||||||
vertName = ic.readString("vertName", null);
|
vertName = ic.readString("vertName", null);
|
||||||
fragName = ic.readString("fragName", null);
|
fragName = ic.readString("fragName", null);
|
||||||
shaderLang = ic.readString("shaderLang", 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);
|
||||||
renderState = (RenderState) ic.readSavable("renderState", null);
|
renderState = (RenderState) ic.readSavable("renderState", null);
|
||||||
usesShaders = ic.readBoolean("usesShaders", false);
|
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;
|
package com.jme3.shader;
|
||||||
|
|
||||||
import com.jme3.export.*;
|
|
||||||
import com.jme3.renderer.Renderer;
|
import com.jme3.renderer.Renderer;
|
||||||
import com.jme3.scene.VertexBuffer;
|
import com.jme3.scene.VertexBuffer;
|
||||||
import com.jme3.util.IntMap;
|
import com.jme3.util.IntMap;
|
||||||
import com.jme3.util.IntMap.Entry;
|
import com.jme3.util.IntMap.Entry;
|
||||||
import com.jme3.util.ListMap;
|
import com.jme3.util.ListMap;
|
||||||
import com.jme3.util.NativeObject;
|
import com.jme3.util.NativeObject;
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
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;
|
private String language;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* True if the shader is fully compiled & linked.
|
* A list of all shader sources currently attached.
|
||||||
* (e.g no GL error will be invoked if used).
|
|
||||||
*/
|
*/
|
||||||
private boolean usable = false;
|
private ArrayList<ShaderSource> shaderSourceList;
|
||||||
|
|
||||||
/**
|
|
||||||
* A list of all shaders currently attached.
|
|
||||||
*/
|
|
||||||
private ArrayList<ShaderSource> shaderList;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Maps uniform name to the uniform variable.
|
* Maps uniform name to the uniform variable.
|
||||||
*/
|
*/
|
||||||
// private HashMap<String, Uniform> uniforms;
|
|
||||||
private ListMap<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
|
* Shader source describes a shader object in OpenGL. Each shader source
|
||||||
* is assigned a certain pipeline which it controls (described by it's type).
|
* 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;
|
ShaderType sourceType;
|
||||||
|
String language;
|
||||||
boolean usable = false;
|
String name;
|
||||||
String name = null;
|
String source;
|
||||||
String source = null;
|
String defines;
|
||||||
String defines = null;
|
|
||||||
|
|
||||||
public ShaderSource(ShaderType type){
|
public ShaderSource(ShaderType type){
|
||||||
super(ShaderSource.class);
|
super(ShaderSource.class);
|
||||||
this.shaderType = type;
|
this.sourceType = type;
|
||||||
if (type == null)
|
if (type == null) {
|
||||||
throw new NullPointerException("The shader type must be specified");
|
throw new NullPointerException("The shader type must be specified");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected ShaderSource(ShaderSource ss){
|
protected ShaderSource(ShaderSource ss){
|
||||||
super(ShaderSource.class, ss.id);
|
super(ShaderSource.class, ss.id);
|
||||||
this.shaderType = ss.shaderType;
|
// No data needs to be copied.
|
||||||
usable = false;
|
// (This is a destructable clone)
|
||||||
name = ss.name;
|
|
||||||
// forget source & defines
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ShaderSource(){
|
public ShaderSource(){
|
||||||
super(ShaderSource.class);
|
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){
|
public void setName(String name){
|
||||||
this.name = name;
|
this.name = name;
|
||||||
}
|
}
|
||||||
@ -147,21 +125,33 @@ public final class Shader extends NativeObject implements Savable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public ShaderType getType() {
|
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){
|
public void setSource(String source){
|
||||||
if (source == null)
|
if (source == null) {
|
||||||
throw new NullPointerException("Shader source cannot be null");
|
throw new NullPointerException("Shader source cannot be null");
|
||||||
|
}
|
||||||
this.source = source;
|
this.source = source;
|
||||||
setUpdateNeeded();
|
setUpdateNeeded();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDefines(String defines){
|
public void setDefines(String defines){
|
||||||
if (defines == null)
|
if (defines == null) {
|
||||||
throw new NullPointerException("Shader defines cannot be null");
|
throw new NullPointerException("Shader defines cannot be null");
|
||||||
|
}
|
||||||
this.defines = defines;
|
this.defines = defines;
|
||||||
setUpdateNeeded();
|
setUpdateNeeded();
|
||||||
}
|
}
|
||||||
@ -174,14 +164,6 @@ public final class Shader extends NativeObject implements Savable {
|
|||||||
return defines;
|
return defines;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isUsable(){
|
|
||||||
return usable;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setUsable(boolean usable){
|
|
||||||
this.usable = usable;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString(){
|
public String toString(){
|
||||||
String nameTxt = "";
|
String nameTxt = "";
|
||||||
@ -192,12 +174,11 @@ public final class Shader extends NativeObject implements Savable {
|
|||||||
|
|
||||||
|
|
||||||
return getClass().getSimpleName() + "["+nameTxt+"type="
|
return getClass().getSimpleName() + "["+nameTxt+"type="
|
||||||
+ shaderType.name()+"]";
|
+ sourceType.name()+", language=" + language + "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
public void resetObject(){
|
public void resetObject(){
|
||||||
id = -1;
|
id = -1;
|
||||||
usable = false;
|
|
||||||
setUpdateNeeded();
|
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){
|
public Shader(String language){
|
||||||
super(Shader.class);
|
super(Shader.class);
|
||||||
this.language = language;
|
this.language = language;
|
||||||
shaderList = new ArrayList<ShaderSource>();
|
initialize();
|
||||||
// uniforms = new HashMap<String, Uniform>();
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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>();
|
uniforms = new ListMap<String, Uniform>();
|
||||||
attribs = new IntMap<Attribute>();
|
attribs = new IntMap<Attribute>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Do not use this constructor. Serialization purposes only.
|
* Creates a new shader, {@link #initialize() } must be called
|
||||||
|
* after this constructor for the shader to be usable.
|
||||||
*/
|
*/
|
||||||
public Shader(){
|
public Shader(){
|
||||||
super(Shader.class);
|
super(Shader.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Do not use this constructor. Used for destructable clones only.
|
||||||
|
*/
|
||||||
protected Shader(Shader s){
|
protected Shader(Shader s){
|
||||||
super(Shader.class, s.id);
|
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
|
// Shader sources cannot be shared, therefore they must
|
||||||
// the GLObjectManager
|
// be destroyed together with the parent shader.
|
||||||
for (ShaderSource source : s.shaderList){
|
shaderSourceList = new ArrayList<ShaderSource>();
|
||||||
shaderList.add( (ShaderSource)source.createDestructableClone() );
|
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
|
* @deprecated Use the method that takes a language argument instead.
|
||||||
* but have not been compiled yet. Does not copy the uniforms or attribs.
|
* {@link #addSource(com.jme3.shader.Shader.ShaderType, java.lang.String, java.lang.String, java.lang.String, java.lang.String) }
|
||||||
* @return
|
|
||||||
*/
|
*/
|
||||||
// public Shader createDeepClone(String defines){
|
@Deprecated
|
||||||
// Shader newShader = new Shader(language);
|
public void addSource(ShaderType type, String name, String source, String defines) {
|
||||||
// for (ShaderSource source : shaderList){
|
addSource(type, name, source, defines, this.language);
|
||||||
// if (!source.getDefines().equals(defines)){
|
}
|
||||||
// // need to clone the shadersource so
|
|
||||||
// // the correct defines can be placed
|
/**
|
||||||
// ShaderSource newSource = new ShaderSource(source.getType());
|
* @deprecated Use the method that takes a language argument instead.
|
||||||
// newSource.setSource(source.getSource());
|
* {@link #addSource(com.jme3.shader.Shader.ShaderType, java.lang.String, java.lang.String, java.lang.String, java.lang.String) }
|
||||||
// newSource.setDefines(defines);
|
*/
|
||||||
// newShader.addSource(newSource);
|
@Deprecated
|
||||||
// }else{
|
public void addSource(ShaderType type, String source, String defines){
|
||||||
// // no need to clone source, also saves
|
addSource(type, null, source, defines);
|
||||||
// // having to compile the shadersource
|
}
|
||||||
// newShader.addSource(source);
|
|
||||||
// }
|
/**
|
||||||
// }
|
* @deprecated Use the method that takes a language argument instead.
|
||||||
// return newShader;
|
* {@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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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){
|
||||||
|
shaderSourceList.add(source);
|
||||||
|
setUpdateNeeded();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds source code to a certain pipeline.
|
* Adds source code to a certain pipeline.
|
||||||
*
|
*
|
||||||
* @param type The pipeline to control
|
* @param type The pipeline to control
|
||||||
* @param source The shader source code (in GLSL).
|
* @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){
|
public void addSource(ShaderType type, String name, String source, String defines, String language){
|
||||||
ShaderSource shader = new ShaderSource(type);
|
ShaderSource shaderSource = new ShaderSource(type);
|
||||||
shader.setSource(source);
|
shaderSource.setSource(source);
|
||||||
shader.setName(name);
|
shaderSource.setName(name);
|
||||||
if (defines != null)
|
shaderSource.setLanguage(language);
|
||||||
shader.setDefines(defines);
|
if (defines != null) {
|
||||||
|
shaderSource.setDefines(defines);
|
||||||
shaderList.add(shader);
|
|
||||||
setUpdateNeeded();
|
|
||||||
}
|
}
|
||||||
|
shaderSourceList.add(shaderSource);
|
||||||
public void addSource(ShaderType type, String source, String defines){
|
|
||||||
addSource(type, null, source, defines);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addSource(ShaderType type, String source){
|
|
||||||
addSource(type, source, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds an existing shader source to this shader.
|
|
||||||
* @param source
|
|
||||||
*/
|
|
||||||
private void addSource(ShaderSource source){
|
|
||||||
shaderList.add(source);
|
|
||||||
setUpdateNeeded();
|
setUpdateNeeded();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -343,69 +317,73 @@ public final class Shader extends NativeObject implements Savable {
|
|||||||
return attrib;
|
return attrib;
|
||||||
}
|
}
|
||||||
|
|
||||||
// public Collection<Uniform> getUniforms(){
|
|
||||||
// return uniforms.values();
|
|
||||||
// }
|
|
||||||
|
|
||||||
public ListMap<String, Uniform> getUniformMap(){
|
public ListMap<String, Uniform> getUniformMap(){
|
||||||
return uniforms;
|
return uniforms;
|
||||||
}
|
}
|
||||||
|
|
||||||
// public Collection<Attribute> getAttributes() {
|
|
||||||
// return attribs.
|
|
||||||
// }
|
|
||||||
|
|
||||||
public Collection<ShaderSource> getSources(){
|
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(){
|
public String getLanguage(){
|
||||||
return language;
|
return language;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return getClass().getSimpleName() + "[language="+language
|
return getClass().getSimpleName() +
|
||||||
+ ", numSources="+shaderList.size()
|
"[numSources=" + shaderSourceList.size() +
|
||||||
+ ", numUniforms="+uniforms.size()
|
", numUniforms=" + uniforms.size() +
|
||||||
+ ", shaderSources="+getSources()+"]";
|
", shaderSources=" + getSources() + "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clears all sources. Assuming that they have already been detached and
|
* @deprecated This method is not needed since deleting
|
||||||
* removed on the GL side.
|
* 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(){
|
public void resetSources(){
|
||||||
shaderList.clear();
|
shaderSourceList.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if this program and all it's shaders have been compiled,
|
* @deprecated Unusable shaders cause the renderer to crash,
|
||||||
* linked and validated successfuly.
|
* therefore this field no longer serves any purpose.
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public boolean isUsable(){
|
public boolean isUsable(){
|
||||||
return usable;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets if the program can be used. Should only be called by the Renderer.
|
* @deprecated Unusable shaders cause the renderer to crash,
|
||||||
* @param usable
|
* therefore this field no longer serves any purpose.
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public void setUsable(boolean usable){
|
public void setUsable(boolean usable){
|
||||||
this.usable = usable;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Usually called when the shader itself changes or during any
|
* 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() {
|
public void resetLocations() {
|
||||||
|
if (uniforms != null) {
|
||||||
// NOTE: Shader sources will be reset seperately from the shader itself.
|
// NOTE: Shader sources will be reset seperately from the shader itself.
|
||||||
for (Uniform uniform : uniforms.values()) {
|
for (Uniform uniform : uniforms.values()) {
|
||||||
uniform.reset(); // fixes issue with re-initialization
|
uniform.reset(); // fixes issue with re-initialization
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (attribs != null) {
|
||||||
for (Entry<Attribute> entry : attribs) {
|
for (Entry<Attribute> entry : attribs) {
|
||||||
entry.getValue().location = -2;
|
entry.getValue().location = ShaderVariable.LOC_UNKNOWN;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -422,12 +400,9 @@ public final class Shader extends NativeObject implements Savable {
|
|||||||
@Override
|
@Override
|
||||||
public void resetObject() {
|
public void resetObject() {
|
||||||
this.id = -1;
|
this.id = -1;
|
||||||
this.usable = false;
|
for (ShaderSource source : shaderSourceList){
|
||||||
|
|
||||||
for (ShaderSource source : shaderList){
|
|
||||||
source.resetObject();
|
source.resetObject();
|
||||||
}
|
}
|
||||||
|
|
||||||
setUpdateNeeded();
|
setUpdateNeeded();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,16 +43,18 @@ public class ShaderKey extends AssetKey<Shader> {
|
|||||||
|
|
||||||
protected String fragName;
|
protected String fragName;
|
||||||
protected DefineList defines;
|
protected DefineList defines;
|
||||||
protected String language;
|
protected String vertLanguage;
|
||||||
|
protected String fragLanguage;
|
||||||
|
|
||||||
public ShaderKey(){
|
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);
|
super(vertName);
|
||||||
this.fragName = fragName;
|
this.fragName = fragName;
|
||||||
this.defines = defines;
|
this.defines = defines;
|
||||||
this.language = lang;
|
this.vertLanguage = vertLanguage;
|
||||||
|
this.fragLanguage = fragLanguage;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -71,7 +73,6 @@ public class ShaderKey extends AssetKey<Shader> {
|
|||||||
|
|
||||||
final ShaderKey other = (ShaderKey) obj;
|
final ShaderKey other = (ShaderKey) obj;
|
||||||
if (name.equals(other.name) && fragName.equals(other.fragName)){
|
if (name.equals(other.name) && fragName.equals(other.fragName)){
|
||||||
// return true;
|
|
||||||
if (defines != null && other.defines != null)
|
if (defines != null && other.defines != null)
|
||||||
return defines.getCompiled().equals(other.defines.getCompiled());
|
return defines.getCompiled().equals(other.defines.getCompiled());
|
||||||
else if (defines != null || other.defines != null)
|
else if (defines != null || other.defines != null)
|
||||||
@ -103,8 +104,20 @@ public class ShaderKey extends AssetKey<Shader> {
|
|||||||
return fragName;
|
return fragName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated Use {@link #getVertexShaderLanguage() } instead.
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
public String getLanguage() {
|
public String getLanguage() {
|
||||||
return language;
|
return vertLanguage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getVertexShaderLanguage() {
|
||||||
|
return vertLanguage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFragmentShaderLanguage() {
|
||||||
|
return fragLanguage;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -112,7 +125,7 @@ public class ShaderKey extends AssetKey<Shader> {
|
|||||||
super.write(ex);
|
super.write(ex);
|
||||||
OutputCapsule oc = ex.getCapsule(this);
|
OutputCapsule oc = ex.getCapsule(this);
|
||||||
oc.write(fragName, "fragment_name", null);
|
oc.write(fragName, "fragment_name", null);
|
||||||
oc.write(language, "language", null);
|
oc.write(vertLanguage, "language", null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -120,7 +133,7 @@ public class ShaderKey extends AssetKey<Shader> {
|
|||||||
super.read(im);
|
super.read(im);
|
||||||
InputCapsule ic = im.getCapsule(this);
|
InputCapsule ic = im.getCapsule(this);
|
||||||
fragName = ic.readString("fragment_name", null);
|
fragName = ic.readString("fragment_name", null);
|
||||||
language = ic.readString("language", null);
|
vertLanguage = ic.readString("language", null);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -32,15 +32,15 @@
|
|||||||
|
|
||||||
package com.jme3.shader;
|
package com.jme3.shader;
|
||||||
|
|
||||||
import com.jme3.export.*;
|
public class ShaderVariable {
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
public class ShaderVariable implements Savable {
|
public static final int LOC_UNKNOWN = -2,
|
||||||
|
LOC_NOT_DEFINED = -1;
|
||||||
|
|
||||||
// if -2, location not known
|
// if -2, location not known
|
||||||
// if -1, not defined in shader
|
// if -1, not defined in shader
|
||||||
// if >= 0, uniform defined and available.
|
// 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.
|
* Name of the uniform as was declared in the shader.
|
||||||
@ -54,15 +54,6 @@ public class ShaderVariable implements Savable {
|
|||||||
*/
|
*/
|
||||||
protected boolean updateNeeded = true;;
|
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){
|
public void setLocation(int location){
|
||||||
this.location = location;
|
this.location = location;
|
||||||
|
@ -53,7 +53,10 @@ import com.jme3.texture.FrameBuffer.RenderBuffer;
|
|||||||
import com.jme3.texture.Image;
|
import com.jme3.texture.Image;
|
||||||
import com.jme3.texture.Texture;
|
import com.jme3.texture.Texture;
|
||||||
import com.jme3.texture.Texture.WrapAxis;
|
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.nio.*;
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -61,7 +64,6 @@ import java.util.logging.Level;
|
|||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
import jme3tools.converters.MipMapGenerator;
|
import jme3tools.converters.MipMapGenerator;
|
||||||
import jme3tools.shader.ShaderDebug;
|
import jme3tools.shader.ShaderDebug;
|
||||||
import org.lwjgl.opengl.*;
|
|
||||||
import static org.lwjgl.opengl.ARBTextureMultisample.*;
|
import static org.lwjgl.opengl.ARBTextureMultisample.*;
|
||||||
import static org.lwjgl.opengl.EXTFramebufferBlit.*;
|
import static org.lwjgl.opengl.EXTFramebufferBlit.*;
|
||||||
import static org.lwjgl.opengl.EXTFramebufferMultisample.*;
|
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.GL14.*;
|
||||||
import static org.lwjgl.opengl.GL15.*;
|
import static org.lwjgl.opengl.GL15.*;
|
||||||
import static org.lwjgl.opengl.GL20.*;
|
import static org.lwjgl.opengl.GL20.*;
|
||||||
|
import org.lwjgl.opengl.*;
|
||||||
//import static org.lwjgl.opengl.ARBDrawInstanced.*;
|
//import static org.lwjgl.opengl.ARBDrawInstanced.*;
|
||||||
|
|
||||||
public class LwjglRenderer implements Renderer {
|
public class LwjglRenderer implements Renderer {
|
||||||
@ -889,7 +892,6 @@ public class LwjglRenderer implements Renderer {
|
|||||||
|
|
||||||
protected void updateShaderUniforms(Shader shader) {
|
protected void updateShaderUniforms(Shader shader) {
|
||||||
ListMap<String, Uniform> uniforms = shader.getUniformMap();
|
ListMap<String, Uniform> uniforms = shader.getUniformMap();
|
||||||
// for (Uniform uniform : shader.getUniforms()){
|
|
||||||
for (int i = 0; i < uniforms.size(); i++) {
|
for (int i = 0; i < uniforms.size(); i++) {
|
||||||
Uniform uniform = uniforms.getValue(i);
|
Uniform uniform = uniforms.getValue(i);
|
||||||
if (uniform.isUpdateNeeded()) {
|
if (uniform.isUpdateNeeded()) {
|
||||||
@ -900,7 +902,6 @@ public class LwjglRenderer implements Renderer {
|
|||||||
|
|
||||||
protected void resetUniformLocations(Shader shader) {
|
protected void resetUniformLocations(Shader shader) {
|
||||||
ListMap<String, Uniform> uniforms = shader.getUniformMap();
|
ListMap<String, Uniform> uniforms = shader.getUniformMap();
|
||||||
// for (Uniform uniform : shader.getUniforms()){
|
|
||||||
for (int i = 0; i < uniforms.size(); i++) {
|
for (int i = 0; i < uniforms.size(); i++) {
|
||||||
Uniform uniform = uniforms.getValue(i);
|
Uniform uniform = uniforms.getValue(i);
|
||||||
uniform.reset(); // e.g check location again
|
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();
|
int id = source.getId();
|
||||||
if (id == -1) {
|
if (id == -1) {
|
||||||
// create id
|
// Create id
|
||||||
id = glCreateShader(convertShaderType(source.getType()));
|
id = glCreateShader(convertShaderType(source.getType()));
|
||||||
if (id <= 0) {
|
if (id <= 0) {
|
||||||
throw new RendererException("Invalid ID received when trying to create shader.");
|
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");
|
throw new RendererException("Cannot recompile shader source");
|
||||||
}
|
}
|
||||||
|
|
||||||
// upload shader source
|
// Upload shader source.
|
||||||
// merge the defines and source code
|
// Merge the defines and source code.
|
||||||
|
String language = source.getLanguage();
|
||||||
stringBuf.setLength(0);
|
stringBuf.setLength(0);
|
||||||
if (language.startsWith("GLSL")) {
|
if (language.startsWith("GLSL")) {
|
||||||
int version = Integer.parseInt(language.substring(4));
|
int version = Integer.parseInt(language.substring(4));
|
||||||
@ -999,6 +1000,7 @@ public class LwjglRenderer implements Renderer {
|
|||||||
} else {
|
} else {
|
||||||
logger.log(Level.FINE, "{0} compile success", source.getName());
|
logger.log(Level.FINE, "{0} compile success", source.getName());
|
||||||
}
|
}
|
||||||
|
source.clearUpdateNeeded();
|
||||||
} else {
|
} else {
|
||||||
logger.log(Level.WARNING, "Bad compile of:\n{0}",
|
logger.log(Level.WARNING, "Bad compile of:\n{0}",
|
||||||
new Object[]{ShaderDebug.formatShaderSource(source.getDefines(), source.getSource(), stringBuf.toString())});
|
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>");
|
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) {
|
public void updateShaderData(Shader shader) {
|
||||||
@ -1041,15 +1028,7 @@ public class LwjglRenderer implements Renderer {
|
|||||||
|
|
||||||
for (ShaderSource source : shader.getSources()) {
|
for (ShaderSource source : shader.getSources()) {
|
||||||
if (source.isUpdateNeeded()) {
|
if (source.isUpdateNeeded()) {
|
||||||
updateShaderSourceData(source, shader.getLanguage());
|
updateShaderSourceData(source);
|
||||||
// shader has been compiled here
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!source.isUsable()) {
|
|
||||||
// it's useless.. just forget about everything..
|
|
||||||
shader.setUsable(false);
|
|
||||||
shader.clearUpdateNeeded();
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
glAttachShader(id, source.getId());
|
glAttachShader(id, source.getId());
|
||||||
}
|
}
|
||||||
@ -1057,13 +1036,16 @@ public class LwjglRenderer implements Renderer {
|
|||||||
if (caps.contains(Caps.OpenGL30)) {
|
if (caps.contains(Caps.OpenGL30)) {
|
||||||
// Check if GLSL version is 1.5 for shader
|
// Check if GLSL version is 1.5 for shader
|
||||||
GL30.glBindFragDataLocation(id, 0, "outFragColor");
|
GL30.glBindFragDataLocation(id, 0, "outFragColor");
|
||||||
|
// For MRT
|
||||||
for(int i = 0 ; i < maxMRTFBOAttachs ; i++) {
|
for(int i = 0 ; i < maxMRTFBOAttachs ; i++) {
|
||||||
GL30.glBindFragDataLocation(id, i, "outFragData[" + i + "]");
|
GL30.glBindFragDataLocation(id, i, "outFragData[" + i + "]");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// link shaders to program
|
// Link shaders to program
|
||||||
glLinkProgram(id);
|
glLinkProgram(id);
|
||||||
|
|
||||||
|
// Check link status
|
||||||
glGetProgram(id, GL_LINK_STATUS, intBuf1);
|
glGetProgram(id, GL_LINK_STATUS, intBuf1);
|
||||||
boolean linkOK = intBuf1.get(0) == GL_TRUE;
|
boolean linkOK = intBuf1.get(0) == GL_TRUE;
|
||||||
String infoLog = null;
|
String infoLog = null;
|
||||||
@ -1089,6 +1071,15 @@ public class LwjglRenderer implements Renderer {
|
|||||||
} else {
|
} else {
|
||||||
logger.fine("shader link success");
|
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 {
|
} else {
|
||||||
if (infoLog != null) {
|
if (infoLog != null) {
|
||||||
throw new RendererException("Shader link failure, shader:" + shader + " info:" + infoLog);
|
throw new RendererException("Shader link failure, shader:" + shader + " info:" + infoLog);
|
||||||
@ -1096,34 +1087,11 @@ public class LwjglRenderer implements Renderer {
|
|||||||
throw new RendererException("Shader link failure, shader:" + shader + " info: <not provided>");
|
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) {
|
public void setShader(Shader shader) {
|
||||||
if (shader == null) {
|
if (shader == null) {
|
||||||
throw new IllegalArgumentException("shader cannot be null");
|
throw new IllegalArgumentException("Shader cannot be null");
|
||||||
// if (context.boundShaderProgram > 0) {
|
|
||||||
// glUseProgram(0);
|
|
||||||
// statistics.onShaderUse(null, true);
|
|
||||||
// context.boundShaderProgram = 0;
|
|
||||||
// boundShader = null;
|
|
||||||
// }
|
|
||||||
} else {
|
} else {
|
||||||
if (shader.isUpdateNeeded()) {
|
if (shader.isUpdateNeeded()) {
|
||||||
updateShaderData(shader);
|
updateShaderData(shader);
|
||||||
@ -1132,10 +1100,6 @@ public class LwjglRenderer implements Renderer {
|
|||||||
// NOTE: might want to check if any of the
|
// NOTE: might want to check if any of the
|
||||||
// sources need an update?
|
// sources need an update?
|
||||||
|
|
||||||
if (!shader.isUsable()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
assert shader.getId() > 0;
|
assert shader.getId() > 0;
|
||||||
|
|
||||||
updateShaderUniforms(shader);
|
updateShaderUniforms(shader);
|
||||||
@ -1148,7 +1112,6 @@ public class LwjglRenderer implements Renderer {
|
|||||||
logger.warning("Shader source is not uploaded to GPU, cannot delete.");
|
logger.warning("Shader source is not uploaded to GPU, cannot delete.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
source.setUsable(false);
|
|
||||||
source.clearUpdateNeeded();
|
source.clearUpdateNeeded();
|
||||||
glDeleteShader(source.getId());
|
glDeleteShader(source.getId());
|
||||||
source.resetObject();
|
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());
|
glDeleteProgram(shader.getId());
|
||||||
|
|
||||||
statistics.onDeleteShader();
|
statistics.onDeleteShader();
|
||||||
|
shader.resetObject();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************************************************************\
|
/*********************************************************************\
|
||||||
@ -2116,46 +2076,6 @@ public class LwjglRenderer implements Renderer {
|
|||||||
throw new UnsupportedOperationException("Unknown buffer format.");
|
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();
|
vb.clearUpdateNeeded();
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user