📄 shadowedrenderpass.java
字号:
if (lightingMethod == LightingMethod.Additive && rTexture ) {
saveEnforcedStates();
context.enforceState(noStencil);
context.enforceState(colorEnabled);
context.enforceState(cullBackFace);
context.enforceState(blendTex);
renderScene(r);
replaceEnforcedStates();
}
if (renderVolume) {
drawVolumes(r);
}
cleanup();
}
protected void cleanup() {
occluderMeshes.clear();
shadowLights.clear();
}
protected void maskShadowLights(int mask) {
for (int x = shadowLights.size(); --x >= 0;) {
Light l = shadowLights.get(x);
l.pushLightMask();
l.setLightMask(mask);
}
}
protected void unmaskShadowLights() {
for (int x = shadowLights.size(); --x >= 0;) {
Light l = shadowLights.get(x);
l.popLightMask();
}
}
protected void renderScene(Renderer r) {
for (int i = 0, sSize = spatials.size(); i < sSize; i++) {
Spatial s = spatials.get(i);
s.onDraw(r);
}
r.renderQueue();
}
protected void getShadowLights() {
if (shadowLights == null) shadowLights = new ArrayList<Light>();
for (int x = occluders.size(); --x >= 0;)
getShadowLights(occluders.get(x));
}
protected void getShadowLights(Spatial s) {
if (s instanceof Geometry) {
Geometry g = (Geometry)s;
LightState ls = (LightState)g.states[RenderState.StateType.Light.ordinal()];
if (ls != null) {
for (int q = ls.getQuantity(); --q >= 0;) {
Light l = ls.get(q);
if (l.isShadowCaster()
&& (l.getType() == Light.Type.Directional ||
l.getType() == Light.Type.Point)
&& !shadowLights.contains(l)) {
shadowLights.add(l);
}
}
}
}
if (s instanceof Node) {
Node n = (Node)s;
if (n.getChildren() != null) {
List<Spatial> children = n.getChildren();
for (int i = children.size(); --i >= 0;) {
Spatial child = children.get(i);
getShadowLights(child);
}
}
}
}
protected void setupOccluderMeshes() {
if (occluderMeshes == null) occluderMeshes = new ArrayList<TriMesh>();
occluderMeshes.clear();
for (int x = occluders.size(); --x >= 0;)
setupOccluderMeshes(occluders.get(x));
meshes.keySet().retainAll(occluderMeshes);
}
protected void setupOccluderMeshes(Spatial spat) {
if (spat instanceof TriMesh)
addOccluderMeshes((TriMesh)spat);
else if (spat instanceof Node) {
Node node = (Node)spat;
for (int c = 0, nQ = node.getQuantity(); c < nQ; c++) {
Spatial child = node.getChild(c);
setupOccluderMeshes(child);
}
}
}
private void addOccluderMeshes(TriMesh mesh) {
if (mesh.isCastsShadows()) {
occluderMeshes.add(mesh);
}
}
/**
* saves any states enforced by the user for replacement at the end of the
* pass.
*/
protected void saveEnforcedStates() {
for (int x = RenderState.StateType.values().length; --x >= 0;) {
preStates[x] = context.enforcedStateList[x];
}
}
/**
* replaces any states enforced by the user at the end of the pass.
*/
protected void replaceEnforcedStates() {
for (int x = RenderState.StateType.values().length; --x >= 0;) {
context.enforcedStateList[x] = preStates[x];
}
}
protected void generateVolumes() {
for (int c = 0; c < occluderMeshes.size(); c++) {
TriMesh mesh = occluderMeshes.get(c);
if (!shadowGate.shouldUpdateShadows(mesh)) continue;
if (!meshes.containsKey(mesh)) {
meshes.put(mesh, new MeshShadows(mesh));
} else if ((mesh.getLocks() & Spatial.LOCKED_SHADOWS) != 0) {
continue;
}
MeshShadows sv = meshes.get(mesh);
// Create the geometry for the shadow volume
sv.createGeometry((LightState) mesh.states[RenderState.StateType.Light.ordinal()]);
}
}
/**
* <code>addShadowVolumes</code> adds the shadow volumes for a given light
* to volumeNode
*
* @param light
* the light whose volumes should be added
*/
protected void addShadowVolumes(Light light) {
if (enabled) {
for (int i = occluderMeshes.size(); --i >= 0;) {
TriMesh key = occluderMeshes.get(i);
if (!shadowGate.shouldDrawShadows(key)) continue;
MeshShadows ms = meshes.get(key);
ShadowVolume lv = ms.getShadowVolume(light);
if (lv != null)
volumeNode.getChildren().add(lv);
}
}
}
/**
* <code>drawVolumes</code> is a debug method used to draw the shadow
* volumes currently in use in the pass.
*
* @param r
* Renderer to draw with.
*/
protected void drawVolumes(Renderer r) {
Node renderNode = new Node("renderVolume");
renderNode.setRenderState(cullBackFace);
renderNode.setRenderState(forTesting);
renderNode.setRenderState(colorEnabled);
renderNode.setRenderState(noStencil);
renderNode.setRenderState(alphaBlended);
for (int i = occluderMeshes.size(); --i >= 0;) {
Object key = occluderMeshes.get(i);
MeshShadows ms = meshes.get(key);
if(ms != null) {
ArrayList<ShadowVolume> volumes = ms.getVolumes();
for (int v = 0, vSize = volumes.size(); v < vSize; v++) {
ShadowVolume vol = volumes.get(v);
renderNode.attachChild(vol);
vol.setDefaultColor(new ColorRGBA(0,1,0,.075f));
}
}
}
renderNode.updateRenderState();
renderNode.updateGeometricState(0, true);
renderNode.onDraw(r);
}
protected static ZBufferState zbufferWriteLE;
protected static ZBufferState zbufferAlways;
protected static ZBufferState forTesting;
protected static ZBufferState forColorPassTesting;
protected static StencilState noStencil;
protected static StencilState stencilFrontFaces;
protected static StencilState stencilBothFaces;
protected static StencilState stencilBackFaces;
protected static StencilState stencilDrawOnlyWhenSet;
protected static StencilState stencilDrawWhenNotSet;
protected static CullState cullFrontFace;
protected static CullState cullBackFace;
protected static CullState noCull;
protected static TextureState noTexture;
protected static LightState lights;
protected static LightState noLights;
public static BlendState blended;
public static BlendState alphaBlended;
public static BlendState modblended;
public static BlendState blendTex;
protected static ColorMaskState colorEnabled;
protected static ColorMaskState colorDisabled;
protected void init() {
if (initialised)
return;
initialised = true;
Renderer r = DisplaySystem.getDisplaySystem().getRenderer();
zbufferWriteLE = r.createZBufferState();
zbufferWriteLE.setWritable(true);
zbufferWriteLE.setFunction(ZBufferState.TestFunction.LessThanOrEqualTo);
zbufferWriteLE.setEnabled(true);
zbufferAlways = r.createZBufferState();
zbufferAlways.setEnabled(false);
zbufferAlways.setWritable(false);
forTesting = r.createZBufferState();
forTesting.setWritable(false);
forTesting.setFunction(ZBufferState.TestFunction.LessThan);
forTesting.setEnabled(true);
forColorPassTesting = r.createZBufferState();
forColorPassTesting.setWritable(false);
forColorPassTesting.setFunction(ZBufferState.TestFunction.LessThanOrEqualTo);
forColorPassTesting.setEnabled(true);
noStencil = r.createStencilState();
noStencil.setEnabled(false);
stencilBothFaces = r.createStencilState();
stencilBothFaces.setEnabled(true);
stencilBothFaces.setUseTwoSided(true);
stencilBothFaces.setStencilMaskFront(~0);
stencilBothFaces.setStencilFunctionFront(StencilFunction.Always);
stencilBothFaces.setStencilOpFailFront(StencilOperation.Keep);
stencilBothFaces.setStencilOpZFailFront(StencilOperation.Keep);
stencilBothFaces.setStencilOpZPassFront(StencilOperation.IncrementWrap);
stencilBothFaces.setStencilMaskBack(~0);
stencilBothFaces.setStencilFunctionBack(StencilFunction.Always);
stencilBothFaces.setStencilOpFailBack(StencilOperation.Keep);
stencilBothFaces.setStencilOpZFailBack(StencilOperation.Keep);
stencilBothFaces.setStencilOpZPassBack(StencilOperation.DecrementWrap);
stencilFrontFaces = r.createStencilState();
stencilFrontFaces.setEnabled(true);
stencilFrontFaces.setStencilMask(~0);
stencilFrontFaces.setStencilFunction(StencilFunction.Always);
stencilFrontFaces.setStencilOpFail(StencilOperation.Keep);
stencilFrontFaces.setStencilOpZFail(StencilOperation.Keep);
stencilFrontFaces.setStencilOpZPass(StencilOperation.IncrementWrap);
stencilBackFaces = r.createStencilState();
stencilBackFaces.setEnabled(true);
stencilBackFaces.setStencilMask(~0);
stencilBackFaces.setStencilFunction(StencilFunction.Always);
stencilBackFaces.setStencilOpFail(StencilOperation.Keep);
stencilBackFaces.setStencilOpZFail(StencilOperation.Keep);
stencilBackFaces.setStencilOpZPass(StencilOperation.DecrementWrap);
stencilDrawOnlyWhenSet = r.createStencilState();
stencilDrawOnlyWhenSet.setEnabled(true);
stencilDrawOnlyWhenSet.setStencilMask(~0);
stencilDrawOnlyWhenSet.setStencilFunction(StencilFunction.NotEqualTo);
stencilDrawOnlyWhenSet.setStencilOpFail(StencilOperation.Keep);
stencilDrawOnlyWhenSet.setStencilOpZFail(StencilOperation.Keep);
stencilDrawOnlyWhenSet.setStencilOpZPass(StencilOperation.Keep);
stencilDrawOnlyWhenSet.setStencilReference(0);
stencilDrawWhenNotSet = r.createStencilState();
stencilDrawWhenNotSet.setEnabled(true);
stencilDrawWhenNotSet.setStencilMask(~0);
stencilDrawWhenNotSet.setStencilFunction(StencilFunction.EqualTo);
stencilDrawWhenNotSet.setStencilOpFail(StencilOperation.Keep);
stencilDrawWhenNotSet.setStencilOpZFail(StencilOperation.Keep);
stencilDrawWhenNotSet.setStencilOpZPass(StencilOperation.Keep);
stencilDrawWhenNotSet.setStencilReference(0);
cullFrontFace = r.createCullState();
cullFrontFace.setEnabled(true);
cullFrontFace.setCullFace(CullState.Face.Front);
noCull = r.createCullState();
noCull.setEnabled(false);
noLights = r.createLightState();
noLights.setEnabled(false);
cullBackFace = r.createCullState();
cullBackFace.setEnabled(true);
cullBackFace.setCullFace(CullState.Face.Back);
blended = r.createBlendState();
blended.setEnabled(true);
blended.setBlendEnabled(true);
blended.setDestinationFunction(BlendState.DestinationFunction.One);
blended.setSourceFunction(BlendState.SourceFunction.DestinationColor);
alphaBlended = r.createBlendState();
alphaBlended.setEnabled(true);
alphaBlended.setBlendEnabled(true);
alphaBlended.setDestinationFunction(BlendState.DestinationFunction.OneMinusSourceAlpha);
alphaBlended.setSourceFunction(BlendState.SourceFunction.One);
modblended = r.createBlendState();
modblended.setEnabled(true);
modblended.setBlendEnabled(true);
modblended.setDestinationFunction(BlendState.DestinationFunction.OneMinusSourceAlpha);
modblended.setSourceFunction(BlendState.SourceFunction.DestinationColor);
blendTex = r.createBlendState();
blendTex.setEnabled(true);
blendTex.setBlendEnabled(true);
blendTex.setDestinationFunction(BlendState.DestinationFunction.Zero);
blendTex.setSourceFunction(BlendState.SourceFunction.DestinationColor);
colorEnabled = r.createColorMaskState();
colorEnabled.setAll(true);
colorDisabled = r.createColorMaskState();
colorDisabled.setAll(false);
volumeNode.setRenderQueueMode(Renderer.QUEUE_SKIP);
volumeNode.updateRenderState();
volumeNode.attachChild(new Node());
noTexture = r.createTextureState();
noTexture.setEnabled(false);
resetShadowQuad(r);
lights = r.createLightState();
lights.setEnabled(true);
lights.setLightMask(LightState.MASK_AMBIENT | LightState.MASK_GLOBALAMBIENT);
}
public void resetShadowQuad(Renderer r) {
if (r.getWidth() == quadWidth && r.getHeight() == quadHeight) return;
quadWidth = r.getWidth();
quadHeight = r.getHeight();
shadowQuad.resize(quadWidth, r.getHeight());
shadowQuad.setLocalTranslation(new Vector3f(quadWidth >> 1, quadHeight >> 1, 0));
shadowQuad.setRenderQueueMode(Renderer.QUEUE_SKIP);
shadowQuad.updateGeometricState(0, true);
shadowQuad.updateRenderState();
}
public ShadowGate getShadowGate() {
return shadowGate;
}
public void setShadowGate(ShadowGate shadowCheck) {
this.shadowGate = shadowCheck;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -