add StaticPassLightingLogic

experimental^2^2
Kirill Vainer 9 years ago
parent cb5c1395b3
commit 10a87ce24e
  1. 156
      jme3-core/src/main/java/com/jme3/material/StaticPassLightingLogic.java

@ -0,0 +1,156 @@
/*
* Copyright (c) 2009-2015 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jme3.material;
import com.jme3.asset.AssetManager;
import com.jme3.light.DirectionalLight;
import com.jme3.light.Light;
import com.jme3.light.Light.Type;
import com.jme3.light.LightList;
import com.jme3.light.PointLight;
import com.jme3.light.SpotLight;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.jme3.renderer.Caps;
import com.jme3.renderer.RenderManager;
import com.jme3.renderer.Renderer;
import com.jme3.scene.Geometry;
import com.jme3.shader.DefineList;
import com.jme3.shader.Shader;
import com.jme3.shader.Uniform;
import com.jme3.shader.VarType;
import java.util.ArrayList;
import java.util.EnumSet;
/**
* Rendering logic for static pass.
*
* @author Kirill Vainer
*/
public final class StaticPassLightingLogic extends DefaultTechniqueDefLogic {
private static final String DEFINE_NUM_DIR_LIGHTS = "NUM_DIR_LIGHTS";
private static final String DEFINE_NUM_POINT_LIGHTS = "NUM_POINT_LIGHTS";
private static final String DEFINE_NUM_SPOT_LIGHTS = "NUM_SPOT_LIGHTS";
private final int numDirLightsDefineId;
private final int numPointLightsDefineId;
private final int numSpotLightsDefineId;
private final ArrayList<DirectionalLight> tempDirLights = new ArrayList<DirectionalLight>();
private final ArrayList<PointLight> tempPointLights = new ArrayList<PointLight>();
private final ArrayList<SpotLight> tempSpotLights = new ArrayList<SpotLight>();
private final ColorRGBA ambientLightColor = new ColorRGBA(0, 0, 0, 1);
public StaticPassLightingLogic(TechniqueDef techniqueDef) {
super(techniqueDef);
numDirLightsDefineId = techniqueDef.addShaderUnmappedDefine(DEFINE_NUM_DIR_LIGHTS, VarType.Int);
numPointLightsDefineId = techniqueDef.addShaderUnmappedDefine(DEFINE_NUM_POINT_LIGHTS, VarType.Int);
numSpotLightsDefineId = techniqueDef.addShaderUnmappedDefine(DEFINE_NUM_SPOT_LIGHTS, VarType.Int);
}
@Override
public Shader makeCurrent(AssetManager assetManager, RenderManager renderManager,
EnumSet<Caps> rendererCaps, LightList lights, DefineList defines) {
// TODO: if it ever changes that render isn't called
// right away with the same geometry after makeCurrent, it would be
// a problem.
// Do a radix sort.
tempDirLights.clear();
tempPointLights.clear();
tempSpotLights.clear();
for (Light light : lights) {
switch (light.getType()) {
case Directional:
tempDirLights.add((DirectionalLight) light);
break;
case Point:
tempPointLights.add((PointLight) light);
break;
case Spot:
tempSpotLights.add((SpotLight) light);
break;
}
}
defines.set(numDirLightsDefineId, tempDirLights.size());
defines.set(numPointLightsDefineId, tempPointLights.size());
defines.set(numSpotLightsDefineId, tempSpotLights.size());
return techniqueDef.getShader(assetManager, rendererCaps, defines);
}
private void updateLightListUniforms(Shader shader, LightList lights) {
Uniform ambientColor = shader.getUniform("g_AmbientLightColor");
ambientColor.setValue(VarType.Vector4, getAmbientColor(lights, true, ambientLightColor));
Uniform lightData = shader.getUniform("g_LightData");
int index = 0;
for (DirectionalLight light : tempDirLights) {
ColorRGBA color = light.getColor();
Vector3f dir = light.getDirection();
lightData.setVector4InArray(color.r, color.g, color.b, 1f, index++);
lightData.setVector4InArray(dir.x, dir.y, dir.z, 1f, index++);
}
for (PointLight light : tempPointLights) {
ColorRGBA color = light.getColor();
Vector3f pos = light.getPosition();
lightData.setVector4InArray(color.r, color.g, color.b, 1f, index++);
lightData.setVector4InArray(pos.x, pos.y, pos.z, 1f, index++);
}
for (SpotLight light : tempSpotLights) {
ColorRGBA color = light.getColor();
Vector3f pos = light.getPosition();
Vector3f dir = light.getDirection();
float invRange = light.getInvSpotRange();
float spotAngleCos = light.getPackedAngleCos();
lightData.setVector4InArray(color.r, color.g, color.b, 1f, index++);
lightData.setVector4InArray(pos.x, pos.y, pos.z, invRange, index++);
lightData.setVector4InArray(dir.x, dir.y, dir.z, spotAngleCos, index++);
}
}
@Override
public void render(RenderManager renderManager, Shader shader, Geometry geometry, LightList lights) {
Renderer renderer = renderManager.getRenderer();
updateLightListUniforms(shader, lights);
renderer.setShader(shader);
renderMeshFromGeometry(renderer, geometry);
}
}
Loading…
Cancel
Save