142 lines
2.6 KiB
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;
|
|
}
|
|
}
|
|
}
|