* Material world parameters are now set in uniformBindingManager instead of RenderManager
* Fix issue 497 -> TempVars are no longer used to set world parameters so they cannot leak onto other params or lighting values * Uniform is no longer serializable * Cleaned up uniform from old/outdated stuff git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@9555 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
This commit is contained in:
parent
9b9fa57de4
commit
f401c9c1da
@ -44,6 +44,7 @@ import com.jme3.renderer.queue.RenderQueue.ShadowMode;
|
|||||||
import com.jme3.scene.*;
|
import com.jme3.scene.*;
|
||||||
import com.jme3.shader.Uniform;
|
import com.jme3.shader.Uniform;
|
||||||
import com.jme3.shader.UniformBinding;
|
import com.jme3.shader.UniformBinding;
|
||||||
|
import com.jme3.shader.UniformBindingManager;
|
||||||
import com.jme3.shader.VarType;
|
import com.jme3.shader.VarType;
|
||||||
import com.jme3.system.NullRenderer;
|
import com.jme3.system.NullRenderer;
|
||||||
import com.jme3.system.Timer;
|
import com.jme3.system.Timer;
|
||||||
@ -68,7 +69,8 @@ public class RenderManager {
|
|||||||
private static final Logger logger = Logger.getLogger(RenderManager.class.getName());
|
private static final Logger logger = Logger.getLogger(RenderManager.class.getName());
|
||||||
|
|
||||||
private Renderer renderer;
|
private Renderer renderer;
|
||||||
private Timer timer;
|
private UniformBindingManager uniformBindingManager = new UniformBindingManager();
|
||||||
|
|
||||||
private ArrayList<ViewPort> preViewPorts = new ArrayList<ViewPort>();
|
private ArrayList<ViewPort> preViewPorts = new ArrayList<ViewPort>();
|
||||||
private ArrayList<ViewPort> viewPorts = new ArrayList<ViewPort>();
|
private ArrayList<ViewPort> viewPorts = new ArrayList<ViewPort>();
|
||||||
private ArrayList<ViewPort> postViewPorts = new ArrayList<ViewPort>();
|
private ArrayList<ViewPort> postViewPorts = new ArrayList<ViewPort>();
|
||||||
@ -78,17 +80,8 @@ public class RenderManager {
|
|||||||
private RenderState forcedRenderState = null;
|
private RenderState forcedRenderState = null;
|
||||||
private boolean shader;
|
private boolean shader;
|
||||||
private int viewX, viewY, viewWidth, viewHeight;
|
private int viewX, viewY, viewWidth, viewHeight;
|
||||||
private float near, far;
|
|
||||||
private Matrix4f orthoMatrix = new Matrix4f();
|
private Matrix4f orthoMatrix = new Matrix4f();
|
||||||
private Matrix4f viewMatrix = new Matrix4f();
|
|
||||||
private Matrix4f projMatrix = new Matrix4f();
|
|
||||||
private Matrix4f viewProjMatrix = new Matrix4f();
|
|
||||||
private Matrix4f worldMatrix = new Matrix4f();
|
|
||||||
private Vector3f camUp = new Vector3f(),
|
|
||||||
camLeft = new Vector3f(),
|
|
||||||
camDir = new Vector3f(),
|
|
||||||
camLoc = new Vector3f();
|
|
||||||
//temp technique
|
|
||||||
private String tmpTech;
|
private String tmpTech;
|
||||||
private boolean handleTranlucentBucket = true;
|
private boolean handleTranlucentBucket = true;
|
||||||
|
|
||||||
@ -99,7 +92,6 @@ public class RenderManager {
|
|||||||
*/
|
*/
|
||||||
public RenderManager(Renderer renderer) {
|
public RenderManager(Renderer renderer) {
|
||||||
this.renderer = renderer;
|
this.renderer = renderer;
|
||||||
//this.shader = renderer.getCaps().contains(Caps.GLSL100);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -327,146 +319,6 @@ public class RenderManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Internal use only.
|
|
||||||
* Updates the given list of uniforms with {@link UniformBinding uniform bindings}
|
|
||||||
* based on the current world state.
|
|
||||||
*/
|
|
||||||
public void updateUniformBindings(List<Uniform> params) {
|
|
||||||
// assums worldMatrix is properly set.
|
|
||||||
TempVars vars = TempVars.get();
|
|
||||||
|
|
||||||
Matrix4f tempMat4 = vars.tempMat4;
|
|
||||||
Matrix3f tempMat3 = vars.tempMat3;
|
|
||||||
Vector2f tempVec2 = vars.vect2d;
|
|
||||||
Quaternion tempVec4 = vars.quat1;
|
|
||||||
|
|
||||||
for (int i = 0; i < params.size(); i++) {
|
|
||||||
Uniform u = params.get(i);
|
|
||||||
switch (u.getBinding()) {
|
|
||||||
case WorldMatrix:
|
|
||||||
u.setValue(VarType.Matrix4, worldMatrix);
|
|
||||||
break;
|
|
||||||
case ViewMatrix:
|
|
||||||
u.setValue(VarType.Matrix4, viewMatrix);
|
|
||||||
break;
|
|
||||||
case ProjectionMatrix:
|
|
||||||
u.setValue(VarType.Matrix4, projMatrix);
|
|
||||||
break;
|
|
||||||
case ViewProjectionMatrix:
|
|
||||||
u.setValue(VarType.Matrix4, viewProjMatrix);
|
|
||||||
break;
|
|
||||||
case WorldViewMatrix:
|
|
||||||
tempMat4.set(viewMatrix);
|
|
||||||
tempMat4.multLocal(worldMatrix);
|
|
||||||
u.setValue(VarType.Matrix4, tempMat4);
|
|
||||||
break;
|
|
||||||
case NormalMatrix:
|
|
||||||
tempMat4.set(viewMatrix);
|
|
||||||
tempMat4.multLocal(worldMatrix);
|
|
||||||
tempMat4.toRotationMatrix(tempMat3);
|
|
||||||
tempMat3.invertLocal();
|
|
||||||
tempMat3.transposeLocal();
|
|
||||||
u.setValue(VarType.Matrix3, tempMat3);
|
|
||||||
break;
|
|
||||||
case WorldViewProjectionMatrix:
|
|
||||||
tempMat4.set(viewProjMatrix);
|
|
||||||
tempMat4.multLocal(worldMatrix);
|
|
||||||
u.setValue(VarType.Matrix4, tempMat4);
|
|
||||||
break;
|
|
||||||
case WorldMatrixInverse:
|
|
||||||
tempMat4.set(worldMatrix);
|
|
||||||
tempMat4.invertLocal();
|
|
||||||
u.setValue(VarType.Matrix4, tempMat4);
|
|
||||||
break;
|
|
||||||
case WorldMatrixInverseTranspose:
|
|
||||||
worldMatrix.toRotationMatrix(tempMat3);
|
|
||||||
tempMat3.invertLocal().transposeLocal();
|
|
||||||
u.setValue(VarType.Matrix3, tempMat3);
|
|
||||||
break;
|
|
||||||
case ViewMatrixInverse:
|
|
||||||
tempMat4.set(viewMatrix);
|
|
||||||
tempMat4.invertLocal();
|
|
||||||
u.setValue(VarType.Matrix4, tempMat4);
|
|
||||||
break;
|
|
||||||
case ProjectionMatrixInverse:
|
|
||||||
tempMat4.set(projMatrix);
|
|
||||||
tempMat4.invertLocal();
|
|
||||||
u.setValue(VarType.Matrix4, tempMat4);
|
|
||||||
break;
|
|
||||||
case ViewProjectionMatrixInverse:
|
|
||||||
tempMat4.set(viewProjMatrix);
|
|
||||||
tempMat4.invertLocal();
|
|
||||||
u.setValue(VarType.Matrix4, tempMat4);
|
|
||||||
break;
|
|
||||||
case WorldViewMatrixInverse:
|
|
||||||
tempMat4.set(viewMatrix);
|
|
||||||
tempMat4.multLocal(worldMatrix);
|
|
||||||
tempMat4.invertLocal();
|
|
||||||
u.setValue(VarType.Matrix4, tempMat4);
|
|
||||||
break;
|
|
||||||
case NormalMatrixInverse:
|
|
||||||
tempMat4.set(viewMatrix);
|
|
||||||
tempMat4.multLocal(worldMatrix);
|
|
||||||
tempMat4.toRotationMatrix(tempMat3);
|
|
||||||
tempMat3.invertLocal();
|
|
||||||
tempMat3.transposeLocal();
|
|
||||||
tempMat3.invertLocal();
|
|
||||||
u.setValue(VarType.Matrix3, tempMat3);
|
|
||||||
break;
|
|
||||||
case WorldViewProjectionMatrixInverse:
|
|
||||||
tempMat4.set(viewProjMatrix);
|
|
||||||
tempMat4.multLocal(worldMatrix);
|
|
||||||
tempMat4.invertLocal();
|
|
||||||
u.setValue(VarType.Matrix4, tempMat4);
|
|
||||||
break;
|
|
||||||
case ViewPort:
|
|
||||||
tempVec4.set(viewX, viewY, viewWidth, viewHeight);
|
|
||||||
u.setValue(VarType.Vector4, tempVec4);
|
|
||||||
break;
|
|
||||||
case Resolution:
|
|
||||||
tempVec2.set(viewWidth, viewHeight);
|
|
||||||
u.setValue(VarType.Vector2, tempVec2);
|
|
||||||
break;
|
|
||||||
case ResolutionInverse:
|
|
||||||
tempVec2.set(1f / viewWidth, 1f / viewHeight);
|
|
||||||
u.setValue(VarType.Vector2, tempVec2);
|
|
||||||
break;
|
|
||||||
case Aspect:
|
|
||||||
float aspect = ((float) viewWidth) / viewHeight;
|
|
||||||
u.setValue(VarType.Float, aspect);
|
|
||||||
break;
|
|
||||||
case FrustumNearFar:
|
|
||||||
tempVec2.set(near, far);
|
|
||||||
u.setValue(VarType.Vector2, tempVec2);
|
|
||||||
break;
|
|
||||||
case CameraPosition:
|
|
||||||
u.setValue(VarType.Vector3, camLoc);
|
|
||||||
break;
|
|
||||||
case CameraDirection:
|
|
||||||
u.setValue(VarType.Vector3, camDir);
|
|
||||||
break;
|
|
||||||
case CameraLeft:
|
|
||||||
u.setValue(VarType.Vector3, camLeft);
|
|
||||||
break;
|
|
||||||
case CameraUp:
|
|
||||||
u.setValue(VarType.Vector3, camUp);
|
|
||||||
break;
|
|
||||||
case Time:
|
|
||||||
u.setValue(VarType.Float, timer.getTimeInSeconds());
|
|
||||||
break;
|
|
||||||
case Tpf:
|
|
||||||
u.setValue(VarType.Float, timer.getTimePerFrame());
|
|
||||||
break;
|
|
||||||
case FrameRate:
|
|
||||||
u.setValue(VarType.Float, timer.getFrameRate());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
vars.release();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the material to use to render all future objects.
|
* Set the material to use to render all future objects.
|
||||||
* This overrides the material set on the geometry and renders
|
* This overrides the material set on the geometry and renders
|
||||||
@ -508,7 +360,7 @@ public class RenderManager {
|
|||||||
* @param timer The timer to query time world parameters
|
* @param timer The timer to query time world parameters
|
||||||
*/
|
*/
|
||||||
public void setTimer(Timer timer) {
|
public void setTimer(Timer timer) {
|
||||||
this.timer = timer;
|
uniformBindingManager.setTimer(timer);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -590,12 +442,21 @@ public class RenderManager {
|
|||||||
*/
|
*/
|
||||||
public void setWorldMatrix(Matrix4f mat) {
|
public void setWorldMatrix(Matrix4f mat) {
|
||||||
if (shader) {
|
if (shader) {
|
||||||
worldMatrix.set(mat);
|
uniformBindingManager.setWorldMatrix(mat);
|
||||||
} else {
|
} else {
|
||||||
renderer.setWorldMatrix(mat);
|
renderer.setWorldMatrix(mat);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal use only.
|
||||||
|
* Updates the given list of uniforms with {@link UniformBinding uniform bindings}
|
||||||
|
* based on the current world state.
|
||||||
|
*/
|
||||||
|
public void updateUniformBindings(List<Uniform> params) {
|
||||||
|
uniformBindingManager.updateUniformBindings(params);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Renders the given geometry.
|
* Renders the given geometry.
|
||||||
* <p>
|
* <p>
|
||||||
@ -975,22 +836,10 @@ public class RenderManager {
|
|||||||
private void setViewProjection(Camera cam, boolean ortho) {
|
private void setViewProjection(Camera cam, boolean ortho) {
|
||||||
if (shader) {
|
if (shader) {
|
||||||
if (ortho) {
|
if (ortho) {
|
||||||
viewMatrix.set(Matrix4f.IDENTITY);
|
uniformBindingManager.setCamera(cam, Matrix4f.IDENTITY, orthoMatrix, orthoMatrix);
|
||||||
projMatrix.set(orthoMatrix);
|
|
||||||
viewProjMatrix.set(orthoMatrix);
|
|
||||||
} else {
|
} else {
|
||||||
viewMatrix.set(cam.getViewMatrix());
|
uniformBindingManager.setCamera(cam, cam.getViewMatrix(), cam.getProjectionMatrix(), cam.getViewProjectionMatrix());
|
||||||
projMatrix.set(cam.getProjectionMatrix());
|
|
||||||
viewProjMatrix.set(cam.getViewProjectionMatrix());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
camLoc.set(cam.getLocation());
|
|
||||||
cam.getLeft(camLeft);
|
|
||||||
cam.getUp(camUp);
|
|
||||||
cam.getDirection(camDir);
|
|
||||||
|
|
||||||
near = cam.getFrustumNear();
|
|
||||||
far = cam.getFrustumFar();
|
|
||||||
} else {
|
} else {
|
||||||
if (ortho) {
|
if (ortho) {
|
||||||
renderer.setViewProjectionMatrices(Matrix4f.IDENTITY, orthoMatrix);
|
renderer.setViewProjectionMatrices(Matrix4f.IDENTITY, orthoMatrix);
|
||||||
@ -998,7 +847,6 @@ public class RenderManager {
|
|||||||
renderer.setViewProjectionMatrices(cam.getViewMatrix(),
|
renderer.setViewProjectionMatrices(cam.getViewMatrix(),
|
||||||
cam.getProjectionMatrix());
|
cam.getProjectionMatrix());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,13 +32,8 @@
|
|||||||
|
|
||||||
package com.jme3.shader;
|
package com.jme3.shader;
|
||||||
|
|
||||||
import com.jme3.export.InputCapsule;
|
|
||||||
import com.jme3.export.JmeExporter;
|
|
||||||
import com.jme3.export.JmeImporter;
|
|
||||||
import com.jme3.export.OutputCapsule;
|
|
||||||
import com.jme3.math.*;
|
import com.jme3.math.*;
|
||||||
import com.jme3.util.BufferUtils;
|
import com.jme3.util.BufferUtils;
|
||||||
import java.io.IOException;
|
|
||||||
import java.nio.FloatBuffer;
|
import java.nio.FloatBuffer;
|
||||||
|
|
||||||
public class Uniform extends ShaderVariable {
|
public class Uniform extends ShaderVariable {
|
||||||
@ -51,6 +46,11 @@ public class Uniform extends ShaderVariable {
|
|||||||
* Currently set value of the uniform.
|
* Currently set value of the uniform.
|
||||||
*/
|
*/
|
||||||
protected Object value = null;
|
protected Object value = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For arrays or matrices, efficient format
|
||||||
|
* that can be sent to GL faster.
|
||||||
|
*/
|
||||||
protected FloatBuffer multiData = null;
|
protected FloatBuffer multiData = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -63,100 +63,11 @@ public class Uniform extends ShaderVariable {
|
|||||||
*/
|
*/
|
||||||
protected UniformBinding binding;
|
protected UniformBinding binding;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to track which uniforms to clear to avoid
|
||||||
|
* values leaking from other materials that use that shader.
|
||||||
|
*/
|
||||||
protected boolean setByCurrentMaterial = false;
|
protected boolean setByCurrentMaterial = false;
|
||||||
// protected Object lastChanger = null;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void write(JmeExporter ex) throws IOException{
|
|
||||||
super.write(ex);
|
|
||||||
OutputCapsule oc = ex.getCapsule(this);
|
|
||||||
oc.write(varType, "varType", null);
|
|
||||||
oc.write(binding, "binding", null);
|
|
||||||
switch (varType){
|
|
||||||
case Boolean:
|
|
||||||
oc.write( ((Boolean)value).booleanValue(), "valueBoolean", false );
|
|
||||||
break;
|
|
||||||
case Float:
|
|
||||||
oc.write( ((Float)value).floatValue(), "valueFloat", 0);
|
|
||||||
break;
|
|
||||||
case FloatArray:
|
|
||||||
oc.write( (FloatBuffer)value, "valueFloatArray", null);
|
|
||||||
break;
|
|
||||||
case Int:
|
|
||||||
oc.write( ((Integer)value).intValue(), "valueInt", 0);
|
|
||||||
break;
|
|
||||||
case Matrix3:
|
|
||||||
oc.write( (Matrix3f)value, "valueMatrix3", null);
|
|
||||||
break;
|
|
||||||
case Matrix3Array:
|
|
||||||
case Matrix4Array:
|
|
||||||
case Vector2Array:
|
|
||||||
throw new UnsupportedOperationException("Come again?");
|
|
||||||
case Matrix4:
|
|
||||||
oc.write( (Matrix4f)value, "valueMatrix4", null);
|
|
||||||
break;
|
|
||||||
case Vector2:
|
|
||||||
oc.write( (Vector2f)value, "valueVector2", null);
|
|
||||||
break;
|
|
||||||
case Vector3:
|
|
||||||
oc.write( (Vector3f)value, "valueVector3", null);
|
|
||||||
break;
|
|
||||||
case Vector3Array:
|
|
||||||
oc.write( (FloatBuffer)value, "valueVector3Array", null);
|
|
||||||
break;
|
|
||||||
case Vector4:
|
|
||||||
oc.write( (ColorRGBA)value, "valueVector4", null);
|
|
||||||
break;
|
|
||||||
case Vector4Array:
|
|
||||||
oc.write( (FloatBuffer)value, "valueVector4Array", null);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void read(JmeImporter im) throws IOException{
|
|
||||||
super.read(im);
|
|
||||||
InputCapsule ic = im.getCapsule(this);
|
|
||||||
varType = ic.readEnum("varType", VarType.class, null);
|
|
||||||
binding = ic.readEnum("binding", UniformBinding.class, null);
|
|
||||||
switch (varType){
|
|
||||||
case Boolean:
|
|
||||||
value = ic.readBoolean("valueBoolean", false);
|
|
||||||
break;
|
|
||||||
case Float:
|
|
||||||
value = ic.readFloat("valueFloat", 0);
|
|
||||||
break;
|
|
||||||
case FloatArray:
|
|
||||||
value = ic.readFloatBuffer("valueFloatArray", null);
|
|
||||||
break;
|
|
||||||
case Int:
|
|
||||||
value = ic.readInt("valueInt", 0);
|
|
||||||
break;
|
|
||||||
case Matrix3:
|
|
||||||
multiData = ic.readFloatBuffer("valueMatrix3", null);
|
|
||||||
value = multiData;
|
|
||||||
break;
|
|
||||||
case Matrix4:
|
|
||||||
multiData = ic.readFloatBuffer("valueMatrix4", null);
|
|
||||||
value = multiData;
|
|
||||||
break;
|
|
||||||
case Vector2:
|
|
||||||
value = ic.readSavable("valueVector2", null);
|
|
||||||
break;
|
|
||||||
case Vector3:
|
|
||||||
value = ic.readSavable("valueVector3", null);
|
|
||||||
break;
|
|
||||||
case Vector3Array:
|
|
||||||
value = ic.readFloatBuffer("valueVector3Array", null);
|
|
||||||
break;
|
|
||||||
case Vector4:
|
|
||||||
value = ic.readSavable("valueVector4", null);
|
|
||||||
break;
|
|
||||||
case Vector4Array:
|
|
||||||
value = ic.readFloatBuffer("valueVector4Array", null);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString(){
|
public String toString(){
|
||||||
@ -199,13 +110,20 @@ public class Uniform extends ShaderVariable {
|
|||||||
setByCurrentMaterial = false;
|
setByCurrentMaterial = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// public void setLastChanger(Object lastChanger){
|
private static void setVector4(Vector4f vec, Object value) {
|
||||||
// this.lastChanger = lastChanger;
|
if (value instanceof ColorRGBA) {
|
||||||
// }
|
ColorRGBA color = (ColorRGBA) value;
|
||||||
//
|
vec.set(color.r, color.g, color.b, color.a);
|
||||||
// public Object getLastChanger(){
|
} else if (value instanceof Quaternion) {
|
||||||
// return lastChanger;
|
Quaternion quat = (Quaternion) value;
|
||||||
// }
|
vec.set(quat.getX(), quat.getY(), quat.getZ(), quat.getW());
|
||||||
|
} else if (value instanceof Vector4f) {
|
||||||
|
Vector4f vec4 = (Vector4f) value;
|
||||||
|
vec.set(vec4);
|
||||||
|
} else{
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void clearValue(){
|
public void clearValue(){
|
||||||
updateNeeded = true;
|
updateNeeded = true;
|
||||||
@ -224,8 +142,9 @@ public class Uniform extends ShaderVariable {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (varType == null)
|
if (varType == null) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
switch (varType){
|
switch (varType){
|
||||||
case Int:
|
case Int:
|
||||||
@ -244,44 +163,43 @@ public class Uniform extends ShaderVariable {
|
|||||||
this.value = Vector3f.ZERO;
|
this.value = Vector3f.ZERO;
|
||||||
break;
|
break;
|
||||||
case Vector4:
|
case Vector4:
|
||||||
if (this.value instanceof ColorRGBA){
|
this.value = Vector4f.ZERO;
|
||||||
this.value = ColorRGBA.BlackNoAlpha;
|
|
||||||
}else{
|
|
||||||
this.value = Quaternion.ZERO;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break; // won't happen because those are either textures
|
// won't happen because those are either textures
|
||||||
// or multidata types
|
// or multidata types
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setValue(VarType type, Object value){
|
public void setValue(VarType type, Object value){
|
||||||
if (location == -1)
|
if (location == LOC_NOT_DEFINED) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (varType != null && varType != type)
|
if (varType != null && varType != type) {
|
||||||
throw new IllegalArgumentException("Expected a " + varType.name() + " value!");
|
throw new IllegalArgumentException("Expected a " + varType.name() + " value!");
|
||||||
|
}
|
||||||
|
|
||||||
if (value == null)
|
if (value == null) {
|
||||||
throw new NullPointerException();
|
throw new NullPointerException();
|
||||||
|
}
|
||||||
|
|
||||||
setByCurrentMaterial = true;
|
setByCurrentMaterial = true;
|
||||||
|
|
||||||
switch (type){
|
switch (type){
|
||||||
case Matrix3:
|
case Matrix3:
|
||||||
Matrix3f m3 = (Matrix3f) value;
|
Matrix3f m3 = (Matrix3f) value;
|
||||||
if (multiData == null)
|
if (multiData == null) {
|
||||||
multiData = BufferUtils.createFloatBuffer(9);
|
multiData = BufferUtils.createFloatBuffer(9);
|
||||||
|
}
|
||||||
m3.fillFloatBuffer(multiData, true);
|
m3.fillFloatBuffer(multiData, true);
|
||||||
multiData.clear();
|
multiData.clear();
|
||||||
break;
|
break;
|
||||||
case Matrix4:
|
case Matrix4:
|
||||||
Matrix4f m4 = (Matrix4f) value;
|
Matrix4f m4 = (Matrix4f) value;
|
||||||
if (multiData == null)
|
if (multiData == null) {
|
||||||
multiData = BufferUtils.createFloatBuffer(16);
|
multiData = BufferUtils.createFloatBuffer(16);
|
||||||
|
}
|
||||||
m4.fillFloatBuffer(multiData, true);
|
m4.fillFloatBuffer(multiData, true);
|
||||||
multiData.clear();
|
multiData.clear();
|
||||||
break;
|
break;
|
||||||
@ -292,7 +210,6 @@ public class Uniform extends ShaderVariable {
|
|||||||
} else {
|
} else {
|
||||||
multiData = BufferUtils.ensureLargeEnough(multiData, fa.length);
|
multiData = BufferUtils.ensureLargeEnough(multiData, fa.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
multiData.put(fa);
|
multiData.put(fa);
|
||||||
multiData.clear();
|
multiData.clear();
|
||||||
break;
|
break;
|
||||||
@ -303,10 +220,9 @@ public class Uniform extends ShaderVariable {
|
|||||||
} else {
|
} else {
|
||||||
multiData = BufferUtils.ensureLargeEnough(multiData, v2a.length * 2);
|
multiData = BufferUtils.ensureLargeEnough(multiData, v2a.length * 2);
|
||||||
}
|
}
|
||||||
|
for (int i = 0; i < v2a.length; i++) {
|
||||||
for (int i = 0; i < v2a.length; i++)
|
|
||||||
BufferUtils.setInBuffer(v2a[i], multiData, i);
|
BufferUtils.setInBuffer(v2a[i], multiData, i);
|
||||||
|
}
|
||||||
multiData.clear();
|
multiData.clear();
|
||||||
break;
|
break;
|
||||||
case Vector3Array:
|
case Vector3Array:
|
||||||
@ -316,60 +232,54 @@ public class Uniform extends ShaderVariable {
|
|||||||
} else {
|
} else {
|
||||||
multiData = BufferUtils.ensureLargeEnough(multiData, v3a.length * 3);
|
multiData = BufferUtils.ensureLargeEnough(multiData, v3a.length * 3);
|
||||||
}
|
}
|
||||||
|
for (int i = 0; i < v3a.length; i++) {
|
||||||
for (int i = 0; i < v3a.length; i++)
|
|
||||||
BufferUtils.setInBuffer(v3a[i], multiData, i);
|
BufferUtils.setInBuffer(v3a[i], multiData, i);
|
||||||
|
}
|
||||||
multiData.clear();
|
multiData.clear();
|
||||||
break;
|
break;
|
||||||
case Vector4Array:
|
case Vector4Array:
|
||||||
Quaternion[] v4a = (Quaternion[]) value;
|
Vector4f[] v4a = (Vector4f[]) value;
|
||||||
if (multiData == null) {
|
if (multiData == null) {
|
||||||
multiData = BufferUtils.createFloatBuffer(v4a);
|
multiData = BufferUtils.createFloatBuffer(v4a);
|
||||||
} else {
|
} else {
|
||||||
multiData = BufferUtils.ensureLargeEnough(multiData, v4a.length * 4);
|
multiData = BufferUtils.ensureLargeEnough(multiData, v4a.length * 4);
|
||||||
}
|
}
|
||||||
|
for (int i = 0; i < v4a.length; i++) {
|
||||||
for (int i = 0; i < v4a.length; i++)
|
|
||||||
BufferUtils.setInBuffer(v4a[i], multiData, i);
|
BufferUtils.setInBuffer(v4a[i], multiData, i);
|
||||||
|
}
|
||||||
multiData.clear();
|
multiData.clear();
|
||||||
break;
|
break;
|
||||||
case Matrix3Array:
|
case Matrix3Array:
|
||||||
Matrix3f[] m3a = (Matrix3f[]) value;
|
Matrix3f[] m3a = (Matrix3f[]) value;
|
||||||
|
if (multiData == null) {
|
||||||
if (multiData == null)
|
|
||||||
multiData = BufferUtils.createFloatBuffer(m3a.length * 9);
|
multiData = BufferUtils.createFloatBuffer(m3a.length * 9);
|
||||||
else{
|
} else {
|
||||||
multiData = BufferUtils.ensureLargeEnough(multiData, m3a.length * 9);
|
multiData = BufferUtils.ensureLargeEnough(multiData, m3a.length * 9);
|
||||||
}
|
}
|
||||||
|
for (int i = 0; i < m3a.length; i++) {
|
||||||
for (int i = 0; i < m3a.length; i++)
|
|
||||||
m3a[i].fillFloatBuffer(multiData, true);
|
m3a[i].fillFloatBuffer(multiData, true);
|
||||||
|
}
|
||||||
multiData.clear();
|
multiData.clear();
|
||||||
break;
|
break;
|
||||||
case Matrix4Array:
|
case Matrix4Array:
|
||||||
Matrix4f[] m4a = (Matrix4f[]) value;
|
Matrix4f[] m4a = (Matrix4f[]) value;
|
||||||
|
if (multiData == null) {
|
||||||
if (multiData == null)
|
|
||||||
multiData = BufferUtils.createFloatBuffer(m4a.length * 16);
|
multiData = BufferUtils.createFloatBuffer(m4a.length * 16);
|
||||||
else{
|
} else {
|
||||||
multiData = BufferUtils.ensureLargeEnough(multiData, m4a.length * 16);
|
multiData = BufferUtils.ensureLargeEnough(multiData, m4a.length * 16);
|
||||||
}
|
}
|
||||||
|
for (int i = 0; i < m4a.length; i++) {
|
||||||
for (int i = 0; i < m4a.length; i++)
|
|
||||||
m4a[i].fillFloatBuffer(multiData, true);
|
m4a[i].fillFloatBuffer(multiData, true);
|
||||||
|
}
|
||||||
multiData.clear();
|
multiData.clear();
|
||||||
break;
|
break;
|
||||||
// Only use check if equals optimization for primitive values
|
// Only use check if equals optimization for primitive values
|
||||||
case Int:
|
case Int:
|
||||||
case Float:
|
case Float:
|
||||||
case Boolean:
|
case Boolean:
|
||||||
if (this.value != null && this.value.equals(value))
|
if (this.value != null && this.value.equals(value)) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
this.value = value;
|
this.value = value;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -377,8 +287,9 @@ public class Uniform extends ShaderVariable {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (multiData != null)
|
if (multiData != null) {
|
||||||
this.value = multiData;
|
this.value = multiData;
|
||||||
|
}
|
||||||
|
|
||||||
varType = type;
|
varType = type;
|
||||||
updateNeeded = true;
|
updateNeeded = true;
|
||||||
|
224
engine/src/core/com/jme3/shader/UniformBindingManager.java
Normal file
224
engine/src/core/com/jme3/shader/UniformBindingManager.java
Normal file
@ -0,0 +1,224 @@
|
|||||||
|
/*
|
||||||
|
* To change this template, choose Tools | Templates
|
||||||
|
* and open the template in the editor.
|
||||||
|
*/
|
||||||
|
package com.jme3.shader;
|
||||||
|
|
||||||
|
import com.jme3.math.*;
|
||||||
|
import com.jme3.renderer.Camera;
|
||||||
|
import com.jme3.renderer.RenderManager;
|
||||||
|
import com.jme3.system.Timer;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <code>UniformBindingManager</code> helps {@link RenderManager} to manage
|
||||||
|
* {@link UniformBinding uniform bindings}.
|
||||||
|
*
|
||||||
|
* The {@link #updateUniformBindings(java.util.List) } will update
|
||||||
|
* a given list of uniforms based on the current state
|
||||||
|
* of the manager.
|
||||||
|
*
|
||||||
|
* @author Kirill Vainer
|
||||||
|
*/
|
||||||
|
public class UniformBindingManager {
|
||||||
|
|
||||||
|
private Timer timer;
|
||||||
|
private float near, far;
|
||||||
|
private int viewX, viewY, viewWidth, viewHeight;
|
||||||
|
private Vector3f camUp = new Vector3f(),
|
||||||
|
camLeft = new Vector3f(),
|
||||||
|
camDir = new Vector3f(),
|
||||||
|
camLoc = new Vector3f();
|
||||||
|
|
||||||
|
private Matrix4f tempMatrix = new Matrix4f();
|
||||||
|
|
||||||
|
private Matrix4f viewMatrix = new Matrix4f();
|
||||||
|
private Matrix4f projMatrix = new Matrix4f();
|
||||||
|
private Matrix4f viewProjMatrix = new Matrix4f();
|
||||||
|
private Matrix4f worldMatrix = new Matrix4f();
|
||||||
|
|
||||||
|
private Matrix4f worldViewMatrix = new Matrix4f();
|
||||||
|
private Matrix4f worldViewProjMatrix = new Matrix4f();
|
||||||
|
private Matrix3f normalMatrix = new Matrix3f();
|
||||||
|
|
||||||
|
private Matrix4f worldMatrixInv = new Matrix4f();
|
||||||
|
private Matrix4f viewMatrixInv = new Matrix4f();
|
||||||
|
private Matrix4f projMatrixInv = new Matrix4f();
|
||||||
|
private Matrix4f viewProjMatrixInv = new Matrix4f();
|
||||||
|
private Matrix4f worldViewMatrixInv = new Matrix4f();
|
||||||
|
private Matrix3f normalMatrixInv = new Matrix3f();
|
||||||
|
private Matrix4f worldViewProjMatrixInv = new Matrix4f();
|
||||||
|
|
||||||
|
private Vector4f viewPort = new Vector4f();
|
||||||
|
private Vector2f resolution = new Vector2f();
|
||||||
|
private Vector2f resolutionInv = new Vector2f();
|
||||||
|
private Vector2f nearFar = new Vector2f();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal use only.
|
||||||
|
* Updates the given list of uniforms with {@link UniformBinding uniform bindings}
|
||||||
|
* based on the current world state.
|
||||||
|
*/
|
||||||
|
public void updateUniformBindings(List<Uniform> params) {
|
||||||
|
for (int i = 0; i < params.size(); i++) {
|
||||||
|
Uniform u = params.get(i);
|
||||||
|
switch (u.getBinding()) {
|
||||||
|
case WorldMatrix:
|
||||||
|
u.setValue(VarType.Matrix4, worldMatrix);
|
||||||
|
break;
|
||||||
|
case ViewMatrix:
|
||||||
|
u.setValue(VarType.Matrix4, viewMatrix);
|
||||||
|
break;
|
||||||
|
case ProjectionMatrix:
|
||||||
|
u.setValue(VarType.Matrix4, projMatrix);
|
||||||
|
break;
|
||||||
|
case ViewProjectionMatrix:
|
||||||
|
u.setValue(VarType.Matrix4, viewProjMatrix);
|
||||||
|
break;
|
||||||
|
case WorldViewMatrix:
|
||||||
|
worldViewMatrix.set(viewMatrix);
|
||||||
|
worldViewMatrix.multLocal(worldMatrix);
|
||||||
|
u.setValue(VarType.Matrix4, worldViewMatrix);
|
||||||
|
break;
|
||||||
|
case NormalMatrix:
|
||||||
|
tempMatrix.set(viewMatrix);
|
||||||
|
tempMatrix.multLocal(worldMatrix);
|
||||||
|
tempMatrix.toRotationMatrix(normalMatrix);
|
||||||
|
normalMatrix.invertLocal();
|
||||||
|
normalMatrix.transposeLocal();
|
||||||
|
u.setValue(VarType.Matrix3, normalMatrix);
|
||||||
|
break;
|
||||||
|
case WorldViewProjectionMatrix:
|
||||||
|
worldViewProjMatrix.set(viewProjMatrix);
|
||||||
|
worldViewProjMatrix.multLocal(worldMatrix);
|
||||||
|
u.setValue(VarType.Matrix4, worldViewProjMatrix);
|
||||||
|
break;
|
||||||
|
case WorldMatrixInverse:
|
||||||
|
worldMatrixInv.set(worldMatrix);
|
||||||
|
worldMatrixInv.invertLocal();
|
||||||
|
u.setValue(VarType.Matrix4, worldMatrixInv);
|
||||||
|
break;
|
||||||
|
case WorldMatrixInverseTranspose:
|
||||||
|
// worldMatrix.toRotationMatrix(tempMat3);
|
||||||
|
// tempMat3.invertLocal().transposeLocal();
|
||||||
|
// u.setValue(VarType.Matrix3, tempMat3, true);
|
||||||
|
break;
|
||||||
|
case ViewMatrixInverse:
|
||||||
|
viewMatrixInv.set(viewMatrix);
|
||||||
|
viewMatrixInv.invertLocal();
|
||||||
|
u.setValue(VarType.Matrix4, viewMatrixInv);
|
||||||
|
break;
|
||||||
|
case ProjectionMatrixInverse:
|
||||||
|
projMatrixInv.set(projMatrix);
|
||||||
|
projMatrixInv.invertLocal();
|
||||||
|
u.setValue(VarType.Matrix4, projMatrixInv);
|
||||||
|
break;
|
||||||
|
case ViewProjectionMatrixInverse:
|
||||||
|
viewProjMatrixInv.set(viewProjMatrix);
|
||||||
|
viewProjMatrixInv.invertLocal();
|
||||||
|
u.setValue(VarType.Matrix4, viewProjMatrixInv);
|
||||||
|
break;
|
||||||
|
case WorldViewMatrixInverse:
|
||||||
|
worldViewMatrixInv.set(viewMatrix);
|
||||||
|
worldViewMatrixInv.multLocal(worldMatrix);
|
||||||
|
worldViewMatrixInv.invertLocal();
|
||||||
|
u.setValue(VarType.Matrix4, worldViewMatrixInv);
|
||||||
|
break;
|
||||||
|
case NormalMatrixInverse:
|
||||||
|
tempMatrix.set(viewMatrix);
|
||||||
|
tempMatrix.multLocal(worldMatrix);
|
||||||
|
tempMatrix.toRotationMatrix(normalMatrixInv);
|
||||||
|
normalMatrixInv.invertLocal();
|
||||||
|
normalMatrixInv.transposeLocal();
|
||||||
|
normalMatrixInv.invertLocal();
|
||||||
|
u.setValue(VarType.Matrix3, normalMatrixInv);
|
||||||
|
break;
|
||||||
|
case WorldViewProjectionMatrixInverse:
|
||||||
|
worldViewProjMatrixInv.set(viewProjMatrix);
|
||||||
|
worldViewProjMatrixInv.multLocal(worldMatrix);
|
||||||
|
worldViewProjMatrixInv.invertLocal();
|
||||||
|
u.setValue(VarType.Matrix4, worldViewProjMatrixInv);
|
||||||
|
break;
|
||||||
|
case ViewPort:
|
||||||
|
viewPort.set(viewX, viewY, viewWidth, viewHeight);
|
||||||
|
u.setValue(VarType.Vector4, viewPort);
|
||||||
|
break;
|
||||||
|
case Resolution:
|
||||||
|
resolution.set(viewWidth, viewHeight);
|
||||||
|
u.setValue(VarType.Vector2, resolution);
|
||||||
|
break;
|
||||||
|
case ResolutionInverse:
|
||||||
|
resolutionInv.set(1f / viewWidth, 1f / viewHeight);
|
||||||
|
u.setValue(VarType.Vector2, resolutionInv);
|
||||||
|
break;
|
||||||
|
case Aspect:
|
||||||
|
float aspect = ((float) viewWidth) / viewHeight;
|
||||||
|
u.setValue(VarType.Float, aspect);
|
||||||
|
break;
|
||||||
|
case FrustumNearFar:
|
||||||
|
nearFar.set(near, far);
|
||||||
|
u.setValue(VarType.Vector2, nearFar);
|
||||||
|
break;
|
||||||
|
case CameraPosition:
|
||||||
|
u.setValue(VarType.Vector3, camLoc);
|
||||||
|
break;
|
||||||
|
case CameraDirection:
|
||||||
|
u.setValue(VarType.Vector3, camDir);
|
||||||
|
break;
|
||||||
|
case CameraLeft:
|
||||||
|
u.setValue(VarType.Vector3, camLeft);
|
||||||
|
break;
|
||||||
|
case CameraUp:
|
||||||
|
u.setValue(VarType.Vector3, camUp);
|
||||||
|
break;
|
||||||
|
case Time:
|
||||||
|
u.setValue(VarType.Float, timer.getTimeInSeconds());
|
||||||
|
break;
|
||||||
|
case Tpf:
|
||||||
|
u.setValue(VarType.Float, timer.getTimePerFrame());
|
||||||
|
break;
|
||||||
|
case FrameRate:
|
||||||
|
u.setValue(VarType.Float, timer.getFrameRate());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal use only. Sets the world matrix to use for future
|
||||||
|
* rendering. This has no effect unless objects are rendered manually
|
||||||
|
* using {@link Material#render(com.jme3.scene.Geometry, com.jme3.renderer.RenderManager) }.
|
||||||
|
* Using {@link #renderGeometry(com.jme3.scene.Geometry) } will
|
||||||
|
* override this value.
|
||||||
|
*
|
||||||
|
* @param mat The world matrix to set
|
||||||
|
*/
|
||||||
|
public void setWorldMatrix(Matrix4f mat) {
|
||||||
|
worldMatrix.set(mat);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the timer that should be used to query the time based
|
||||||
|
* {@link UniformBinding}s for material world parameters.
|
||||||
|
*
|
||||||
|
* @param timer The timer to query time world parameters
|
||||||
|
*/
|
||||||
|
public void setTimer(com.jme3.system.Timer timer) {
|
||||||
|
this.timer = timer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCamera(Camera cam, Matrix4f viewMatrix, Matrix4f projMatrix, Matrix4f viewProjMatrix) {
|
||||||
|
this.viewMatrix.set(viewMatrix);
|
||||||
|
this.projMatrix.set(projMatrix);
|
||||||
|
this.viewProjMatrix.set(viewProjMatrix);
|
||||||
|
|
||||||
|
camLoc.set(cam.getLocation());
|
||||||
|
cam.getLeft(camLeft);
|
||||||
|
cam.getUp(camUp);
|
||||||
|
cam.getDirection(camDir);
|
||||||
|
|
||||||
|
near = cam.getFrustumNear();
|
||||||
|
far = cam.getFrustumFar();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user