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, , 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); } }