SimpleJavaEngine/src/main/java/speiger/src/coreengine/rendering/shader/ShaderTracker.java

142 lines
2.6 KiB
Java

package speiger.src.coreengine.rendering.shader;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Supplier;
import org.lwjgl.opengl.GL20;
import speiger.src.collections.objects.lists.ObjectArrayList;
import speiger.src.coreengine.assets.AssetManager;
import speiger.src.coreengine.assets.reloader.IReloadableResource;
public class ShaderTracker implements IReloadableResource
{
public static final ShaderTracker INSTANCE = new ShaderTracker();
List<ReloadReference<?>> programs = new ObjectArrayList<>();
int activeShader = 0;
boolean reloading = false;
AssetManager assets;
public void init(AssetManager assets)
{
this.assets = assets;
}
public <T extends ShaderProgram> T register(Supplier<T> creator, Consumer<T> reloader)
{
T result = creator.get();
result.init();
programs.add(new ReloadReference<>(result, creator, reloader));
return result;
}
protected AssetManager getAssets()
{
return assets;
}
void startNextShader(ShaderProgram shader)
{
if(shader.getShaderID() == activeShader)
{
return;
}
activeShader = shader.getShaderID();
GL20.glUseProgram(activeShader);
}
void stopShader(ShaderProgram shader)
{
if(activeShader == 0)
{
return;
}
activeShader = 0;
GL20.glUseProgram(activeShader);
}
public void stopShader()
{
if(activeShader == 0)
{
return;
}
activeShader = 0;
GL20.glUseProgram(activeShader);
}
public boolean isShaderActive()
{
return activeShader > 0;
}
@Override
public void reload()
{
for(int i = 0,m = programs.size();i<m;i++)
{
programs.get(i).reload();
}
}
@Override
public void destroy()
{
reloading = true;
for(int i = 0,m = programs.size();i<m;i++)
{
programs.get(i).destroy();
}
programs.clear();
reloading = false;
}
class ReloadReference<T extends ShaderProgram>
{
T program;
Supplier<T> creator;
Consumer<T> listener;
public ReloadReference(T value, Supplier<T> creator, Consumer<T> listener)
{
this.program = value;
this.creator = creator;
this.listener = listener;
program.setReference(this);
}
private void destroy()
{
if(program == null || reloading)
{
return;
}
program.removeShader();
program = null;
listener.accept(null);
}
public void removeReference()
{
destroy();
if(reloading)
{
return;
}
programs.remove(this);
}
public void reload()
{
reloading = true;
program.removeShader();
program = creator.get();
program.init();
program.setReference(this);
listener.accept(program);
reloading = false;
}
}
}