use of com.jme3.shader.Shader in project jmonkeyengine by jMonkeyEngine.
the class Material method getSortId.
/**
* Returns the sorting ID or sorting index for this material.
*
* <p>The sorting ID is used internally by the system to sort rendering
* of geometries. It sorted to reduce shader switches, if the shaders
* are equal, then it is sorted by textures.
*
* @return The sorting ID used for sorting geometries for rendering.
*/
public int getSortId() {
if (sortingId == -1 && technique != null) {
sortingId = technique.getSortId() << 16;
int texturesSortId = 17;
for (int i = 0; i < paramValues.size(); i++) {
MatParam param = paramValues.getValue(i);
if (!param.getVarType().isTextureType()) {
continue;
}
Texture texture = (Texture) param.getValue();
if (texture == null) {
continue;
}
Image image = texture.getImage();
if (image == null) {
continue;
}
int textureId = image.getId();
if (textureId == -1) {
textureId = 0;
}
texturesSortId = texturesSortId * 23 + textureId;
}
sortingId |= texturesSortId & 0xFFFF;
}
return sortingId;
}
use of com.jme3.shader.Shader 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.shader.Shader 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.shader.Shader in project jmonkeyengine by jMonkeyEngine.
the class Technique method render.
/**
* Render the technique according to its {@link TechniqueDefLogic}.
*
* @param renderManager The render manager to perform the rendering against.
* @param shader The shader that was selected in
* {@link #makeCurrent(com.jme3.renderer.RenderManager, java.util.EnumSet)}.
* @param geometry The geometry to render
* @param lights Lights which influence the geometry.
*/
void render(RenderManager renderManager, Shader shader, Geometry geometry, LightList lights, int lastTexUnit) {
TechniqueDefLogic logic = def.getLogic();
logic.render(renderManager, shader, geometry, lights, lastTexUnit);
}
use of com.jme3.shader.Shader in project jmonkeyengine by jMonkeyEngine.
the class TechniqueDef method loadShader.
private Shader loadShader(AssetManager assetManager, EnumSet<Caps> rendererCaps, DefineList defines) {
StringBuilder sb = new StringBuilder();
sb.append(shaderPrologue);
defines.generateSource(sb, defineNames, defineTypes);
String definesSourceCode = sb.toString();
Shader shader;
if (isUsingShaderNodes()) {
ShaderGenerator shaderGenerator = assetManager.getShaderGenerator(rendererCaps);
if (shaderGenerator == null) {
throw new UnsupportedOperationException("ShaderGenerator was not initialized, " + "make sure assetManager.getGenerator(caps) has been called");
}
shaderGenerator.initialize(this);
shader = shaderGenerator.generateShader(definesSourceCode);
} else {
shader = new Shader();
for (ShaderType type : ShaderType.values()) {
String language = shaderLanguages.get(type);
String shaderSourceAssetName = shaderNames.get(type);
if (language == null || shaderSourceAssetName == null) {
continue;
}
String shaderSourceCode = (String) assetManager.loadAsset(shaderSourceAssetName);
shader.addSource(type, shaderSourceAssetName, shaderSourceCode, definesSourceCode, language);
}
}
if (getWorldBindings() != null) {
for (UniformBinding binding : getWorldBindings()) {
shader.addUniformBinding(binding);
}
}
return shader;
}
Aggregations