Renderer/src/main/java/electrosphere/renderer/light/LightManager.java
austin 05c51896e0
Some checks failed
studiorailgun/Renderer/pipeline/head There was a failure building this commit
more accurate opengl error tracking
2024-08-28 16:09:53 -04:00

294 lines
9.8 KiB
Java

package electrosphere.renderer.light;
import static org.lwjgl.opengl.GL15.*;
import static org.lwjgl.opengl.GL31.GL_UNIFORM_BUFFER;
import java.nio.ByteBuffer;
import org.joml.Vector3f;
import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.GL30;
import org.lwjgl.opengl.GL31;
import electrosphere.engine.Globals;
import electrosphere.entity.types.camera.CameraEntityUtils;
import electrosphere.logger.LoggerInterface;
import electrosphere.renderer.OpenGLState;
import electrosphere.renderer.shader.ShaderProgram;
/**
* Manages the light sources in the engine
*/
public class LightManager {
final static int BIND_POINT = 1;
final static int POINT_LIGHT_COUNT = 10;
final static int BUFFER_SIZE = 1184;
int uboIndex;
ByteBuffer dataBuffer;
//sun position (For shadow maps)
Vector3f sunPosition = new Vector3f(0.2f,-1.0f,0.3f);
//lights
DirectionalLight directionalLight;
PointLight[] pointLights;
public LightManager(){
//create data buffer
dataBuffer = BufferUtils.createByteBuffer(BUFFER_SIZE);
uboIndex = glGenBuffers();
glBindBuffer(GL_UNIFORM_BUFFER, uboIndex);
glBufferData(GL_UNIFORM_BUFFER, BUFFER_SIZE, GL_DYNAMIC_DRAW); // allocate 152 bytes of memory
//set range to full size
int offset = 0;
GL30.glBindBufferRange(GL_UNIFORM_BUFFER, BIND_POINT, uboIndex, offset, BUFFER_SIZE);
//unbind
glBindBuffer(GL_UNIFORM_BUFFER, 0);
//create directional light
directionalLight = new DirectionalLight(new Vector3f(1,-1,0).normalize());
directionalLight.setAmbient(new Vector3f(0.6f,0.6f,0.6f));
directionalLight.setDiffuse(new Vector3f(0.3f,0.3f,0.3f));
directionalLight.setDirection(sunPosition);
directionalLight.setSpecular(new Vector3f(0.0f,0.0f,0.0f));
pointLights = new PointLight[POINT_LIGHT_COUNT];
for(int i = 0; i < POINT_LIGHT_COUNT; i++){
pointLights[i] = new PointLight(new Vector3f(0,0,0),new Vector3f(0,0,0));
}
pointLights[0].setAmbient(new Vector3f(0.924500f, 0.369800f, 0.092450f));
pointLights[0].setConstant(1.0f);
pointLights[0].setDiffuse(new Vector3f(0.924500f, 0.369800f, 0.092450f));
pointLights[0].setLinear(0.7f);
pointLights[0].setPosition(new Vector3f(1.0f,0.05f,1.0f));
pointLights[0].setQuadratic(1.8f);
pointLights[0].setSpecular(new Vector3f(0.0f,0.0f,0.0f));
// pointLights[0].setAmbient(new Vector3f(0.924500f, 0.369800f, 0.092450f));
// pointLights[0].setConstant(1.0f);
// pointLights[0].setDiffuse(new Vector3f(0.924500f, 0.369800f, 0.092450f));
// pointLights[0].setLinear(0.09f);
// pointLights[0].setPosition(new Vector3f(1.0f,0.05f,1.0f));
// pointLights[0].setQuadratic(0.032f);
// pointLights[0].setSpecular(new Vector3f(0.0f,0.0f,0.0f));
/*
Vector3f lightLoc = new Vector3f(0.2f,-1.0f,0.3f);
float temp[] = new float[3];
temp[0] = lightLoc.x;
temp[1] = lightLoc.y;
temp[2] = lightLoc.z;
glUniform3fv(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "dirLight.direction"), temp);
temp[0] = 0.4f;
temp[1] = 0.4f;
temp[2] = 0.4f;
glUniform3fv(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "dirLight.ambient"), temp);
temp[0] = 0.3f;
temp[1] = 0.3f;
temp[2] = 0.3f;
glUniform3fv(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "dirLight.diffuse"), temp);
temp[0] = 0.1f;
temp[1] = 0.1f;
temp[2] = 0.1f;
glUniform3fv(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "dirLight.specular"), temp);
temp[0] = 32f;
*/
//glBufferData(GL_UNIFORM_BUFFER, <my_data>, GL_STATIC_DRAW);
}
//
//
// HIGHER ORDER OBJECT MANIPULATION
//
//
public void setPointLight(PointLight light, int index){
pointLights[index] = light;
}
/**
* Gets the directional light for this light manager
* @return the directional light
*/
public DirectionalLight getDirectionalLight(){
return this.directionalLight;
}
//
//
// BUFFER MANAGEMENT
//
//
/**
* Call in each mesh / per each shader
* @param shaderIndex
*/
public void bindBuffer(OpenGLState openGLState){
//get position of lights object in shader
int bufferIndex = GL31.glGetUniformBlockIndex(openGLState.getActiveShader().getShaderId(), "Lights");
Globals.renderingEngine.checkError();
if(bufferIndex == ShaderProgram.INVALID_UNIFORM_NAME){
LoggerInterface.loggerRenderer.INFO("Tried to buffer light manager to shader that does not have it active.");
} else {
//bind that position to the slot '2'
GL31.glUniformBlockBinding(openGLState.getActiveShader().getShaderId(), bufferIndex, BIND_POINT);
Globals.renderingEngine.checkError();
//bind our buffer to slot '2' as well
GL31.glBindBufferBase(GL_UNIFORM_BUFFER, BIND_POINT, uboIndex);
Globals.renderingEngine.checkError();
}
//alternatively if want to use range, do glBindBufferRange(GL_UNIFORM_BUFFER, 2, uboExampleBlock, 0, 152);
// Globals.renderingEngine.checkError();
}
/**
* Call once per render loop to set buffer values
*/
public void updateData(){
putDataInBuffer();
bufferData();
}
void bufferData(){
glBindBuffer(GL_UNIFORM_BUFFER, uboIndex);
// int offset = 0;
glBufferData(GL_UNIFORM_BUFFER, dataBuffer, GL_DYNAMIC_DRAW);
// glBufferSubData(GL_UNIFORM_BUFFER, offset, dataBuffer);
glBindBuffer(GL_UNIFORM_BUFFER, 0);
}
void putDataInBuffer(){
//implicitly flips
dataBuffer.clear();
//direct light
//vec3 dirLightDirection
dataBuffer.putFloat(directionalLight.direction.x);
dataBuffer.putFloat(directionalLight.direction.y);
dataBuffer.putFloat(directionalLight.direction.z);
dataBuffer.putFloat(0);
//vec3 dirLightAmbient
dataBuffer.putFloat(directionalLight.ambient.x);
dataBuffer.putFloat(directionalLight.ambient.y);
dataBuffer.putFloat(directionalLight.ambient.z);
dataBuffer.putFloat(0);
//vec3 dirLightDiffuse
dataBuffer.putFloat(directionalLight.diffuse.x);
dataBuffer.putFloat(directionalLight.diffuse.y);
dataBuffer.putFloat(directionalLight.diffuse.z);
dataBuffer.putFloat(0);
//vec3 dirLightSpecular
dataBuffer.putFloat(directionalLight.specular.x);
dataBuffer.putFloat(directionalLight.specular.y);
dataBuffer.putFloat(directionalLight.specular.z);
dataBuffer.putFloat(0);
//point light
//vec3 position[10]
//dont sub cam
// for(int i = 0; i < POINT_LIGHT_COUNT; i++){
// PointLight light = pointLights[i];
// dataBuffer.putFloat(light.position.x);
// dataBuffer.putFloat(light.position.y);
// dataBuffer.putFloat(light.position.z);
// dataBuffer.putFloat(0);
// }
//do sub cam
if(Globals.playerCamera != null){
Vector3f cameraPos = CameraEntityUtils.getCameraCenter(Globals.playerCamera);
for(int i = 0; i < POINT_LIGHT_COUNT; i++){
PointLight light = pointLights[i];
dataBuffer.putFloat(light.position.x - cameraPos.x);
dataBuffer.putFloat(light.position.y - cameraPos.y);
dataBuffer.putFloat(light.position.z - cameraPos.z);
dataBuffer.putFloat(0);
}
}
//float constant[10]
for(int i = 0; i < POINT_LIGHT_COUNT; i++){
PointLight light = pointLights[i];
dataBuffer.putFloat(light.constant);
dataBuffer.putFloat(0);
dataBuffer.putFloat(0);
dataBuffer.putFloat(0);
}
//float linear[10]
for(int i = 0; i < POINT_LIGHT_COUNT; i++){
PointLight light = pointLights[i];
dataBuffer.putFloat(light.linear);
dataBuffer.putFloat(0);
dataBuffer.putFloat(0);
dataBuffer.putFloat(0);
}
//float quadratic[10]
for(int i = 0; i < POINT_LIGHT_COUNT; i++){
PointLight light = pointLights[i];
dataBuffer.putFloat(light.quadratic);
dataBuffer.putFloat(0);
dataBuffer.putFloat(0);
dataBuffer.putFloat(0);
}
//vec3 ambient[10]
for(int i = 0; i < POINT_LIGHT_COUNT; i++){
PointLight light = pointLights[i];
dataBuffer.putFloat(light.ambient.x);
dataBuffer.putFloat(light.ambient.y);
dataBuffer.putFloat(light.ambient.z);
dataBuffer.putFloat(0);
}
//vec3 diffuse[10]
for(int i = 0; i < POINT_LIGHT_COUNT; i++){
PointLight light = pointLights[i];
dataBuffer.putFloat(light.diffuse.x);
dataBuffer.putFloat(light.diffuse.y);
dataBuffer.putFloat(light.diffuse.z);
dataBuffer.putFloat(0);
}
//vec3 specular[10]
for(int i = 0; i < POINT_LIGHT_COUNT; i++){
PointLight light = pointLights[i];
dataBuffer.putFloat(light.specular.x);
dataBuffer.putFloat(light.specular.y);
dataBuffer.putFloat(light.specular.z);
dataBuffer.putFloat(0);
}
dataBuffer.flip();
// dataBuffer.position(0);
}
}