Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UBO/SSBO Improvements, Structs, BufferObject and sub data update #1782

Merged
merged 4 commits into from
Jan 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions jme-angle/src/native/angle
Submodule angle added at 231960
148 changes: 82 additions & 66 deletions jme3-core/src/main/java/com/jme3/material/Material.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2009-2021 jMonkeyEngine
* Copyright (c) 2009-2024 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
Expand Down Expand Up @@ -47,6 +47,7 @@
import com.jme3.renderer.queue.RenderQueue.Bucket;
import com.jme3.scene.Geometry;
import com.jme3.shader.*;
import com.jme3.shader.bufferobject.BufferObject;
import com.jme3.texture.Image;
import com.jme3.texture.Texture;
import com.jme3.texture.image.ColorSpace;
Expand Down Expand Up @@ -87,6 +88,16 @@ public class Material implements CloneableSmartAsset, Cloneable, Savable {
private boolean receivesShadows = false;
private int sortingId = -1;

/**
* Track bind ids for textures and buffers
* Used internally
*/
public static class BindUnits {
public int textureUnit = 0;
public int bufferUnit = 0;
}
private BindUnits bindUnits = new BindUnits();

public Material(MaterialDef def) {
if (def == null) {
throw new IllegalArgumentException("Material definition cannot be null");
Expand Down Expand Up @@ -506,6 +517,18 @@ public void setParam(String name, VarType type, Object value) {
}
}

/**
* Pass a parameter to the material shader.
*
* @param name the name of the parameter defined in the material definition (j3md)
* @param value the value of the parameter
*/
public void setParam(String name, Object value) {
MatParam p = getMaterialDef().getMaterialParam(name);
setParam(name, p.getVarType(), value);
}


/**
* Clear a parameter from this material. The parameter must exist
* @param name the name of the parameter to clear
Expand Down Expand Up @@ -685,8 +708,7 @@ public void setColor(String name, ColorRGBA value) {
* @param value the buffer object.
*/
public void setUniformBufferObject(final String name, final BufferObject value) {
value.setBufferType(BufferObject.BufferType.UniformBufferObject);
setParam(name, VarType.BufferObject, value);
setParam(name, VarType.UniformBufferObject, value);
}

/**
Expand All @@ -696,8 +718,7 @@ public void setUniformBufferObject(final String name, final BufferObject value)
* @param value the buffer object.
*/
public void setShaderStorageBufferObject(final String name, final BufferObject value) {
value.setBufferType(BufferObject.BufferType.ShaderStorageBufferObject);
setParam(name, VarType.BufferObject, value);
setParam(name, VarType.ShaderStorageBufferObject, value);
}

/**
Expand Down Expand Up @@ -797,7 +818,7 @@ public void selectTechnique(String name, final RenderManager renderManager) {
sortingId = -1;
}

private int applyOverrides(Renderer renderer, Shader shader, SafeArrayList<MatParamOverride> overrides, int unit) {
private void applyOverrides(Renderer renderer, Shader shader, SafeArrayList<MatParamOverride> overrides, BindUnits bindUnits) {
for (MatParamOverride override : overrides.getArray()) {
VarType type = override.getVarType();

Expand All @@ -810,85 +831,80 @@ private int applyOverrides(Renderer renderer, Shader shader, SafeArrayList<MatPa
Uniform uniform = shader.getUniform(override.getPrefixedName());

if (override.getValue() != null) {
if (type.isTextureType()) {
try {
renderer.setTexture(unit, (Texture) override.getValue());
} catch (TextureUnitException exception) {
int numTexParams = unit + 1;
String message = "Too many texture parameters ("
+ numTexParams + ") assigned\n to " + toString();
throw new IllegalStateException(message);
}
uniform.setValue(VarType.Int, unit);
unit++;
} else {
uniform.setValue(type, override.getValue());
}
updateShaderMaterialParameter(renderer, type, shader, override, bindUnits, true);
} else {
uniform.clearValue();
}
}
return unit;
}

private int updateShaderMaterialParameters(Renderer renderer, Shader shader,
SafeArrayList<MatParamOverride> worldOverrides, SafeArrayList<MatParamOverride> forcedOverrides) {

int unit = 0;
private void updateShaderMaterialParameter(Renderer renderer, VarType type, Shader shader, MatParam param, BindUnits unit, boolean override) {
if (type == VarType.UniformBufferObject || type == VarType.ShaderStorageBufferObject) {
ShaderBufferBlock bufferBlock = shader.getBufferBlock(param.getPrefixedName());
BufferObject bufferObject = (BufferObject) param.getValue();

ShaderBufferBlock.BufferType btype;
if (type == VarType.ShaderStorageBufferObject) {
btype = ShaderBufferBlock.BufferType.ShaderStorageBufferObject;
bufferBlock.setBufferObject(btype, bufferObject);
renderer.setShaderStorageBufferObject(unit.bufferUnit, bufferObject); // TODO: probably not needed
} else {
btype = ShaderBufferBlock.BufferType.UniformBufferObject;
bufferBlock.setBufferObject(btype, bufferObject);
renderer.setUniformBufferObject(unit.bufferUnit, bufferObject); // TODO: probably not needed
}
unit.bufferUnit++;
} else {
Uniform uniform = shader.getUniform(param.getPrefixedName());
if (!override && uniform.isSetByCurrentMaterial()) return;

if (type.isTextureType()) {
try {
renderer.setTexture(unit.textureUnit, (Texture) param.getValue());
} catch (TextureUnitException exception) {
int numTexParams = unit.textureUnit + 1;
String message = "Too many texture parameters (" + numTexParams + ") assigned\n to " + toString();
throw new IllegalStateException(message);
}
uniform.setValue(VarType.Int, unit.textureUnit);
unit.textureUnit++;
} else {
uniform.setValue(type, param.getValue());
}
}
}




private BindUnits updateShaderMaterialParameters(Renderer renderer, Shader shader, SafeArrayList<MatParamOverride> worldOverrides,
SafeArrayList<MatParamOverride> forcedOverrides) {

bindUnits.textureUnit = 0;
bindUnits.bufferUnit = 0;

if (worldOverrides != null) {
unit = applyOverrides(renderer, shader, worldOverrides, unit);
applyOverrides(renderer, shader, worldOverrides, bindUnits);
}
if (forcedOverrides != null) {
unit = applyOverrides(renderer, shader, forcedOverrides, unit);
applyOverrides(renderer, shader, forcedOverrides, bindUnits);
}

for (int i = 0; i < paramValues.size(); i++) {

MatParam param = paramValues.getValue(i);
VarType type = param.getVarType();

if (isBO(type)) {

final ShaderBufferBlock bufferBlock = shader.getBufferBlock(param.getPrefixedName());
bufferBlock.setBufferObject((BufferObject) param.getValue());

} else {

Uniform uniform = shader.getUniform(param.getPrefixedName());
if (uniform.isSetByCurrentMaterial()) {
continue;
}

if (type.isTextureType()) {
try {
renderer.setTexture(unit, (Texture) param.getValue());
} catch (TextureUnitException exception) {
int numTexParams = unit + 1;
String message = "Too many texture parameters ("
+ numTexParams + ") assigned\n to " + toString();
throw new IllegalStateException(message);
}
uniform.setValue(VarType.Int, unit);
unit++;
} else {
uniform.setValue(type, param.getValue());
}
}
updateShaderMaterialParameter(renderer, type, shader, param, bindUnits, false);
}

//TODO HACKY HACK remove this when texture unit is handled by the uniform.
return unit;
// TODO HACKY HACK remove this when texture unit is handled by the
// uniform.
return bindUnits;
}

/**
* Returns true if the type is Buffer Object's type.
*
* @param type the material parameter type.
* @return true if the type is Buffer Object's type.
*/
private boolean isBO(final VarType type) {
return type == VarType.BufferObject;
}


private void updateRenderState(Geometry geometry, RenderManager renderManager, Renderer renderer, TechniqueDef techniqueDef) {
if (renderManager.getForcedRenderState() != null) {
Expand Down Expand Up @@ -1064,13 +1080,13 @@ public void render(Geometry geometry, LightList lights, RenderManager renderMana
renderManager.updateUniformBindings(shader);

// Set material parameters
int unit = updateShaderMaterialParameters(renderer, shader, overrides, renderManager.getForcedMatParams());
BindUnits units = 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);
technique.render(renderManager, shader, geometry, lights, units);
}

/**
Expand Down
7 changes: 4 additions & 3 deletions jme3-core/src/main/java/com/jme3/material/Technique.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2009-2021 jMonkeyEngine
* Copyright (c) 2009-2024 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
Expand Down Expand Up @@ -33,6 +33,7 @@

import com.jme3.asset.AssetManager;
import com.jme3.light.LightList;
import com.jme3.material.Material.BindUnits;
import com.jme3.material.TechniqueDef.LightMode;
import com.jme3.material.logic.TechniqueDefLogic;
import com.jme3.renderer.Caps;
Expand Down Expand Up @@ -162,9 +163,9 @@ Shader makeCurrent(RenderManager renderManager, SafeArrayList<MatParamOverride>
* @param lights Lights which influence the geometry.
* @param lastTexUnit the index of the most recently used texture unit
*/
void render(RenderManager renderManager, Shader shader, Geometry geometry, LightList lights, int lastTexUnit) {
void render(RenderManager renderManager, Shader shader, Geometry geometry, LightList lights, BindUnits lastBindUnits) {
TechniqueDefLogic logic = def.getLogic();
logic.render(renderManager, shader, geometry, lights, lastTexUnit);
logic.render(renderManager, shader, geometry, lights, lastBindUnits);
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2009-2021 jMonkeyEngine
* Copyright (c) 2009-2024 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
Expand Down Expand Up @@ -34,6 +34,7 @@
import com.jme3.asset.AssetManager;
import com.jme3.light.*;
import com.jme3.material.TechniqueDef;
import com.jme3.material.Material.BindUnits;
import com.jme3.math.ColorRGBA;
import com.jme3.renderer.Caps;
import com.jme3.renderer.RenderManager;
Expand Down Expand Up @@ -91,7 +92,7 @@ protected static ColorRGBA getAmbientColor(LightList lightList, boolean removeLi


@Override
public void render(RenderManager renderManager, Shader shader, Geometry geometry, LightList lights, int lastTexUnit) {
public void render(RenderManager renderManager, Shader shader, Geometry geometry, LightList lights, BindUnits lastBindUnits) {
Renderer renderer = renderManager.getRenderer();
renderer.setShader(shader);
renderMeshFromGeometry(renderer, geometry);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2009-2021 jMonkeyEngine
* Copyright (c) 2009-2024 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
Expand Down Expand Up @@ -38,6 +38,7 @@
import com.jme3.light.SpotLight;
import com.jme3.material.RenderState;
import com.jme3.material.TechniqueDef;
import com.jme3.material.Material.BindUnits;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Quaternion;
import com.jme3.math.Vector3f;
Expand Down Expand Up @@ -67,7 +68,7 @@ public MultiPassLightingLogic(TechniqueDef techniqueDef) {
}

@Override
public void render(RenderManager renderManager, Shader shader, Geometry geometry, LightList lights, int lastTexUnit) {
public void render(RenderManager renderManager, Shader shader, Geometry geometry, LightList lights, BindUnits lastBindUnits) {
Renderer r = renderManager.getRenderer();
Uniform lightDir = shader.getUniform("g_LightDirection");
Uniform lightColor = shader.getUniform("g_LightColor");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2009-2021 jMonkeyEngine
* Copyright (c) 2009-2024 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
Expand Down Expand Up @@ -34,6 +34,7 @@
import com.jme3.asset.AssetManager;
import com.jme3.light.*;
import com.jme3.material.*;
import com.jme3.material.Material.BindUnits;
import com.jme3.material.RenderState.BlendMode;
import com.jme3.math.*;
import com.jme3.renderer.*;
Expand Down Expand Up @@ -262,17 +263,17 @@ private int setProbeData(RenderManager rm, int lastTexUnit, Uniform lightProbeDa
}

@Override
public void render(RenderManager renderManager, Shader shader, Geometry geometry, LightList lights, int lastTexUnit) {
public void render(RenderManager renderManager, Shader shader, Geometry geometry, LightList lights, BindUnits lastBindUnits) {
int nbRenderedLights = 0;
Renderer renderer = renderManager.getRenderer();
int batchSize = renderManager.getSinglePassLightBatchSize();
if (lights.size() == 0) {
updateLightListUniforms(shader, geometry, lights,batchSize, renderManager, 0, lastTexUnit);
updateLightListUniforms(shader, geometry, lights, batchSize, renderManager, 0, lastBindUnits.textureUnit);
renderer.setShader(shader);
renderMeshFromGeometry(renderer, geometry);
} else {
while (nbRenderedLights < lights.size()) {
nbRenderedLights = updateLightListUniforms(shader, geometry, lights, batchSize, renderManager, nbRenderedLights, lastTexUnit);
nbRenderedLights = updateLightListUniforms(shader, geometry, lights, batchSize, renderManager, nbRenderedLights, lastBindUnits.textureUnit);
renderer.setShader(shader);
renderMeshFromGeometry(renderer, geometry);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2009-2021 jMonkeyEngine
* Copyright (c) 2009-2024 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
Expand Down Expand Up @@ -40,6 +40,7 @@
import com.jme3.material.RenderState;
import com.jme3.material.RenderState.BlendMode;
import com.jme3.material.TechniqueDef;
import com.jme3.material.Material.BindUnits;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector3f;
import com.jme3.math.Vector4f;
Expand Down Expand Up @@ -206,7 +207,7 @@ protected int updateLightListUniforms(Shader shader, Geometry g, LightList light
}

@Override
public void render(RenderManager renderManager, Shader shader, Geometry geometry, LightList lights, int lastTexUnit) {
public void render(RenderManager renderManager, Shader shader, Geometry geometry, LightList lights, BindUnits lastBindUnits) {
int nbRenderedLights = 0;
Renderer renderer = renderManager.getRenderer();
int batchSize = renderManager.getSinglePassLightBatchSize();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2009-2021 jMonkeyEngine
* Copyright (c) 2009-2024 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
Expand Down Expand Up @@ -38,6 +38,7 @@
import com.jme3.light.PointLight;
import com.jme3.light.SpotLight;
import com.jme3.material.TechniqueDef;
import com.jme3.material.Material.BindUnits;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Matrix4f;
import com.jme3.math.Vector3f;
Expand Down Expand Up @@ -171,7 +172,7 @@ private void updateLightListUniforms(Matrix4f viewMatrix, Shader shader, LightLi
}

@Override
public void render(RenderManager renderManager, Shader shader, Geometry geometry, LightList lights, int lastTexUnit) {
public void render(RenderManager renderManager, Shader shader, Geometry geometry, LightList lights, BindUnits lastBindUnits) {
Renderer renderer = renderManager.getRenderer();
Matrix4f viewMatrix = renderManager.getCurrentCamera().getViewMatrix();
updateLightListUniforms(viewMatrix, shader, lights);
Expand Down
Loading
Loading