SimpleJavaEngine/src/main/java/speiger/src/coreengine/rendering/shaderOld/ShaderProgram.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;
}
}