use of com.jme3.material.MatParamOverride in project jmonkeyengine by jMonkeyEngine.
the class Material method updateShaderMaterialParameters.
private int updateShaderMaterialParameters(Renderer renderer, Shader shader, SafeArrayList<MatParamOverride> worldOverrides, SafeArrayList<MatParamOverride> forcedOverrides) {
int unit = 0;
if (worldOverrides != null) {
unit = applyOverrides(renderer, shader, worldOverrides, unit);
}
if (forcedOverrides != null) {
unit = applyOverrides(renderer, shader, forcedOverrides, unit);
}
for (int i = 0; i < paramValues.size(); i++) {
MatParam param = paramValues.getValue(i);
VarType type = param.getVarType();
Uniform uniform = shader.getUniform(param.getPrefixedName());
if (uniform.isSetByCurrentMaterial()) {
continue;
}
if (type.isTextureType()) {
renderer.setTexture(unit, (Texture) param.getValue());
uniform.setValue(VarType.Int, unit);
unit++;
} else {
uniform.setValue(type, param.getValue());
}
}
//TODO HACKY HACK remove this when texture unit is handled by the uniform.
return unit;
}
use of com.jme3.material.MatParamOverride in project jmonkeyengine by jMonkeyEngine.
the class MPOTestUtils method validateSubScene.
private static void validateSubScene(Spatial scene) {
scene.checkCulling(DUMMY_CAM);
Set<MatParamOverride> actualOverrides = new HashSet<MatParamOverride>();
for (MatParamOverride override : scene.getWorldMatParamOverrides()) {
actualOverrides.add(override);
}
Set<MatParamOverride> expectedOverrides = new HashSet<MatParamOverride>();
Spatial current = scene;
while (current != null) {
for (MatParamOverride override : current.getLocalMatParamOverrides()) {
expectedOverrides.add(override);
}
current = current.getParent();
}
assertEquals("For " + scene, expectedOverrides, actualOverrides);
}
use of com.jme3.material.MatParamOverride in project jmonkeyengine by jMonkeyEngine.
the class Material method render.
/**
* Called by {@link RenderManager} to render the geometry by
* using this material.
* <p>
* The material is rendered as follows:
* <ul>
* <li>Determine which technique to use to render the material -
* either what the user selected via
* {@link #selectTechnique(java.lang.String, com.jme3.renderer.RenderManager)
* Material.selectTechnique()},
* or the first default technique that the renderer supports
* (based on the technique's {@link TechniqueDef#getRequiredCaps() requested rendering capabilities})<ul>
* <li>If the technique has been changed since the last frame, then it is notified via
* {@link Technique#makeCurrent(com.jme3.asset.AssetManager, boolean, java.util.EnumSet)
* Technique.makeCurrent()}.
* If the technique wants to use a shader to render the model, it should load it at this part -
* the shader should have all the proper defines as declared in the technique definition,
* including those that are bound to material parameters.
* The technique can re-use the shader from the last frame if
* no changes to the defines occurred.</li></ul>
* <li>Set the {@link RenderState} to use for rendering. The render states are
* applied in this order (later RenderStates override earlier RenderStates):<ol>
* <li>{@link TechniqueDef#getRenderState() Technique Definition's RenderState}
* - i.e. specific renderstate that is required for the shader.</li>
* <li>{@link #getAdditionalRenderState() Material Instance Additional RenderState}
* - i.e. ad-hoc renderstate set per model</li>
* <li>{@link RenderManager#getForcedRenderState() RenderManager's Forced RenderState}
* - i.e. renderstate requested by a {@link com.jme3.post.SceneProcessor} or
* post-processing filter.</li></ol>
* <li>If the technique {@link TechniqueDef#isUsingShaders() uses a shader}, then the uniforms of the shader must be updated.<ul>
* <li>Uniforms bound to material parameters are updated based on the current material parameter values.</li>
* <li>Uniforms bound to world parameters are updated from the RenderManager.
* Internally {@link UniformBindingManager} is used for this task.</li>
* <li>Uniforms bound to textures will cause the texture to be uploaded as necessary.
* The uniform is set to the texture unit where the texture is bound.</li></ul>
* <li>If the technique uses a shader, the model is then rendered according
* to the lighting mode specified on the technique definition.<ul>
* <li>{@link LightMode#SinglePass single pass light mode} fills the shader's light uniform arrays
* with the first 4 lights and renders the model once.</li>
* <li>{@link LightMode#MultiPass multi pass light mode} light mode renders the model multiple times,
* for the first light it is rendered opaque, on subsequent lights it is
* rendered with {@link BlendMode#AlphaAdditive alpha-additive} blending and depth writing disabled.</li>
* </ul>
* <li>For techniques that do not use shaders,
* fixed function OpenGL is used to render the model (see {@link GL1Renderer} interface):<ul>
* <li>OpenGL state ({@link FixedFuncBinding}) that is bound to material parameters is updated. </li>
* <li>The texture set on the material is uploaded and bound.
* Currently only 1 texture is supported for fixed function techniques.</li>
* <li>If the technique uses lighting, then OpenGL lighting state is updated
* based on the light list on the geometry, otherwise OpenGL lighting is disabled.</li>
* <li>The mesh is uploaded and rendered.</li>
* </ul>
* </ul>
*
* @param geometry The geometry to render
* @param lights Presorted and filtered light list to use for rendering
* @param renderManager The render manager requesting the rendering
*/
public void render(Geometry geometry, LightList lights, RenderManager renderManager) {
if (technique == null) {
selectTechnique(TechniqueDef.DEFAULT_TECHNIQUE_NAME, renderManager);
}
TechniqueDef techniqueDef = technique.getDef();
Renderer renderer = renderManager.getRenderer();
EnumSet<Caps> rendererCaps = renderer.getCaps();
if (techniqueDef.isNoRender()) {
return;
}
// Apply render state
updateRenderState(renderManager, renderer, techniqueDef);
// Get world overrides
SafeArrayList<MatParamOverride> overrides = geometry.getWorldMatParamOverrides();
// Select shader to use
Shader shader = technique.makeCurrent(renderManager, overrides, renderManager.getForcedMatParams(), lights, rendererCaps);
// Begin tracking which uniforms were changed by material.
clearUniformsSetByCurrent(shader);
// Set uniform bindings
renderManager.updateUniformBindings(shader);
// Set material parameters
int unit = updateShaderMaterialParameters(renderer, shader, overrides, renderManager.getForcedMatParams());
// Clear any uniforms not changed by material.
resetUniformsNotSetByCurrent(shader);
// Delegate rendering to the technique
technique.render(renderManager, shader, geometry, lights, unit);
}
use of com.jme3.material.MatParamOverride in project jmonkeyengine by jMonkeyEngine.
the class Technique method makeCurrent.
/**
* Called by the material to determine which shader to use for rendering.
*
* The {@link TechniqueDefLogic} is used to determine the shader to use
* based on the {@link LightMode}.
*
* @param renderManager The render manager for which the shader is to be selected.
* @param rendererCaps The renderer capabilities which the shader should support.
* @return A compatible shader.
*/
Shader makeCurrent(RenderManager renderManager, SafeArrayList<MatParamOverride> worldOverrides, SafeArrayList<MatParamOverride> forcedOverrides, LightList lights, EnumSet<Caps> rendererCaps) {
TechniqueDefLogic logic = def.getLogic();
AssetManager assetManager = owner.getMaterialDef().getAssetManager();
dynamicDefines.clear();
dynamicDefines.setAll(paramDefines);
if (worldOverrides != null) {
applyOverrides(dynamicDefines, worldOverrides);
}
if (forcedOverrides != null) {
applyOverrides(dynamicDefines, forcedOverrides);
}
return logic.makeCurrent(assetManager, renderManager, rendererCaps, lights, dynamicDefines);
}
use of com.jme3.material.MatParamOverride in project jmonkeyengine by jMonkeyEngine.
the class Spatial method read.
public void read(JmeImporter im) throws IOException {
InputCapsule ic = im.getCapsule(this);
name = ic.readString("name", null);
worldBound = (BoundingVolume) ic.readSavable("world_bound", null);
cullHint = ic.readEnum("cull_mode", CullHint.class, CullHint.Inherit);
batchHint = ic.readEnum("batch_hint", BatchHint.class, BatchHint.Inherit);
queueBucket = ic.readEnum("queue", RenderQueue.Bucket.class, RenderQueue.Bucket.Inherit);
shadowMode = ic.readEnum("shadow_mode", ShadowMode.class, ShadowMode.Inherit);
localTransform = (Transform) ic.readSavable("transform", Transform.IDENTITY);
localLights = (LightList) ic.readSavable("lights", null);
localLights.setOwner(this);
ArrayList<MatParamOverride> localOverridesList = ic.readSavableArrayList("overrides", null);
if (localOverridesList == null) {
localOverrides = new SafeArrayList<>(MatParamOverride.class);
} else {
localOverrides = new SafeArrayList(MatParamOverride.class, localOverridesList);
}
worldOverrides = new SafeArrayList<>(MatParamOverride.class);
//changed for backward compatibility with j3o files generated before the AnimControl/SkeletonControl split
//the AnimControl creates the SkeletonControl for old files and add it to the spatial.
//The SkeletonControl must be the last in the stack so we add the list of all other control before it.
//When backward compatibility won't be needed anymore this can be replaced by :
//controls = ic.readSavableArrayList("controlsList", null));
controls.addAll(0, ic.readSavableArrayList("controlsList", null));
userData = (HashMap<String, Savable>) ic.readStringSavableMap("user_data", null);
}
Aggregations