Some checks failed
studiorailgun/Renderer/pipeline/head There was a failure building this commit
292 lines
9.3 KiB
Java
292 lines
9.3 KiB
Java
package electrosphere.renderer;
|
|
|
|
import java.util.HashMap;
|
|
import java.util.Map;
|
|
|
|
import org.joml.Vector2i;
|
|
import org.lwjgl.opengl.GL40;
|
|
|
|
import electrosphere.engine.Globals;
|
|
import electrosphere.logger.LoggerInterface;
|
|
import electrosphere.renderer.shader.ShaderProgram;
|
|
|
|
/**
|
|
* Encapsulates the state of opengl.
|
|
* The main function of this class is to sit between any consuming classes and opengl.
|
|
* It can then deduplicate calls based on the state that is already set.
|
|
*/
|
|
public class OpenGLState {
|
|
|
|
//tracks whether caching should be used or not (to deduplicate opengl calls)
|
|
private static final boolean DISABLE_CACHING = false;
|
|
|
|
//the max texture allowed by the current environment
|
|
int MAX_TEXTURE_WIDTH = 0;
|
|
|
|
//the current viewport dimensions
|
|
private Vector2i viewport = new Vector2i(0,0);
|
|
|
|
//whether depth test is enabled or not
|
|
boolean depthTest = false;
|
|
|
|
//the current depth function
|
|
int depthFunction = -1;
|
|
|
|
//whether to blend or nit
|
|
boolean blendTest = false;
|
|
|
|
//the current blend func
|
|
//map is (texture unit) -> [sfactor,dfactor]
|
|
Map<Integer,int[]> blendFuncMap = new HashMap<Integer,int[]>();
|
|
//the key that contains the value of glBlendFunc (which would affect all buffers)
|
|
static final int ALL_BUFFERS_KEY = -1;
|
|
|
|
//the currently active texture
|
|
int activeTexture = 0;
|
|
|
|
//the currently bound framebuffer
|
|
int framebufferType = 0;
|
|
int framebufferPointer = 0;
|
|
|
|
//active shader
|
|
ShaderProgram activeShader = null;
|
|
|
|
//map of texture units and their corresponding texture pointers
|
|
Map<Integer,Integer> unitToPointerMap = new HashMap<Integer,Integer>();
|
|
|
|
|
|
/**
|
|
* Gets the constraints of the current environment (ie how large can the max texture be)
|
|
*/
|
|
public void storeCurrentEnvironmentContraints(){
|
|
|
|
//the array used to store values fetched from opengl
|
|
int[] intFetchArray = new int[1];
|
|
|
|
//get max texture size
|
|
GL40.glGetIntegerv(GL40.GL_MAX_TEXTURE_SIZE, intFetchArray);
|
|
MAX_TEXTURE_WIDTH = intFetchArray[0];
|
|
|
|
|
|
}
|
|
|
|
/**
|
|
* Sets the viewport
|
|
* @param x the width
|
|
* @param y the height
|
|
*/
|
|
public void glViewport(int x, int y){
|
|
if(DISABLE_CACHING || x != viewport.x || y != viewport.y){
|
|
viewport.x = x;
|
|
viewport.y = y;
|
|
GL40.glViewport(0, 0, viewport.x, viewport.y);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Gets the viewport's dimensions
|
|
* @return The viewport's dimensions
|
|
*/
|
|
public Vector2i getViewport(){
|
|
return viewport;
|
|
}
|
|
|
|
/**
|
|
* Sets the depth test
|
|
* @param depthTest the depth test state
|
|
*/
|
|
public void glDepthTest(boolean depthTest){
|
|
// if(this.depthTest != depthTest){
|
|
this.depthTest = depthTest;
|
|
if(this.depthTest){
|
|
GL40.glEnable(GL40.GL_DEPTH_TEST);
|
|
} else {
|
|
GL40.glDisable(GL40.GL_DEPTH_TEST);
|
|
}
|
|
// }
|
|
}
|
|
|
|
/**
|
|
* Sets the depth function
|
|
* @param depthFunction The depth function
|
|
*/
|
|
public void glDepthFunc(int depthFunction){
|
|
if(DISABLE_CACHING || this.depthFunction != depthFunction){
|
|
this.depthFunction = depthFunction;
|
|
GL40.glDepthFunc(this.depthFunction);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Sets the active texture
|
|
* @param texture The active texture
|
|
*/
|
|
public void glActiveTexture(int texture){
|
|
if(DISABLE_CACHING || this.activeTexture != texture){
|
|
this.activeTexture = texture;
|
|
GL40.glActiveTexture(this.activeTexture);
|
|
Globals.renderingEngine.checkError();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Binds a texture
|
|
* @param textureType The type of texture
|
|
* @param textureValue The texture pointer
|
|
*/
|
|
public void glBindTexture(int textureType, int texturePointer){
|
|
this.glBindTextureUnit(this.activeTexture, texturePointer, textureType);
|
|
}
|
|
|
|
/**
|
|
* Binds a texture to a given texture unit if the texture hasn't already been bound to that unit
|
|
* @param textureUnit The texture unit
|
|
* @param texturePointer The texture pointer
|
|
* @param textureType the type of texture (2d, 3d, etc)
|
|
*/
|
|
public void glBindTextureUnit(int textureUnit, int texturePointer, int textureType){
|
|
if(DISABLE_CACHING || !unitToPointerMap.containsKey(textureUnit) || unitToPointerMap.get(textureUnit)!=texturePointer){
|
|
unitToPointerMap.put(textureUnit,texturePointer);
|
|
this.glActiveTexture(textureUnit);
|
|
GL40.glBindTexture(textureType,texturePointer);
|
|
Globals.renderingEngine.checkError();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Binds a texture to a given texture unit if the texture hasn't already been bound to that unit
|
|
* @param textureUnit The texture unit
|
|
* @param texturePointer The texture pointer
|
|
* @param textureType the type of texture (2d, 3d, etc)
|
|
*/
|
|
public void glBindTextureUnitForce(int textureUnit, int texturePointer, int textureType){
|
|
unitToPointerMap.put(textureUnit,texturePointer);
|
|
this.activeTexture = textureUnit;
|
|
GL40.glActiveTexture(this.activeTexture);
|
|
Globals.renderingEngine.checkError();
|
|
GL40.glBindTexture(textureType,texturePointer);
|
|
Globals.renderingEngine.checkError();
|
|
}
|
|
|
|
/**
|
|
* Binds a framebuffer
|
|
* @param framebufferType the type of framebuffer (vanilla, renderbuffer, etc)
|
|
* @param framebufferPointer the pointer to the framebuffer
|
|
*/
|
|
public void glBindFramebuffer(int framebufferType, int framebufferPointer){
|
|
if(DISABLE_CACHING || this.framebufferType != framebufferType || this.framebufferPointer != framebufferPointer){
|
|
this.framebufferType = framebufferType;
|
|
this.framebufferPointer = framebufferPointer;
|
|
GL40.glBindFramebuffer(this.framebufferType,this.framebufferPointer);
|
|
Globals.renderingEngine.checkError();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Gets the currently bound framebuffer's pointer
|
|
* @return The pointer
|
|
*/
|
|
public int getBoundFramebuffer(){
|
|
return this.framebufferPointer;
|
|
}
|
|
|
|
/**
|
|
* Sets the currently active shader program for the renderer
|
|
* @param renderPipelineState The render pipeline state object
|
|
* @param program The shader program to bind
|
|
*/
|
|
public void setActiveShader(RenderPipelineState renderPipelineState, ShaderProgram program){
|
|
if(DISABLE_CACHING || program != activeShader){
|
|
activeShader = program;
|
|
GL40.glUseProgram(activeShader.getShaderId());
|
|
int glErrorCode = Globals.renderingEngine.getError();
|
|
if(glErrorCode != 0){
|
|
LoggerInterface.loggerRenderer.DEBUG_LOOP(RenderingEngine.getErrorInEnglish(glErrorCode));
|
|
}
|
|
Globals.renderingEngine.checkError();
|
|
renderPipelineState.setCurrentShaderPointer(activeShader.getShaderId());
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Gets the active shader program
|
|
* @return The active shader
|
|
*/
|
|
public ShaderProgram getActiveShader(){
|
|
return activeShader;
|
|
}
|
|
|
|
/**
|
|
* Checks whether the provided shader program is the active shader program
|
|
* @param program The program to check
|
|
* @return true if the provided program is the active program, false otherwise
|
|
*/
|
|
public boolean isCurrentShader(ShaderProgram program){
|
|
return this.activeShader == program;
|
|
}
|
|
|
|
/**
|
|
* Gets MAX_TEXTURE_WIDTH
|
|
* @return MAX_TEXTURE_WIDTH
|
|
*/
|
|
public int getMAX_TEXTURE_WIDTH(){
|
|
return MAX_TEXTURE_WIDTH;
|
|
}
|
|
|
|
/**
|
|
*
|
|
* @param sfactor
|
|
* @param dfactor
|
|
*/
|
|
public void glBlendFunc(int sfactor, int dfactor){
|
|
GL40.glBlendFunc(sfactor, dfactor);
|
|
//set all other keys
|
|
for(int keyCurrent : this.blendFuncMap.keySet()){
|
|
if(keyCurrent != ALL_BUFFERS_KEY){
|
|
int[] funcs = this.blendFuncMap.get(keyCurrent);
|
|
funcs[0] = sfactor;
|
|
funcs[1] = dfactor;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Sets the blend function for opengl
|
|
* @param drawBufferIndex The draw buffer index that will have this function set
|
|
* @param sfactor The source factor
|
|
* @param dfactor The destination factor
|
|
*/
|
|
public void glBlendFunci(int drawBufferIndex, int sfactor, int dfactor){
|
|
if(!DISABLE_CACHING && this.blendFuncMap.containsKey(drawBufferIndex)){
|
|
int[] funcs = this.blendFuncMap.get(drawBufferIndex);
|
|
int sFactorCurr = funcs[0];
|
|
int dFactorCurr = funcs[1];
|
|
if(sfactor != sFactorCurr || dfactor != dFactorCurr){
|
|
funcs[0] = sfactor;
|
|
funcs[1] = dfactor;
|
|
this.blendFuncMap.put(drawBufferIndex,funcs);
|
|
GL40.glBlendFunci(drawBufferIndex, sfactor, dfactor);
|
|
}
|
|
} else {
|
|
int[] funcs = new int[]{
|
|
sfactor, dfactor
|
|
};
|
|
this.blendFuncMap.put(drawBufferIndex,funcs);
|
|
GL40.glBlendFunci(drawBufferIndex, sfactor, dfactor);
|
|
}
|
|
|
|
}
|
|
|
|
public void glBlend(boolean blend){
|
|
// if(this.blendTest != blend){
|
|
this.blendTest = blend;
|
|
if(this.blendTest){
|
|
GL40.glEnable(GL40.GL_BLEND);
|
|
} else {
|
|
GL40.glDisable(GL40.GL_BLEND);
|
|
}
|
|
// }
|
|
}
|
|
|
|
}
|