110 lines
3.0 KiB
Java
110 lines
3.0 KiB
Java
package speiger.src.coreengine.rendering.shaderOld;
|
|
|
|
import java.util.List;
|
|
|
|
import org.lwjgl.opengl.GL20;
|
|
|
|
import speiger.src.collections.objects.lists.ObjectArrayList;
|
|
import speiger.src.coreengine.assets.AssetLocation;
|
|
import speiger.src.coreengine.assets.base.IAsset;
|
|
import speiger.src.coreengine.rendering.shaderOld.ShaderTracker.ReloadReference;
|
|
import speiger.src.coreengine.rendering.shaderOld.uniforms.Uniform;
|
|
import speiger.src.coreengine.utils.collections.iterators.IterableWrapper;
|
|
import speiger.src.coreengine.utils.io.GameLog;
|
|
|
|
public abstract class ShaderProgram
|
|
{
|
|
protected List<Uniform> localUniforms = new ObjectArrayList<>();
|
|
ReloadReference<?> reference;
|
|
private int shaderID;
|
|
|
|
protected ShaderProgram(AssetLocation vertex, AssetLocation fragment, String[] attributes) {
|
|
int vertexID = loadShader(vertex, GL20.GL_VERTEX_SHADER);
|
|
int fragmentID = loadShader(fragment, GL20.GL_FRAGMENT_SHADER);
|
|
if(vertexID == -1 || fragmentID == -1) {
|
|
shaderID = 0;
|
|
return;
|
|
}
|
|
shaderID = GL20.glCreateProgram();
|
|
GL20.glAttachShader(shaderID, vertexID);
|
|
GL20.glAttachShader(shaderID, fragmentID);
|
|
for(int i = 0;i < attributes.length;i++) {
|
|
GL20.glBindAttribLocation(shaderID, i, attributes[i]);
|
|
}
|
|
GL20.glLinkProgram(shaderID);
|
|
GL20.glDetachShader(shaderID, vertexID);
|
|
GL20.glDetachShader(shaderID, fragmentID);
|
|
GL20.glDeleteShader(vertexID);
|
|
GL20.glDeleteShader(fragmentID);
|
|
}
|
|
|
|
public void addUniforms(Uniform... uniforms) {
|
|
for(Uniform uni : uniforms) {
|
|
uni.loadUniform(this);
|
|
localUniforms.add(uni);
|
|
}
|
|
GL20.glValidateProgram(shaderID);
|
|
}
|
|
|
|
void setReference(ReloadReference<?> ref) {
|
|
reference = ref;
|
|
}
|
|
|
|
public abstract ShaderProgram init();
|
|
|
|
public boolean isShaderValid() {
|
|
return shaderID != 0;
|
|
}
|
|
|
|
public int getShaderID() {
|
|
return shaderID;
|
|
}
|
|
|
|
public void startShader() {
|
|
ShaderTracker.INSTANCE.startNextShader(this);
|
|
}
|
|
|
|
public void stopShader() {
|
|
ShaderTracker.INSTANCE.stopShader(this);
|
|
}
|
|
|
|
public boolean isShaderRunning() {
|
|
return ShaderTracker.INSTANCE.activeShader == getShaderID();
|
|
}
|
|
|
|
public void removeShader() {
|
|
if(shaderID == 0) return;
|
|
stopShader();
|
|
GL20.glDeleteProgram(shaderID);
|
|
shaderID = 0;
|
|
reference.removeReference();
|
|
reference = null;
|
|
}
|
|
|
|
private int loadShader(AssetLocation location, int type) {
|
|
StringBuilder shaderSource = new StringBuilder();
|
|
try(IAsset asset = ShaderTracker.INSTANCE.getAssets().getAsset(location)) {
|
|
for(String s : IterableWrapper.wrap(asset.reader()))
|
|
{
|
|
if(s.startsWith("//")) continue;
|
|
shaderSource.append(s).append("\n");
|
|
}
|
|
}
|
|
catch(Exception e) {
|
|
e.printStackTrace();
|
|
return -1;
|
|
}
|
|
int shaderID = GL20.glCreateShader(type);
|
|
GL20.glShaderSource(shaderID, shaderSource);
|
|
GL20.glCompileShader(shaderID);
|
|
if(GL20.glGetShaderi(shaderID, GL20.GL_COMPILE_STATUS) == 0) {
|
|
GameLog.warn("Could not compile shader " + location);
|
|
int[] length = new int[1];
|
|
GL20.glGetShaderiv(shaderID, GL20.GL_INFO_LOG_LENGTH, length);
|
|
GameLog.error(GL20.glGetShaderInfoLog(shaderID, length[0]));
|
|
return -1;
|
|
}
|
|
return shaderID;
|
|
}
|
|
}
|