Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
main.io.github.seba244c.icespire.graphics.ShaderProgram Maven / Gradle / Ivy
package io.github.seba244c.icespire.graphics;
import static org.lwjgl.opengl.GL20.*;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import org.joml.Matrix4f;
import org.joml.Vector3f;
import org.joml.Vector4f;
import org.lwjgl.system.MemoryStack;
import io.github.seba244c.icespire.graphics.lighting.DirectionalLight;
import io.github.seba244c.icespire.graphics.lighting.PointLight;
import io.github.seba244c.icespire.graphics.lighting.SpotLight;
import io.github.seba244c.icespire.utils.LoggingUtils;
/**
* Controls the shaders of games
* @author Sebsa
* @since 1.0.2
*/
public class ShaderProgram {
private final int programId;
private int vertexShaderId;
private int fragmentShaderId;
private final Map uniforms;
public ShaderProgram() throws Exception {
LoggingUtils.infoLog("ShaderProgram", "Creating the Shader");
programId = glCreateProgram();
if (programId == 0) {
LoggingUtils.errorLog("ShaderProgram", "Could not create the shader");
throw new IllegalStateException("[ShaderProgram.java] Could not create Shader");
}
uniforms = new HashMap<>();
}
public void createUniform(String uniformName) throws Exception {
LoggingUtils.debugLog("ShaderProgram", "createUniform", "Creating uniform: "+uniformName);
int uniformLocation = glGetUniformLocation(programId, uniformName);
if (uniformLocation < 0) {
LoggingUtils.errorLog("ShaderProgram", "createUniform", "Could not find uniform:"+uniformName);
throw new IllegalArgumentException("[ShaderProgram.java/createUniform] Could not find uniform:" + uniformName);
}
uniforms.put(uniformName, uniformLocation);
}
public void createPointLightListUniform(String uniformName, int size) throws Exception {
for (int i = 0; i < size; i++) {
createPointLightUniform(uniformName + "[" + i + "]");
}
}
public void createPointLightUniform(String uniformName) throws Exception {
createUniform(uniformName + ".colour");
createUniform(uniformName + ".position");
createUniform(uniformName + ".intensity");
createUniform(uniformName + ".att.constant");
createUniform(uniformName + ".att.linear");
createUniform(uniformName + ".att.exponent");
}
public void createSpotLightListUniform(String uniformName, int size) throws Exception {
for (int i = 0; i < size; i++) {
createSpotLightUniform(uniformName + "[" + i + "]");
}
}
public void createSpotLightUniform(String uniformName) throws Exception {
createPointLightUniform(uniformName + ".pl");
createUniform(uniformName + ".conedir");
createUniform(uniformName + ".cutoff");
}
public void createDirectionalLightUniform(String uniformName) throws Exception {
createUniform(uniformName + ".colour");
createUniform(uniformName + ".direction");
createUniform(uniformName + ".intensity");
}
public void createMaterialUniform(String uniformName) throws Exception {
createUniform(uniformName + ".ambient");
createUniform(uniformName + ".diffuse");
createUniform(uniformName + ".specular");
createUniform(uniformName + ".hasTexture");
createUniform(uniformName + ".reflectance");
}
public void setUniform(String uniformName, Matrix4f value) {
// Dump the matrix into a float buffer
try (MemoryStack stack = MemoryStack.stackPush()) {
glUniformMatrix4fv(uniforms.get(uniformName), false,
value.get(stack.mallocFloat(16)));
}
}
public void setUniform(String uniformName, int value) {
glUniform1i(uniforms.get(uniformName), value);
}
public void setUniform(String uniformName, float value) {
glUniform1f(uniforms.get(uniformName), value);
}
public void setUniform(String uniformName, Vector3f value) {
glUniform3f(uniforms.get(uniformName), value.x, value.y, value.z);
}
public void setUniform(String uniformName, Vector4f value) {
glUniform4f(uniforms.get(uniformName), value.x, value.y, value.z, value.w);
}
public void setUniform(String uniformName, PointLight[] pointLights) {
int numLights = pointLights != null ? pointLights.length : 0;
for (int i = 0; i < numLights; i++) {
setUniform(uniformName, pointLights[i], i);
}
}
public void setUniform(String uniformName, PointLight pointLight, int pos) {
setUniform(uniformName + "[" + pos + "]", pointLight);
}
public void setUniform(String uniformName, PointLight pointLight) {
setUniform(uniformName + ".colour", pointLight.getColor());
setUniform(uniformName + ".position", pointLight.getPosition());
setUniform(uniformName + ".intensity", pointLight.getIntensity());
PointLight.Attenuation att = pointLight.getAttenuation();
setUniform(uniformName + ".att.constant", att.getConstant());
setUniform(uniformName + ".att.linear", att.getLinear());
setUniform(uniformName + ".att.exponent", att.getExponent());
}
public void setUniform(String uniformName, SpotLight[] spotLights) {
int numLights = spotLights != null ? spotLights.length : 0;
for (int i = 0; i < numLights; i++) {
setUniform(uniformName, spotLights[i], i);
}
}
public void setUniform(String uniformName, SpotLight spotLight, int pos) {
setUniform(uniformName + "[" + pos + "]", spotLight);
}
public void setUniform(String uniformName, SpotLight spotLight) {
setUniform(uniformName + ".pl", spotLight.getPointLight());
setUniform(uniformName + ".conedir", spotLight.getConeDirection());
setUniform(uniformName + ".cutoff", spotLight.getCutOff());
}
public void setUniform(String uniformName, DirectionalLight dirLight) {
setUniform(uniformName + ".colour", dirLight.getColor());
setUniform(uniformName + ".direction", dirLight.getDirection());
setUniform(uniformName + ".intensity", dirLight.getIntensity());
}
public void setUniform(String uniformName, Material material) {
setUniform(uniformName + ".ambient", material.getAmbientColour());
setUniform(uniformName + ".diffuse", material.getDiffuseColour());
setUniform(uniformName + ".specular", material.getSpecularColour());
setUniform(uniformName + ".hasTexture", material.isTextured() ? 1 : 0);
setUniform(uniformName + ".reflectance", material.getReflectance());
}
public void createVertexShader(String shaderCode) throws Exception {
vertexShaderId = createShader(shaderCode, GL_VERTEX_SHADER);
}
public void createFragmentShader(String shaderCode) throws Exception {
fragmentShaderId = createShader(shaderCode, GL_FRAGMENT_SHADER);
}
protected int createShader(String shaderCode, int shaderType) throws Exception {
LoggingUtils.infoLog("ShaderProgram", "createShader", "Creating Shader with type: " + shaderType);
int shaderId = glCreateShader(shaderType);
if (shaderId == 0) {
throw new IllegalStateException("[ShaderProgram.java/createShader] Error creating shader. Type: " + shaderType);
}
glShaderSource(shaderId, shaderCode);
glCompileShader(shaderId);
if (glGetShaderi(shaderId, GL_COMPILE_STATUS) == 0) {
throw new IOException("[ShaderProgram.java/createShader] Error compiling Shader code: " + glGetShaderInfoLog(shaderId, 1024));
}
glAttachShader(programId, shaderId);
return shaderId;
}
public void link() throws Exception {
LoggingUtils.infoLog("ShaderProgram", "link", "Linking the ShaderProgram");
glLinkProgram(programId);
if (glGetProgrami(programId, GL_LINK_STATUS) == 0) {
throw new UnknownError("[ShaderProgram.java/link] Error linking Shader code: " + glGetProgramInfoLog(programId, 1024));
}
if (vertexShaderId != 0) {
glDetachShader(programId, vertexShaderId);
}
if (fragmentShaderId != 0) {
glDetachShader(programId, fragmentShaderId);
}
glValidateProgram(programId);
if (glGetProgrami(programId, GL_VALIDATE_STATUS) == 0) {
LoggingUtils.errorLog("ShaderProgram", "link", "Warning validating Shader code: " + glGetProgramInfoLog(programId, 1024));
}
}
public void bind() {
glUseProgram(programId);
}
public void unbind() {
glUseProgram(0);
}
public void cleanup() {
LoggingUtils.infoLog("ShaderProgram", "cleanup", "Cleaning up the ShaderProgram");
unbind();
if (programId != 0) {
LoggingUtils.infoLog("ShaderProgram", "cleanup", "Deleting ShaderProgram");
glDeleteProgram(programId);
}
}
}