Renderer param drill organization + OIT debugging
This commit is contained in:
parent
bb089a7d36
commit
bf914b15ec
@ -11,6 +11,7 @@ layout (binding = 1) uniform sampler2D reveal;
|
||||
|
||||
// epsilon number
|
||||
const float EPSILON = 0.00001f;
|
||||
const float REALLY_BIG_NUMBER = 75000.0f;
|
||||
|
||||
// caluclate floating point numbers equality accurately
|
||||
bool isApproximatelyEqual(float a, float b){
|
||||
@ -36,6 +37,11 @@ void main(){
|
||||
|
||||
// fragment color
|
||||
vec4 accumulation = texelFetch(accum, coords, 0);
|
||||
|
||||
//clamp accumulation to not go to INF
|
||||
if(accumulation.a > REALLY_BIG_NUMBER){
|
||||
accumulation.a = REALLY_BIG_NUMBER;
|
||||
}
|
||||
|
||||
// suppress overflow
|
||||
if (isinf(max3(abs(accumulation.rgb)))){
|
||||
|
||||
200
assets/Shaders/oit/general/FragmentShader.fs
Normal file
200
assets/Shaders/oit/general/FragmentShader.fs
Normal file
@ -0,0 +1,200 @@
|
||||
#version 400 core
|
||||
|
||||
#define NR_POINT_LIGHTS 10
|
||||
|
||||
layout (location = 0) out vec4 accum;
|
||||
layout (location = 1) out float reveal;
|
||||
|
||||
|
||||
layout (std140) uniform Lights {
|
||||
// this is how many because we have to align
|
||||
// bytes it SHOULD in multiples of 16, this
|
||||
// take it where it ACTUALLY is
|
||||
//
|
||||
//refer: https://learnopengl.com/Advanced-OpenGL/Advanced-GLSL
|
||||
//
|
||||
// base alignment aligned offset
|
||||
//direct light
|
||||
vec3 dLDirection; // 16 0
|
||||
vec3 dLAmbient; // 16 16
|
||||
vec3 dLDiffuse; // 16 32
|
||||
vec3 dLSpecular; // 16 48
|
||||
|
||||
//point light
|
||||
vec3 pLposition[NR_POINT_LIGHTS]; // 16*10 64
|
||||
float pLconstant[NR_POINT_LIGHTS]; // 16*10 224
|
||||
float pLlinear[NR_POINT_LIGHTS]; // 16*10 384
|
||||
float pLquadratic[NR_POINT_LIGHTS]; // 16*10 544
|
||||
vec3 pLambient[NR_POINT_LIGHTS]; // 16*10 704
|
||||
vec3 pLdiffuse[NR_POINT_LIGHTS]; // 16*10 864
|
||||
vec3 pLspecular[NR_POINT_LIGHTS]; // 16*10 1024
|
||||
|
||||
//for a total size of 1184
|
||||
|
||||
};
|
||||
|
||||
struct Material {
|
||||
sampler2D diffuse;
|
||||
sampler2D specular;
|
||||
float shininess;
|
||||
};
|
||||
|
||||
|
||||
//inputs
|
||||
in vec3 FragPos;
|
||||
in vec3 Normal;
|
||||
in vec2 TexCoord;
|
||||
in vec4 FragPosLightSpace;
|
||||
|
||||
|
||||
//view position
|
||||
uniform vec3 viewPos;
|
||||
|
||||
//material
|
||||
uniform Material material;
|
||||
|
||||
|
||||
|
||||
//light depth map
|
||||
uniform sampler2D shadowMap;
|
||||
|
||||
|
||||
//function prototypes
|
||||
float calcLightIntensityTotal(vec3 normal);
|
||||
float ShadowCalculation(vec4 fragPosLightSpace, vec3 lightDir, vec3 normal);
|
||||
|
||||
|
||||
|
||||
|
||||
void main(){
|
||||
|
||||
vec3 norm = normalize(Normal);
|
||||
vec3 viewDir = normalize(viewPos - FragPos);
|
||||
|
||||
//grab light intensity
|
||||
float lightIntensity = calcLightIntensityTotal(norm);
|
||||
|
||||
//get color of base texture
|
||||
vec4 textureColor = texture(material.diffuse, TexCoord);
|
||||
vec3 textureRGB = textureColor.rgb;
|
||||
|
||||
//shadow
|
||||
float shadow = ShadowCalculation(FragPosLightSpace, normalize(-dLDirection), norm);
|
||||
vec3 shadowModifiedColor = textureRGB * lightIntensity * max(shadow, 0.4);
|
||||
|
||||
//calculate final color
|
||||
vec4 finalColor = vec4(shadowModifiedColor,textureColor.a);
|
||||
|
||||
//calculate weight function
|
||||
float weight = clamp(pow(min(1.0, finalColor.a * 10.0) + 0.01, 3.0) * 1e8 *
|
||||
pow(1.0 - gl_FragCoord.z * 0.9, 3.0), 1e-2, 3e3);
|
||||
|
||||
//emit colors
|
||||
accum = vec4(finalColor.rgb * finalColor.a, finalColor.a) * weight;
|
||||
reveal = finalColor.a;
|
||||
}
|
||||
|
||||
|
||||
|
||||
float calcLightIntensityAmbient(){
|
||||
//calculate average of ambient light
|
||||
float avg = (dLAmbient.x + dLAmbient.y + dLAmbient.z)/3.0;
|
||||
return avg;
|
||||
}
|
||||
|
||||
//
|
||||
float calcLightIntensityDir(vec3 normal){
|
||||
vec3 lightDir = normalize(-dLDirection);
|
||||
// diffuse shading
|
||||
float diff = max(dot(normal, lightDir), 0.0);
|
||||
|
||||
return diff;
|
||||
}
|
||||
|
||||
//
|
||||
float calcLightIntensityTotal(vec3 normal){
|
||||
//ambient intensity
|
||||
float ambientLightIntensity = calcLightIntensityAmbient();
|
||||
|
||||
//get direct intensity
|
||||
float directLightIntensity = calcLightIntensityDir(normal);
|
||||
|
||||
//sum
|
||||
float total = ambientLightIntensity + directLightIntensity;
|
||||
return total;
|
||||
}
|
||||
|
||||
//
|
||||
vec3 getTotalLightColor(vec3 normal){
|
||||
//get the direct light color adjusted for intensity
|
||||
vec3 diffuseLightColor = dLDiffuse * calcLightIntensityDir(normal);
|
||||
|
||||
//sum light colors
|
||||
vec3 totalLightColor = diffuseLightColor;
|
||||
return totalLightColor;
|
||||
}
|
||||
|
||||
vec3 CalcPointLight(int i, vec3 normal, vec3 fragPos, vec3 viewDir){
|
||||
vec3 lightDir = normalize(pLposition[i] - fragPos);
|
||||
// diffuse shading
|
||||
float diff = max(dot(normal, lightDir), 0.0);
|
||||
// specular shading
|
||||
// vec3 reflectDir = reflect(-lightDir, normal);
|
||||
// float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);
|
||||
// attenuation
|
||||
float distance = length(pLposition[i] - fragPos);
|
||||
float attenuation = 1.0 / (pLconstant[i] + pLlinear[i] * distance + pLquadratic[i] * (distance * distance));
|
||||
// combine results
|
||||
vec3 ambient = pLambient[i];// * vec4(texture(material.diffuse, TexCoord)).xyz;
|
||||
vec3 diffuse = pLdiffuse[i] * diff;// * vec4(texture(material.diffuse, TexCoord)).xyz;
|
||||
// vec3 specular = pLspecular[i] * spec;// * vec4(texture(material.specular, TexCoord)).xyz;
|
||||
ambient *= attenuation;
|
||||
diffuse *= attenuation;
|
||||
// specular *= attenuation;
|
||||
vec3 specular = vec3(0,0,0);
|
||||
|
||||
vec3 finalValue = (ambient + diffuse + specular);
|
||||
finalValue = vec3(max(finalValue.x,0),max(finalValue.y,0),max(finalValue.z,0));
|
||||
|
||||
return finalValue;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
float ShadowCalculation(vec4 fragPosLightSpace, vec3 lightDir, vec3 normal){
|
||||
|
||||
// perform perspective divide
|
||||
vec3 projCoords = fragPosLightSpace.xyz / fragPosLightSpace.w;
|
||||
|
||||
//transform to NDC
|
||||
projCoords = projCoords * 0.5 + 0.5;
|
||||
|
||||
//get closest depth from light's POV
|
||||
float closestDepth = texture(shadowMap, projCoords.xy).r;
|
||||
|
||||
//get depth of current fragment
|
||||
float currentDepth = projCoords.z;
|
||||
|
||||
//calculate bias
|
||||
float bias = max(0.05 * (1.0 - dot(normal, lightDir)), 0.005);
|
||||
|
||||
//calculate shadow value
|
||||
float shadow = currentDepth - bias > closestDepth ? 1.0 : 0.0;
|
||||
|
||||
if(projCoords.z > 1.0){
|
||||
shadow = 0.0;
|
||||
}
|
||||
|
||||
//calculate dot product, if it is >0 we know they're parallel-ish therefore should disregard the shadow mapping
|
||||
//ie the fragment is already facing away from the light source
|
||||
float dotprod = dot(normalize(lightDir),normalize(normal));
|
||||
|
||||
if(dotprod > 0.0){
|
||||
shadow = 0.0;
|
||||
}
|
||||
|
||||
// shadow = currentDepth;
|
||||
|
||||
return shadow;
|
||||
}
|
||||
71
assets/Shaders/oit/general/VertexShader.vs
Normal file
71
assets/Shaders/oit/general/VertexShader.vs
Normal file
@ -0,0 +1,71 @@
|
||||
//Vertex Shader
|
||||
#version 400 core
|
||||
|
||||
|
||||
|
||||
//input buffers
|
||||
layout (location = 0) in vec3 aPos;
|
||||
layout (location = 1) in vec3 aNormal;
|
||||
layout (location = 2) in vec4 aWeights;
|
||||
layout (location = 3) in vec4 aIndex;
|
||||
layout (location = 4) in vec2 aTex;
|
||||
|
||||
|
||||
//coordinate space transformation matrices
|
||||
uniform mat4 transform;
|
||||
uniform mat4 model;
|
||||
uniform mat4 view;
|
||||
uniform mat4 projection;
|
||||
uniform mat4 lightSpaceMatrix;
|
||||
|
||||
//bone related variables
|
||||
const int MAX_WEIGHTS = 4;
|
||||
const int MAX_BONES = 100;
|
||||
uniform mat4 bones[MAX_BONES];
|
||||
uniform int hasBones;
|
||||
uniform int numBones;
|
||||
|
||||
|
||||
|
||||
//output buffers
|
||||
out vec3 Normal;
|
||||
out vec3 FragPos;
|
||||
out vec2 TexCoord;
|
||||
out vec4 FragPosLightSpace;
|
||||
|
||||
|
||||
|
||||
|
||||
void main() {
|
||||
|
||||
|
||||
|
||||
//calculate bone transform
|
||||
mat4 BoneTransform = (bones[int(aIndex[0])] * aWeights[0]);
|
||||
BoneTransform = BoneTransform + (bones[int(aIndex[1])] * aWeights[1]);
|
||||
BoneTransform = BoneTransform + (bones[int(aIndex[2])] * aWeights[2]);
|
||||
BoneTransform = BoneTransform + (bones[int(aIndex[3])] * aWeights[3]);
|
||||
|
||||
|
||||
//apply bone transform to position vectors
|
||||
vec4 FinalVertex = BoneTransform * vec4(aPos, 1.0);
|
||||
vec4 FinalNormal = BoneTransform * vec4(aNormal, 1.0);
|
||||
|
||||
|
||||
//make sure the W component is 1.0
|
||||
FinalVertex = vec4(FinalVertex.xyz, 1.0);
|
||||
FinalNormal = vec4(FinalNormal.xyz, 1.0);
|
||||
|
||||
|
||||
//push frag, normal, and texture positions to fragment shader
|
||||
FragPos = vec3(model * FinalVertex);
|
||||
Normal = mat3(transpose(inverse(model))) * FinalNormal.xyz;
|
||||
TexCoord = aTex;
|
||||
|
||||
//shadow map stuff
|
||||
FragPosLightSpace = lightSpaceMatrix * vec4(FragPos, 1.0);
|
||||
|
||||
|
||||
//set final position with opengl space
|
||||
gl_Position = projection * view * model * FinalVertex;
|
||||
}
|
||||
48
assets/Shaders/oit/general/VertexShaderNoBones.vs
Normal file
48
assets/Shaders/oit/general/VertexShaderNoBones.vs
Normal file
@ -0,0 +1,48 @@
|
||||
//Vertex Shader
|
||||
#version 400 core
|
||||
|
||||
|
||||
|
||||
//input buffers
|
||||
layout (location = 0) in vec3 aPos;
|
||||
layout (location = 1) in vec3 aNormal;
|
||||
layout (location = 4) in vec2 aTex;
|
||||
|
||||
|
||||
//coordinate space transformation matrices
|
||||
uniform mat4 transform;
|
||||
uniform mat4 model;
|
||||
uniform mat4 view;
|
||||
uniform mat4 projection;
|
||||
uniform mat4 lightSpaceMatrix;
|
||||
|
||||
|
||||
|
||||
//output buffers
|
||||
out vec3 Normal;
|
||||
out vec3 FragPos;
|
||||
out vec2 TexCoord;
|
||||
out vec4 FragPosLightSpace;
|
||||
|
||||
|
||||
|
||||
|
||||
void main() {
|
||||
//normalize posiiton and normal
|
||||
vec4 FinalVertex = vec4(aPos, 1.0);
|
||||
vec4 FinalNormal = vec4(aNormal, 1.0);
|
||||
|
||||
|
||||
//push frag, normal, and texture positions to fragment shader
|
||||
FragPos = vec3(model * FinalVertex);
|
||||
Normal = mat3(transpose(inverse(model))) * aNormal;
|
||||
TexCoord = aTex;
|
||||
|
||||
|
||||
//shadow map stuff
|
||||
FragPosLightSpace = lightSpaceMatrix * vec4(FragPos, 1.0);
|
||||
|
||||
|
||||
//set final position with opengl space
|
||||
gl_Position = projection * view * model * FinalVertex;
|
||||
}
|
||||
@ -3,6 +3,7 @@ package electrosphere.engine;
|
||||
import java.io.IOException;
|
||||
import java.io.PipedInputStream;
|
||||
import java.io.PipedOutputStream;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.Semaphore;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@ -782,12 +783,23 @@ public class LoadingThread extends Thread {
|
||||
// loader.serverInstantiateSceneFile("Scenes/testscene1/testscene1.json");
|
||||
|
||||
|
||||
Entity chunk = TerrainChunk.createTerrainChunkEntity();
|
||||
// Entity chunk = TerrainChunk.createTerrainChunkEntity();
|
||||
|
||||
Entity leaves = EntityUtils.spawnDrawableEntity(AssetDataStrings.LEAVES_MODEL);
|
||||
EntityUtils.repositionEntity(leaves, new Vector3d(1,0,1));
|
||||
leaves.putData(EntityDataStrings.DRAW_SOLID_PASS, true);
|
||||
leaves.putData(EntityDataStrings.DRAW_TRANSPARENT_PASS, true);
|
||||
|
||||
Random rand = new Random();
|
||||
for(int i = 0; i < 100; i++){
|
||||
Entity leaves = EntityUtils.spawnDrawableEntity(AssetDataStrings.LEAVES_MODEL);
|
||||
float rad = rand.nextFloat();
|
||||
float angle = (float)(rand.nextFloat() * 2.0 * Math.PI);
|
||||
Vector3d position = new Vector3d(Math.cos(angle) * rad + 4,1 + (rand.nextFloat() - 0.5),Math.sin(angle) * rad + 4);
|
||||
Quaternionf rotation = new Quaternionf(rand.nextFloat(), rand.nextFloat(), rand.nextFloat(), rand.nextFloat()).normalize();
|
||||
System.out.println(position);
|
||||
EntityUtils.repositionEntity(leaves, position);
|
||||
EntityUtils.getPosition(leaves).set(position);
|
||||
EntityUtils.getRotation(leaves).slerp(rotation, 0.3f);
|
||||
leaves.removeData(EntityDataStrings.DRAW_SOLID_PASS);
|
||||
leaves.putData(EntityDataStrings.DRAW_TRANSPARENT_PASS, true);
|
||||
}
|
||||
|
||||
// Globals.entityManager.registerBehaviorTree(new BehaviorTree() {
|
||||
// int i = 0;
|
||||
|
||||
@ -14,6 +14,8 @@ import static org.lwjgl.opengl.GL11.GL_TEXTURE_2D;
|
||||
import static org.lwjgl.opengl.GL11.glBindTexture;
|
||||
import static org.lwjgl.opengl.GL13.GL_TEXTURE0;
|
||||
import static org.lwjgl.opengl.GL13.glActiveTexture;
|
||||
import static org.lwjgl.opengl.GL20.glGetUniformLocation;
|
||||
import static org.lwjgl.opengl.GL20.glUniform1i;
|
||||
|
||||
/**
|
||||
*
|
||||
@ -74,10 +76,12 @@ public class Material {
|
||||
Texture diffuseTexture = Globals.assetManager.fetchTexture(diffuse);
|
||||
if(diffuseTexture != null){
|
||||
diffuseTexture.bind(0);
|
||||
glUniform1i(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "material.diffuse"), 0);
|
||||
}
|
||||
Texture specularTexture = Globals.assetManager.fetchTexture(specular);
|
||||
if(specularTexture != null){
|
||||
specularTexture.bind(1);
|
||||
glUniform1i(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "material.specular"), 1);
|
||||
}
|
||||
} else {
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
|
||||
@ -4,6 +4,7 @@ import electrosphere.engine.Globals;
|
||||
import electrosphere.engine.Main;
|
||||
import electrosphere.entity.types.camera.CameraEntityUtils;
|
||||
import electrosphere.logger.LoggerInterface;
|
||||
import electrosphere.renderer.RenderPipelineState.SelectedShaderEnum;
|
||||
import electrosphere.renderer.actor.ActorTextureMask;
|
||||
import electrosphere.renderer.light.LightManager;
|
||||
import electrosphere.renderer.loading.ModelPretransforms;
|
||||
@ -97,6 +98,7 @@ public class Mesh {
|
||||
public float vertexMaxZ;
|
||||
|
||||
public ShaderProgram shader;
|
||||
ShaderProgram oitShader;
|
||||
|
||||
int shaderBoneArrayLocation;
|
||||
|
||||
@ -403,6 +405,7 @@ public class Mesh {
|
||||
|
||||
if(!Globals.HEADLESS){
|
||||
rVal.shader = ShaderProgram.smart_assemble_shader(has_bones, apply_lighting);
|
||||
rVal.oitShader = ShaderProgram.smartAssembleOITProgram(has_bones, apply_lighting);
|
||||
}
|
||||
|
||||
|
||||
@ -517,6 +520,17 @@ public class Mesh {
|
||||
this.material = input;
|
||||
}
|
||||
|
||||
public void generateShader(SelectedShaderEnum selectedShader, boolean hasBones, boolean applyLighting){
|
||||
switch(selectedShader){
|
||||
case PRIMARY: {
|
||||
shader = ShaderProgram.smart_assemble_shader(hasBones, applyLighting);
|
||||
} break;
|
||||
case OIT: {
|
||||
oitShader = ShaderProgram.smartAssembleOITProgram(hasBones, applyLighting);
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
public void setShader(ShaderProgram shader){
|
||||
this.shader = shader;
|
||||
}
|
||||
@ -546,20 +560,37 @@ public class Mesh {
|
||||
}
|
||||
|
||||
|
||||
public void complexDraw(
|
||||
/*
|
||||
*
|
||||
*
|
||||
*
|
||||
boolean setShader,
|
||||
boolean bufferStandardUniforms,
|
||||
boolean bufferNonStandardUniforms,
|
||||
boolean useMaterial,
|
||||
boolean useShadowMap,
|
||||
boolean setBones,
|
||||
boolean useLight){
|
||||
boolean useLight
|
||||
*/
|
||||
public void complexDraw(RenderPipelineState renderPipelineState){
|
||||
|
||||
if(setShader){
|
||||
Globals.renderingEngine.setActiveShader(shader);
|
||||
if(renderPipelineState.getUseMeshShader()){
|
||||
ShaderProgram selectedProgram = null;
|
||||
switch(renderPipelineState.getSelectedShader()){
|
||||
case PRIMARY: {
|
||||
selectedProgram = shader;
|
||||
} break;
|
||||
case OIT: {
|
||||
selectedProgram = oitShader;
|
||||
} break;
|
||||
}
|
||||
if(selectedProgram == null){
|
||||
selectedProgram = shader;
|
||||
}
|
||||
Globals.renderingEngine.setActiveShader(selectedProgram);
|
||||
}
|
||||
|
||||
if(useLight){
|
||||
if(renderPipelineState.getUseLight()){
|
||||
//Until we switch to uniform buffer objects we will have to buffer lighting data here manually each time we draw
|
||||
//side note: :(
|
||||
if(Globals.renderingEngine.getLightManager() == null){
|
||||
@ -570,7 +601,7 @@ public class Mesh {
|
||||
}
|
||||
}
|
||||
|
||||
if(useMaterial && textureMask == null){
|
||||
if(renderPipelineState.getUseMaterial() && textureMask == null){
|
||||
if(material == null){
|
||||
Globals.materialDefault.apply_material(0,1);
|
||||
GL20.glUniform1i(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "hasTransparency"), 0);
|
||||
@ -612,14 +643,14 @@ public class Mesh {
|
||||
// glActiveTexture(GL_TEXTURE0);
|
||||
}
|
||||
|
||||
if(useShadowMap){
|
||||
if(renderPipelineState.getUseShadowMap()){
|
||||
glActiveTexture(GL_TEXTURE3);
|
||||
glBindTexture(GL_TEXTURE_2D, Globals.shadowMapTextureLoc);
|
||||
glUniform1i(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "shadowMap"), 3);
|
||||
}
|
||||
|
||||
|
||||
if(setBones){
|
||||
if(renderPipelineState.getUseBones()){
|
||||
//
|
||||
//Handle bones
|
||||
//
|
||||
@ -658,7 +689,7 @@ public class Mesh {
|
||||
}
|
||||
|
||||
|
||||
if(bufferStandardUniforms){
|
||||
if(renderPipelineState.getBufferStandardUniforms()){
|
||||
//buffer model/view/proj matrices
|
||||
glUniformMatrix4fv(Globals.renderingEngine.getActiveShader().shaderVertexModelLoc, false, parent.modelMatrix.get(new float[16]));
|
||||
glUniformMatrix4fv(Globals.renderingEngine.getActiveShader().shaderVertexViewLoc, false, Globals.viewMatrix.get(new float[16]));
|
||||
@ -669,7 +700,7 @@ public class Mesh {
|
||||
glUniform1f(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "time"), (float)Main.getCurrentFrame());
|
||||
}
|
||||
|
||||
if(bufferNonStandardUniforms){
|
||||
if(renderPipelineState.getBufferNonStandardUniforms()){
|
||||
bufferAllUniforms();
|
||||
}
|
||||
|
||||
|
||||
@ -209,7 +209,7 @@ public class Model {
|
||||
meshes = null;
|
||||
}
|
||||
|
||||
public void draw(boolean setShader, boolean bufferStandardUniforms, boolean bufferNonStandardUniforms, boolean useMaterial, boolean useShadowMap, boolean setBones, boolean useLight){
|
||||
public void draw(RenderPipelineState renderPipelineState){
|
||||
// if(node_map != null && !node_map.isEmpty()){
|
||||
// update_node_transform(root_anim_node);
|
||||
// }
|
||||
@ -226,7 +226,7 @@ public class Model {
|
||||
currentMesh.setTextureMask(textureMap.get(currentMesh.nodeID));
|
||||
}
|
||||
//draw
|
||||
currentMesh.complexDraw(setShader, bufferStandardUniforms, bufferNonStandardUniforms, useMaterial, useShadowMap, setBones, useLight);
|
||||
currentMesh.complexDraw(renderPipelineState);
|
||||
//reset texture mask
|
||||
currentMesh.setTextureMask(null);
|
||||
//reset shader
|
||||
@ -240,7 +240,7 @@ public class Model {
|
||||
ShaderProgram original = toDraw.shader;
|
||||
ShaderProgram shader = getCorrectShader(shaderMask, toDraw, toDraw.shader);
|
||||
toDraw.shader = shader;
|
||||
toDraw.complexDraw(setShader, bufferStandardUniforms, bufferNonStandardUniforms, useMaterial, useShadowMap, setBones, useLight);
|
||||
toDraw.complexDraw(renderPipelineState);
|
||||
toDraw.shader = original;
|
||||
}
|
||||
}
|
||||
@ -439,30 +439,9 @@ public class Model {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void drawForDepthBuffer(){
|
||||
Iterator<Mesh> mesh_Iterator = meshes.iterator();
|
||||
while(mesh_Iterator.hasNext()){
|
||||
Mesh currentMesh = mesh_Iterator.next();
|
||||
currentMesh.setUniform("model", modelMatrix);
|
||||
if(currentMesh.hasBones){
|
||||
currentMesh.complexDraw(false, false, true, false, false, true, false);
|
||||
} else {
|
||||
currentMesh.setUniform("hasBones", 0);
|
||||
currentMesh.complexDraw(false, false, true, false, false, false, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void drawUI(){
|
||||
for(Mesh m : meshes){
|
||||
m.complexDraw(true, false, true, true, false, false, false);
|
||||
}
|
||||
}
|
||||
|
||||
public void drawFramebuffer(){
|
||||
for(Mesh m : meshes){
|
||||
m.complexDraw(true, false, true, false, false, false, false);
|
||||
m.complexDraw(RenderingEngine.getRenderPipelineState());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,93 @@
|
||||
package electrosphere.renderer;
|
||||
|
||||
public class RenderPipelineState {
|
||||
|
||||
public static enum RenderPipelineStateEnum {
|
||||
SHADOW_MAP,
|
||||
MAIN_OIT,
|
||||
MAIN_NON_TRANSPARENT,
|
||||
NORMALS,
|
||||
COMPOSITE,
|
||||
}
|
||||
|
||||
public static enum SelectedShaderEnum {
|
||||
PRIMARY,
|
||||
OIT,
|
||||
}
|
||||
|
||||
RenderPipelineStateEnum state = RenderPipelineStateEnum.SHADOW_MAP;
|
||||
SelectedShaderEnum selectedShader = SelectedShaderEnum.PRIMARY;
|
||||
|
||||
boolean useMeshShader = false;
|
||||
boolean bufferStandardUniforms = false;
|
||||
boolean bufferNonStandardUniforms = false;
|
||||
boolean useMaterial = false;
|
||||
boolean useShadowMap = false;
|
||||
boolean useBones = false;
|
||||
boolean useLight = false;
|
||||
|
||||
public boolean getUseMeshShader(){
|
||||
return this.useMeshShader;
|
||||
}
|
||||
|
||||
public void setUseMeshShader(boolean useMeshShader){
|
||||
this.useMeshShader = useMeshShader;
|
||||
}
|
||||
|
||||
public boolean getBufferStandardUniforms(){
|
||||
return this.bufferStandardUniforms;
|
||||
}
|
||||
|
||||
public void setBufferStandardUniforms(boolean bufferStandardUniforms){
|
||||
this.bufferStandardUniforms = bufferStandardUniforms;
|
||||
}
|
||||
|
||||
public boolean getBufferNonStandardUniforms(){
|
||||
return this.bufferNonStandardUniforms;
|
||||
}
|
||||
|
||||
public void setBufferNonStandardUniforms(boolean bufferNonStandardUniforms){
|
||||
this.bufferNonStandardUniforms = bufferNonStandardUniforms;
|
||||
}
|
||||
|
||||
public boolean getUseMaterial(){
|
||||
return this.useMaterial;
|
||||
}
|
||||
|
||||
public void setUseMaterial(boolean useMaterial){
|
||||
this.useMaterial = useMaterial;
|
||||
}
|
||||
|
||||
public boolean getUseShadowMap(){
|
||||
return this.useShadowMap;
|
||||
}
|
||||
|
||||
public void setUseShadowMap(boolean useShadowMap){
|
||||
this.useShadowMap = useShadowMap;
|
||||
}
|
||||
|
||||
public boolean getUseBones(){
|
||||
return useBones;
|
||||
}
|
||||
|
||||
public void setUseBones(boolean useBones){
|
||||
this.useBones = useBones;
|
||||
}
|
||||
|
||||
public boolean getUseLight(){
|
||||
return this.useLight;
|
||||
}
|
||||
|
||||
public void setUseLight(boolean useLight){
|
||||
this.useLight = useLight;
|
||||
}
|
||||
|
||||
public SelectedShaderEnum getSelectedShader(){
|
||||
return selectedShader;
|
||||
}
|
||||
|
||||
public void setSelectedShader(SelectedShaderEnum selectedShader){
|
||||
this.selectedShader = selectedShader;
|
||||
}
|
||||
|
||||
}
|
||||
@ -148,13 +148,13 @@ public class RenderUtils {
|
||||
|
||||
Mesh skyboxmesh = new Mesh(){
|
||||
@Override
|
||||
public void complexDraw(boolean setShader, boolean bufferStandardUniforms, boolean bufferNonStandardUniforms, boolean useMaterial, boolean useShadowMap, boolean setBones, boolean useLight){
|
||||
if(setShader){
|
||||
public void complexDraw(RenderPipelineState renderPipelineState){
|
||||
if(renderPipelineState.getUseMeshShader()){
|
||||
GL11.glDepthFunc(GL_LEQUAL);
|
||||
glUseProgram(shader.shaderProgram);
|
||||
}
|
||||
|
||||
if(useMaterial){
|
||||
if(renderPipelineState.getUseMaterial()){
|
||||
if(material == null){
|
||||
Globals.materialDefault.apply_material(0,1);
|
||||
Iterator<Vector3f> colorIterator = Globals.skyboxColors.iterator();
|
||||
@ -176,7 +176,7 @@ public class RenderUtils {
|
||||
|
||||
|
||||
|
||||
if(bufferStandardUniforms){
|
||||
if(renderPipelineState.getBufferStandardUniforms()){
|
||||
//buffer model/view/proj matrices
|
||||
glUniformMatrix4fv(shader.shaderVertexModelLoc, false, parent.modelMatrix.get(new float[16]));
|
||||
glUniformMatrix4fv(shader.shaderVertexViewLoc, false, new Matrix4f(Globals.viewMatrix).scale(100).get(new float[16]));
|
||||
@ -187,7 +187,7 @@ public class RenderUtils {
|
||||
GL11.glDrawElements(GL_TRIANGLES, elementCount, GL_UNSIGNED_INT, 0);
|
||||
glBindVertexArray(0);
|
||||
|
||||
if(setShader){
|
||||
if(renderPipelineState.getUseMeshShader()){
|
||||
GL11.glDepthFunc(GL_LESS);
|
||||
}
|
||||
}
|
||||
|
||||
@ -21,6 +21,7 @@ import static org.lwjgl.opengl.GL11.GL_COLOR_BUFFER_BIT;
|
||||
import static org.lwjgl.opengl.GL11.GL_DEPTH_BUFFER_BIT;
|
||||
import static org.lwjgl.opengl.GL11.GL_DEPTH_TEST;
|
||||
import static org.lwjgl.opengl.GL11.GL_LESS;
|
||||
import static org.lwjgl.opengl.GL11.GL_LEQUAL;
|
||||
import static org.lwjgl.opengl.GL11.GL_ONE;
|
||||
import static org.lwjgl.opengl.GL11.GL_ONE_MINUS_SRC_ALPHA;
|
||||
import static org.lwjgl.opengl.GL11.GL_ONE_MINUS_SRC_COLOR;
|
||||
@ -67,8 +68,10 @@ import org.joml.Vector3f;
|
||||
import org.lwjgl.BufferUtils;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
import org.lwjgl.opengl.GL;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
import org.lwjgl.opengl.GL15;
|
||||
import org.lwjgl.opengl.GL20;
|
||||
import org.lwjgl.opengl.GL30;
|
||||
|
||||
import electrosphere.controls.ControlCallback;
|
||||
import electrosphere.controls.MouseCallback;
|
||||
@ -82,6 +85,7 @@ import electrosphere.entity.types.hitbox.HitboxData;
|
||||
import electrosphere.entity.types.hitbox.HitboxUtils;
|
||||
import electrosphere.game.data.creature.type.CollidableTemplate;
|
||||
import electrosphere.logger.LoggerInterface;
|
||||
import electrosphere.renderer.RenderPipelineState.SelectedShaderEnum;
|
||||
import electrosphere.renderer.actor.Actor;
|
||||
import electrosphere.renderer.debug.DebugRendering;
|
||||
import electrosphere.renderer.framebuffer.Framebuffer;
|
||||
@ -179,6 +183,8 @@ public class RenderingEngine {
|
||||
//used in calculating projection matrix
|
||||
static float aspectRatio = 1.0f;
|
||||
static float verticalFOV = 90.0f;
|
||||
|
||||
static RenderPipelineState renderPipelineState = new RenderPipelineState();
|
||||
|
||||
|
||||
public void createOpenglContext(){
|
||||
@ -318,7 +324,7 @@ public class RenderingEngine {
|
||||
//
|
||||
transparencyAccumulatorClear = new float[]{0.0f, 0.0f, 0.0f, 0.0f};
|
||||
transparencyAccumulatorTexture = FramebufferUtils.generateOITAccumulatorTexture(Globals.userSettings.getRenderResolutionX(), Globals.userSettings.getRenderResolutionY());
|
||||
transparencyRevealageClear = new float[]{1.0f, 0.0f, 0.0f, 0.0f};
|
||||
transparencyRevealageClear = new float[]{1.0f, 1.0f, 1.0f, 1.0f};
|
||||
transparencyRevealageTexture = FramebufferUtils.generateOITRevealageTexture(Globals.userSettings.getRenderResolutionX(), Globals.userSettings.getRenderResolutionY());
|
||||
transparencyBuffer = FramebufferUtils.generateOITFramebuffer(Globals.userSettings.getRenderResolutionX(), Globals.userSettings.getRenderResolutionY(), transparencyAccumulatorTexture, transparencyRevealageTexture, screenTextureDepth);
|
||||
oitCompositeProgram = ShaderProgram.loadSpecificShader("Shaders/oit/composite.vs", "Shaders/oit/composite.fs");
|
||||
@ -503,7 +509,8 @@ public class RenderingEngine {
|
||||
}
|
||||
|
||||
|
||||
|
||||
//check for errors
|
||||
// checkError();
|
||||
|
||||
//check and call events and swap the buffers
|
||||
glfwSwapBuffers(Globals.window);
|
||||
@ -546,6 +553,17 @@ public class RenderingEngine {
|
||||
|
||||
// glCullFace(GL_FRONT);
|
||||
|
||||
//
|
||||
// Set render pipeline state
|
||||
//
|
||||
renderPipelineState.setUseMeshShader(false);
|
||||
renderPipelineState.setBufferStandardUniforms(true);
|
||||
renderPipelineState.setBufferNonStandardUniforms(true);
|
||||
renderPipelineState.setUseMaterial(false);
|
||||
renderPipelineState.setUseShadowMap(false);
|
||||
renderPipelineState.setUseBones(true);
|
||||
renderPipelineState.setUseLight(false);
|
||||
|
||||
//
|
||||
// D R A W A L L E N T I T I E S
|
||||
//
|
||||
@ -570,7 +588,7 @@ public class RenderingEngine {
|
||||
modelTransformMatrix.scale(EntityUtils.getScale(currentEntity));
|
||||
currentActor.applyModelMatrix(modelTransformMatrix);
|
||||
//draw
|
||||
currentActor.drawForDepthBuffer();
|
||||
currentActor.draw(renderPipelineState);
|
||||
}
|
||||
}
|
||||
|
||||
@ -607,6 +625,19 @@ public class RenderingEngine {
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
|
||||
//
|
||||
// Set render pipeline state
|
||||
//
|
||||
renderPipelineState.setSelectedShader(SelectedShaderEnum.PRIMARY);
|
||||
renderPipelineState.setUseMeshShader(true);
|
||||
renderPipelineState.setBufferStandardUniforms(true);
|
||||
renderPipelineState.setBufferNonStandardUniforms(false);
|
||||
renderPipelineState.setUseMaterial(true);
|
||||
renderPipelineState.setUseShadowMap(true);
|
||||
renderPipelineState.setUseBones(true);
|
||||
renderPipelineState.setUseLight(true);
|
||||
|
||||
|
||||
//
|
||||
// Pass One: Solids
|
||||
//
|
||||
@ -634,17 +665,15 @@ public class RenderingEngine {
|
||||
modelTransformMatrix.scale(EntityUtils.getScale(currentEntity));
|
||||
currentActor.applyModelMatrix(modelTransformMatrix);
|
||||
//draw
|
||||
currentActor.draw(true);
|
||||
currentActor.draw(renderPipelineState);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Pass Two: Transparency Accumulator + Revealage
|
||||
//
|
||||
// glDisable(GL_DEPTH_TEST);
|
||||
glDepthMask(false);
|
||||
glDepthFunc(GL_LESS);
|
||||
// glDepthFunc(GL_GREATER);
|
||||
// glDepthFunc(GL_ALWAYS);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunci(0, GL_ONE, GL_ONE);
|
||||
glBlendFunci(1, GL_ZERO, GL_ONE_MINUS_SRC_COLOR);
|
||||
@ -654,6 +683,22 @@ public class RenderingEngine {
|
||||
glClearBufferfv(GL_COLOR,0,transparencyAccumulatorClear);
|
||||
glClearBufferfv(GL_COLOR,1,transparencyRevealageClear);
|
||||
|
||||
//
|
||||
// Set render pipeline state
|
||||
//
|
||||
renderPipelineState.setSelectedShader(SelectedShaderEnum.OIT);
|
||||
|
||||
//
|
||||
//!!!WARNING!!!
|
||||
//Comments on function:
|
||||
//If you're going "gee wilikers I don't know why the back planes of my transparent-labeled aren't showing through the transparency", this is for you
|
||||
//The transparent pass receives the depth buffer of the opaque pass and IS DEPTH MASK CULLED
|
||||
//This means if you draw the transparent object in the depth pass, it will not draw in the transparent pass as it is culled
|
||||
//
|
||||
//!!!WARNING!!!
|
||||
//TLDR OF ABOVE: DO NOT DRAW TRANSPARENT OBJECTS IN OPAQUE PASS
|
||||
//
|
||||
|
||||
|
||||
for(Entity currentEntity : Globals.entityManager.getEntitiesWithTag(EntityTags.DRAWABLE)){
|
||||
Vector3d position = EntityUtils.getPosition(currentEntity);
|
||||
@ -673,10 +718,16 @@ public class RenderingEngine {
|
||||
modelTransformMatrix.scale(EntityUtils.getScale(currentEntity));
|
||||
currentActor.applyModelMatrix(modelTransformMatrix);
|
||||
//draw
|
||||
currentActor.draw(true);
|
||||
currentActor.draw(renderPipelineState);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Set render pipeline state
|
||||
//
|
||||
renderPipelineState.setSelectedShader(SelectedShaderEnum.PRIMARY);
|
||||
|
||||
|
||||
|
||||
// glBindVertexArray(0);
|
||||
@ -706,6 +757,17 @@ public class RenderingEngine {
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
|
||||
//
|
||||
// Set render pipeline state
|
||||
//
|
||||
renderPipelineState.setUseMeshShader(true);
|
||||
renderPipelineState.setBufferStandardUniforms(true);
|
||||
renderPipelineState.setBufferNonStandardUniforms(false);
|
||||
renderPipelineState.setUseMaterial(true);
|
||||
renderPipelineState.setUseShadowMap(true);
|
||||
renderPipelineState.setUseBones(true);
|
||||
renderPipelineState.setUseLight(true);
|
||||
|
||||
//
|
||||
// D R A W A L L E N T I T I E S
|
||||
//
|
||||
@ -728,7 +790,7 @@ public class RenderingEngine {
|
||||
modelTransformMatrix.scale(EntityUtils.getScale(currentEntity));
|
||||
currentActor.applyModelMatrix(modelTransformMatrix);
|
||||
//draw
|
||||
currentActor.draw(true);
|
||||
currentActor.draw(renderPipelineState);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -747,6 +809,18 @@ public class RenderingEngine {
|
||||
///
|
||||
//Sets the background color.
|
||||
|
||||
|
||||
//
|
||||
// Set render pipeline state
|
||||
//
|
||||
renderPipelineState.setUseMeshShader(true);
|
||||
renderPipelineState.setBufferStandardUniforms(true);
|
||||
renderPipelineState.setBufferNonStandardUniforms(false);
|
||||
renderPipelineState.setUseMaterial(true);
|
||||
renderPipelineState.setUseShadowMap(true);
|
||||
renderPipelineState.setUseBones(true);
|
||||
renderPipelineState.setUseLight(true);
|
||||
|
||||
Matrix4f modelTransformMatrix = new Matrix4f();
|
||||
|
||||
if(Globals.userSettings.graphicsDebugDrawCollisionSpheres()){
|
||||
@ -765,7 +839,7 @@ public class RenderingEngine {
|
||||
// modelTransformMatrix.translate(-0.25f, 0.0f, 0.5f); //center sphere
|
||||
modelTransformMatrix.scale(data.getRadius() * 2);
|
||||
hitboxModel.modelMatrix = modelTransformMatrix;
|
||||
hitboxModel.draw(true, true, false, true, true, true, true);
|
||||
hitboxModel.draw(renderPipelineState);
|
||||
}
|
||||
} else if(data.getType().equals(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HIT)){
|
||||
if((hitboxModel = Globals.assetManager.fetchModel("Models/unitsphere_1.fbx")) != null){
|
||||
@ -777,7 +851,7 @@ public class RenderingEngine {
|
||||
// modelTransformMatrix.translate(-0.25f, 0.0f, 0.5f); //center sphere
|
||||
modelTransformMatrix.scale(data.getRadius() * 2);
|
||||
hitboxModel.modelMatrix = modelTransformMatrix;
|
||||
hitboxModel.draw(true, true, false, true, true, true, true);
|
||||
hitboxModel.draw(renderPipelineState);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -788,7 +862,7 @@ public class RenderingEngine {
|
||||
// modelTransformMatrix.translate(-0.25f, 0.0f, 0.5f); //center sphere
|
||||
modelTransformMatrix.scale(data.getRadius() * 2);
|
||||
hitboxModel.modelMatrix = modelTransformMatrix;
|
||||
hitboxModel.draw(true, true, false, true, true, true, true);
|
||||
hitboxModel.draw(renderPipelineState);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -812,7 +886,7 @@ public class RenderingEngine {
|
||||
// modelTransformMatrix.translate(template.getOffsetX(),template.getOffsetY(),template.getOffsetZ()); //center sphere
|
||||
modelTransformMatrix.scale(template.getDimension1(),template.getDimension2(),template.getDimension3());
|
||||
physicsGraphicsModel.modelMatrix = modelTransformMatrix;
|
||||
physicsGraphicsModel.draw(true, true, false, true, true, true, true);
|
||||
physicsGraphicsModel.draw(renderPipelineState);
|
||||
}
|
||||
break;
|
||||
case "CUBE":
|
||||
@ -828,7 +902,7 @@ public class RenderingEngine {
|
||||
// modelTransformMatrix.translate(template.getOffsetX(),template.getOffsetY(),template.getOffsetZ()); //center sphere
|
||||
modelTransformMatrix.scale(template.getDimension1(),template.getDimension2(),template.getDimension3());
|
||||
physicsGraphicsModel.modelMatrix = modelTransformMatrix;
|
||||
physicsGraphicsModel.draw(true, true, false, true, true, true, true);
|
||||
physicsGraphicsModel.draw(renderPipelineState);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -849,7 +923,7 @@ public class RenderingEngine {
|
||||
// modelTransformMatrix.translate(template.getOffsetX(),template.getOffsetY(),template.getOffsetZ()); //center sphere
|
||||
modelTransformMatrix.scale(scale);
|
||||
physicsGraphicsModel.modelMatrix = modelTransformMatrix;
|
||||
physicsGraphicsModel.draw(true, true, false, true, true, true, true);
|
||||
physicsGraphicsModel.draw(renderPipelineState);
|
||||
}
|
||||
} else if(physicsEntity.containsKey(EntityDataStrings.COLLISION_ENTITY_TYPE_CUBE)){
|
||||
if((physicsGraphicsModel = Globals.assetManager.fetchModel("Models/unitcube.fbx")) != null){
|
||||
@ -864,7 +938,7 @@ public class RenderingEngine {
|
||||
// modelTransformMatrix.translate(template.getOffsetX(),template.getOffsetY(),template.getOffsetZ()); //center sphere
|
||||
modelTransformMatrix.scale(scale);
|
||||
physicsGraphicsModel.modelMatrix = modelTransformMatrix;
|
||||
physicsGraphicsModel.draw(true, true, false, true, true, true, true);
|
||||
physicsGraphicsModel.draw(renderPipelineState);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -889,7 +963,7 @@ public class RenderingEngine {
|
||||
// modelTransformMatrix.translate(template.getOffsetX(),template.getOffsetY(),template.getOffsetZ()); //center sphere
|
||||
modelTransformMatrix.scale(scale);
|
||||
shapeGraphicsModel.modelMatrix = modelTransformMatrix;
|
||||
shapeGraphicsModel.draw(true, true, false, true, true, true, true);
|
||||
shapeGraphicsModel.draw(renderPipelineState);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -922,6 +996,21 @@ public class RenderingEngine {
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Set render pipeline state
|
||||
//
|
||||
renderPipelineState.setUseMeshShader(false);
|
||||
renderPipelineState.setBufferStandardUniforms(true);
|
||||
renderPipelineState.setBufferNonStandardUniforms(false);
|
||||
renderPipelineState.setUseMaterial(true);
|
||||
renderPipelineState.setUseShadowMap(true);
|
||||
renderPipelineState.setUseBones(true);
|
||||
renderPipelineState.setUseLight(true);
|
||||
|
||||
|
||||
|
||||
Matrix4f modelTransformMatrix = new Matrix4f();
|
||||
|
||||
Globals.renderingEngine.setActiveShader(renderNormalsShader);
|
||||
@ -947,7 +1036,7 @@ public class RenderingEngine {
|
||||
modelTransformMatrix.scale(EntityUtils.getScale(currentEntity));
|
||||
currentActor.applyModelMatrix(modelTransformMatrix);
|
||||
//draw
|
||||
currentActor.draw(false);
|
||||
currentActor.draw(renderPipelineState);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1101,6 +1190,17 @@ public class RenderingEngine {
|
||||
|
||||
|
||||
static void renderUI(){
|
||||
//
|
||||
// Set render pipeline state
|
||||
//
|
||||
renderPipelineState.setUseMeshShader(true);
|
||||
renderPipelineState.setBufferStandardUniforms(false);
|
||||
renderPipelineState.setBufferNonStandardUniforms(true);
|
||||
renderPipelineState.setUseMaterial(true);
|
||||
renderPipelineState.setUseShadowMap(false);
|
||||
renderPipelineState.setUseBones(false);
|
||||
renderPipelineState.setUseLight(false);
|
||||
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
for(Element currentElement : Globals.elementManager.getWindowList()){
|
||||
if(currentElement instanceof DrawableElement){
|
||||
@ -1156,6 +1256,18 @@ public class RenderingEngine {
|
||||
|
||||
// glCullFace(GL_FRONT);
|
||||
|
||||
//
|
||||
// Set render pipeline state
|
||||
//
|
||||
renderPipelineState.setUseMeshShader(false);
|
||||
renderPipelineState.setBufferStandardUniforms(false);
|
||||
renderPipelineState.setBufferNonStandardUniforms(true);
|
||||
renderPipelineState.setUseMaterial(false);
|
||||
renderPipelineState.setUseShadowMap(false);
|
||||
renderPipelineState.setUseBones(true);
|
||||
renderPipelineState.setUseLight(false);
|
||||
|
||||
|
||||
//
|
||||
// D R A W A L L E N T I T I E S
|
||||
//
|
||||
@ -1188,7 +1300,7 @@ public class RenderingEngine {
|
||||
currentActor.applyModelMatrix(modelTransformMatrix);
|
||||
//draw
|
||||
// if(!currentEntity.getDataKeys().contains(EntityDataStrings.TERRAIN_IS_TERRAIN) && !currentEntity.getDataKeys().contains(EntityDataStrings.DATA_STRING_CREATURE_IS_CREATURE)){
|
||||
currentActor.drawForDepthBuffer();
|
||||
currentActor.draw(renderPipelineState);
|
||||
// System.out.println(currentActor.modelPath);
|
||||
// }
|
||||
}
|
||||
@ -1216,7 +1328,7 @@ public class RenderingEngine {
|
||||
modelTransformMatrix.rotate(EntityUtils.getRotation(currentEntity));
|
||||
modelTransformMatrix.scale(EntityUtils.getScale(currentEntity));
|
||||
currentActor.applyModelMatrix(modelTransformMatrix);
|
||||
currentActor.drawForDepthBuffer();
|
||||
currentActor.draw(renderPipelineState);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1266,7 +1378,7 @@ public class RenderingEngine {
|
||||
currentActor.applyModelMatrix(modelTransformMatrix);
|
||||
//draw
|
||||
// if(!currentEntity.getDataKeys().contains(EntityDataStrings.TERRAIN_IS_TERRAIN) && !currentEntity.getDataKeys().contains(EntityDataStrings.DATA_STRING_CREATURE_IS_CREATURE)){
|
||||
currentActor.drawForDepthBuffer();
|
||||
currentActor.draw(renderPipelineState);
|
||||
// System.out.println(currentActor.modelPath);
|
||||
// }
|
||||
}
|
||||
@ -1376,5 +1488,50 @@ public class RenderingEngine {
|
||||
float nearClip = 0.001f;
|
||||
Globals.projectionMatrix.setPerspective(radVerticalFOV, RenderingEngine.aspectRatio, nearClip, Globals.userSettings.getGraphicsViewDistance());
|
||||
}
|
||||
|
||||
public static RenderPipelineState getRenderPipelineState(){
|
||||
return renderPipelineState;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks for any errors currently caught by OpenGL.
|
||||
* Refer: https://docs.gl/gl4/glGetError
|
||||
*/
|
||||
private static void checkError(){
|
||||
int error = GL11.glGetError();
|
||||
String errorInEnglish = "";
|
||||
switch(error){
|
||||
case GL11.GL_NO_ERROR: {
|
||||
errorInEnglish = "";
|
||||
} break;
|
||||
case GL11.GL_INVALID_ENUM: {
|
||||
errorInEnglish = "An unacceptable value is specified for an enumerated argument. The offending command is ignored and has no other side effect than to set the error flag.";
|
||||
} break;
|
||||
case GL11.GL_INVALID_VALUE: {
|
||||
errorInEnglish = "A numeric argument is out of range. The offending command is ignored and has no other side effect than to set the error flag.";
|
||||
} break;
|
||||
case GL11.GL_INVALID_OPERATION: {
|
||||
errorInEnglish = "The specified operation is not allowed in the current state. The offending command is ignored and has no other side effect than to set the error flag.";
|
||||
} break;
|
||||
case GL30.GL_INVALID_FRAMEBUFFER_OPERATION: {
|
||||
errorInEnglish = "The framebuffer object is not complete. The offending command is ignored and has no other side effect than to set the error flag. ";
|
||||
} break;
|
||||
case GL11.GL_OUT_OF_MEMORY: {
|
||||
errorInEnglish = "There is not enough memory left to execute the command. The state of the GL is undefined, except for the state of the error flags, after this error is recorded. ";
|
||||
} break;
|
||||
case GL11.GL_STACK_UNDERFLOW: {
|
||||
errorInEnglish = "An attempt has been made to perform an operation that would cause an internal stack to underflow. ";
|
||||
} break;
|
||||
case GL11.GL_STACK_OVERFLOW: {
|
||||
errorInEnglish = "An attempt has been made to perform an operation that would cause an internal stack to overflow. ";
|
||||
} break;
|
||||
default: {
|
||||
errorInEnglish = "Un-enum'd error " + error;
|
||||
} break;
|
||||
}
|
||||
if(!errorInEnglish.equals("")){
|
||||
LoggerInterface.loggerRenderer.ERROR(errorInEnglish, new Exception(errorInEnglish));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -187,6 +187,134 @@ public class ShaderProgram {
|
||||
|
||||
|
||||
|
||||
return rVal;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Intelligently assembles a shader for use in OIT part of render pipeline
|
||||
* @param ContainsBones True if contains bones
|
||||
* @param apply_lighting True if should apply lighting
|
||||
* @return The int-pointer to the shader compiled
|
||||
*/
|
||||
public static ShaderProgram smartAssembleOITProgram(boolean ContainsBones, boolean apply_lighting){
|
||||
|
||||
String vertex_shader_path = "";
|
||||
if(ContainsBones){
|
||||
vertex_shader_path = "/Shaders/oit/general/VertexShader.vs";
|
||||
} else {
|
||||
vertex_shader_path = "/Shaders/oit/general/VertexShaderNoBones.vs";
|
||||
}
|
||||
|
||||
String fragment_shader_path = "/Shaders/oit/general/FragmentShader.fs";
|
||||
//
|
||||
//Create ShaderProgram object
|
||||
//
|
||||
ShaderProgram rVal = new ShaderProgram();
|
||||
//
|
||||
//Read in shader programs
|
||||
//
|
||||
String tempForReadingShaders = "";
|
||||
try {
|
||||
BufferedReader br = new BufferedReader(new InputStreamReader(FileUtils.getAssetFileAsStream(vertex_shader_path)));
|
||||
try {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
String line = br.readLine();
|
||||
|
||||
while (line != null) {
|
||||
sb.append(line);
|
||||
sb.append(System.lineSeparator());
|
||||
line = br.readLine();
|
||||
}
|
||||
tempForReadingShaders = sb.toString();
|
||||
} finally {
|
||||
br.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
}
|
||||
String vertexShaderSource = tempForReadingShaders;
|
||||
//This try-catch block reads the FragmentShader source into memory
|
||||
try {
|
||||
BufferedReader br = new BufferedReader(new InputStreamReader(FileUtils.getAssetFileAsStream(fragment_shader_path)));
|
||||
try {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
String line = br.readLine();
|
||||
while (line != null) {
|
||||
sb.append(line);
|
||||
sb.append(System.lineSeparator());
|
||||
line = br.readLine();
|
||||
}
|
||||
tempForReadingShaders = sb.toString();
|
||||
} finally {
|
||||
br.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
}
|
||||
String fragmentShaderSource = tempForReadingShaders;
|
||||
//Creates a new shader object and assigns its 'pointer' to the integer "vertexShader"
|
||||
rVal.vertexShader = glCreateShader(GL20.GL_VERTEX_SHADER);
|
||||
//This alerts openGL to the presence of a vertex shader and points the shader at its source
|
||||
glShaderSource(rVal.vertexShader, vertexShaderSource);
|
||||
//Compiles the source for the vertex shader object
|
||||
glCompileShader(rVal.vertexShader);
|
||||
//The following tests if the vertex shader compiles successfully
|
||||
int success;
|
||||
success = glGetShaderi(rVal.vertexShader, GL_COMPILE_STATUS);
|
||||
if (success != GL_TRUE) {
|
||||
LoggerInterface.loggerRenderer.WARNING("Vertex Shader failed to compile!");
|
||||
LoggerInterface.loggerRenderer.WARNING("Source is: ");
|
||||
LoggerInterface.loggerRenderer.WARNING(GL20.glGetShaderSource(rVal.vertexShader));
|
||||
LoggerInterface.loggerRenderer.ERROR("Runtime Exception", new RuntimeException(GL20.glGetShaderInfoLog(rVal.vertexShader)));
|
||||
}
|
||||
//Creates and opengl object for a fragment shader and assigns its 'pointer' to the integer fragmentShader
|
||||
rVal.fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
//This points the opengl shadder object to its proper source
|
||||
glShaderSource(rVal.fragmentShader, fragmentShaderSource);
|
||||
//This compiles the shader object
|
||||
glCompileShader(rVal.fragmentShader);
|
||||
//This tests for the success of the compile attempt
|
||||
success = glGetShaderi(rVal.fragmentShader, GL_COMPILE_STATUS);
|
||||
if (success != GL_TRUE) {
|
||||
LoggerInterface.loggerRenderer.WARNING("Fragment Shader failed to compile!");
|
||||
LoggerInterface.loggerRenderer.WARNING("Source is: ");
|
||||
LoggerInterface.loggerRenderer.WARNING(GL20.glGetShaderSource(rVal.fragmentShader));
|
||||
LoggerInterface.loggerRenderer.ERROR("Runtime Exception", new RuntimeException(GL20.glGetShaderInfoLog(rVal.fragmentShader)));
|
||||
}
|
||||
//This creates a shader program opengl object and assigns its 'pointer' to the integer shaderProgram
|
||||
rVal.shaderProgram = glCreateProgram();
|
||||
//This attaches the vertex and fragment shaders to the program
|
||||
glAttachShader(rVal.shaderProgram, rVal.vertexShader);
|
||||
glAttachShader(rVal.shaderProgram, rVal.fragmentShader);
|
||||
//This links the program to the GPU (I think its to the GPU anyway)
|
||||
glLinkProgram(rVal.shaderProgram);
|
||||
//Tests for the success of the shader program creation
|
||||
success = glGetProgrami(rVal.shaderProgram, GL_LINK_STATUS);
|
||||
if (success != GL_TRUE) {
|
||||
throw new RuntimeException(glGetProgramInfoLog(rVal.shaderProgram));
|
||||
}
|
||||
|
||||
//Deletes the individual shader objects to free up memory
|
||||
glDeleteShader(rVal.vertexShader);
|
||||
glDeleteShader(rVal.fragmentShader);
|
||||
|
||||
|
||||
|
||||
//
|
||||
//Set locations
|
||||
//
|
||||
rVal.shaderVertexModelLoc = glGetUniformLocation(rVal.shaderProgram, "model");
|
||||
rVal.shaderVertexViewLoc = glGetUniformLocation(rVal.shaderProgram, "view");
|
||||
rVal.shaderVertexProjectionLoc = glGetUniformLocation(rVal.shaderProgram, "projection");
|
||||
rVal.shaderVertexViewPosLoc = glGetUniformLocation(rVal.shaderProgram, "viewPos");
|
||||
if(ContainsBones){
|
||||
rVal.shaderVertexBonesLoc = glGetUniformLocation(rVal.shaderProgram, "bones");
|
||||
rVal.shaderVertexNumBonesLoc = glGetUniformLocation(rVal.shaderProgram, "numBones");
|
||||
}
|
||||
rVal.shaderVertexHasBonesLoc = glGetUniformLocation(rVal.shaderProgram, "hasBones");
|
||||
|
||||
|
||||
|
||||
|
||||
return rVal;
|
||||
}
|
||||
|
||||
|
||||
@ -3,6 +3,7 @@ package electrosphere.renderer.actor;
|
||||
import electrosphere.engine.Globals;
|
||||
import electrosphere.renderer.Bone;
|
||||
import electrosphere.renderer.Model;
|
||||
import electrosphere.renderer.RenderPipelineState;
|
||||
import electrosphere.renderer.texture.Texture;
|
||||
|
||||
import java.util.HashMap;
|
||||
@ -181,7 +182,7 @@ public class Actor {
|
||||
}
|
||||
}
|
||||
|
||||
public void draw(boolean setShader){
|
||||
public void draw(RenderPipelineState renderPipelineState){
|
||||
Model model = Globals.assetManager.fetchModel(modelPath);
|
||||
boolean hasDrawn = false;
|
||||
if(model != null){
|
||||
@ -210,34 +211,17 @@ public class Actor {
|
||||
if(overrideTextureObject != null){
|
||||
overrideTextureObject.bind();
|
||||
hasDrawn = true;
|
||||
model.draw(setShader, true, false, false, true, true, true);
|
||||
model.draw(renderPipelineState);
|
||||
}
|
||||
}
|
||||
if(!hasDrawn){
|
||||
model.draw(setShader, true, false, true, true, true, true);
|
||||
model.draw(renderPipelineState);
|
||||
}
|
||||
model.getShaderMask().clear();
|
||||
model.setTextureMask(null);
|
||||
}
|
||||
}
|
||||
|
||||
public void drawForDepthBuffer(){
|
||||
Model model = Globals.assetManager.fetchModel(modelPath);
|
||||
if(model != null){
|
||||
// if(animation != null){
|
||||
// model.playAnimation(animation);
|
||||
// model.incrementTime(animationTime);
|
||||
// if(model.currentAnimation == null){
|
||||
// playingAnimation = false;
|
||||
// }
|
||||
// }
|
||||
applyAnimationMasks(model);
|
||||
model.setMeshMask(meshMask);
|
||||
calculateNodeTransforms(model);
|
||||
model.drawForDepthBuffer();
|
||||
}
|
||||
}
|
||||
|
||||
public void drawUI(){
|
||||
Model model = Globals.assetManager.fetchModel(modelPath);
|
||||
if(model != null){
|
||||
|
||||
@ -70,7 +70,7 @@ public class DebugRendering {
|
||||
// Globals.renderingEngine.setActiveShader(Globals.assetManager.fetchShader("Shaders/plane/plane.vs", null, "Shaders/plane/plane.fs"));
|
||||
// }
|
||||
//drawUI sets shader so overriding window bound shader
|
||||
planeModel.draw(false, false, true, false, false, false, false);
|
||||
planeModel.draw(RenderingEngine.getRenderPipelineState());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -94,7 +94,7 @@ public class DebugRendering {
|
||||
// Globals.renderingEngine.setActiveShader(Globals.assetManager.fetchShader("Shaders/plane/plane.vs", null, "Shaders/plane/plane.fs"));
|
||||
// }
|
||||
//drawUI sets shader so overriding window bound shader
|
||||
planeModel.draw(false, false, true, false, false, false, false);
|
||||
planeModel.draw(RenderingEngine.getRenderPipelineState());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,7 +5,7 @@ import java.util.concurrent.TimeUnit;
|
||||
import org.lwjgl.opengl.GL30;
|
||||
import static org.lwjgl.opengl.GL30.GL_FRAMEBUFFER;
|
||||
import static org.lwjgl.opengl.GL30.GL_DRAW_FRAMEBUFFER;
|
||||
import static org.lwjgl.opengl.GL30.GL_FRAMEBUFFER_COMPLETE;
|
||||
import static org.lwjgl.opengl.GL30.*;
|
||||
import static org.lwjgl.opengl.GL30.glBindFramebuffer;
|
||||
import static org.lwjgl.opengl.GL30.glCheckFramebufferStatus;
|
||||
import static org.lwjgl.opengl.GL30.glDeleteFramebuffers;
|
||||
@ -50,7 +50,8 @@ public class Framebuffer {
|
||||
}
|
||||
|
||||
public void blockUntilCompiled(){
|
||||
while(glCheckFramebufferStatus(framebufferPointer) != GL_FRAMEBUFFER_COMPLETE){
|
||||
int status = -1;
|
||||
while((status = glCheckFramebufferStatus(framebufferPointer)) != GL_FRAMEBUFFER_UNDEFINED){
|
||||
try {
|
||||
TimeUnit.MILLISECONDS.sleep(1);
|
||||
} catch (InterruptedException ex) {
|
||||
|
||||
@ -4,6 +4,7 @@ import electrosphere.engine.Globals;
|
||||
import electrosphere.renderer.Material;
|
||||
import electrosphere.renderer.Mesh;
|
||||
import electrosphere.renderer.Model;
|
||||
import electrosphere.renderer.RenderPipelineState.SelectedShaderEnum;
|
||||
|
||||
import static org.lwjgl.opengl.GL30.glBindVertexArray;
|
||||
import static org.lwjgl.opengl.GL30.glGenVertexArrays;
|
||||
@ -183,7 +184,8 @@ public class TreeModelGeneration {
|
||||
Globals.assetManager.addTexturePathtoQueue("/Textures/leavesStylized1.png");
|
||||
m.setMaterial(groundMat);
|
||||
|
||||
m.setShader(Globals.defaultMeshShader);
|
||||
m.generateShader(SelectedShaderEnum.PRIMARY, false, true);
|
||||
m.generateShader(SelectedShaderEnum.OIT, false, true);
|
||||
m.parent = rVal;
|
||||
|
||||
rVal.meshes.add(m);
|
||||
|
||||
@ -99,9 +99,26 @@ public class ActorPanel implements DrawableElement, DraggableElement {
|
||||
actor.incrementAnimationTime(0.0001);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Set rendering engine state
|
||||
//
|
||||
RenderingEngine.getRenderPipelineState().setUseMeshShader(true);
|
||||
RenderingEngine.getRenderPipelineState().setBufferStandardUniforms(true);
|
||||
RenderingEngine.getRenderPipelineState().setBufferNonStandardUniforms(true);
|
||||
RenderingEngine.getRenderPipelineState().setUseMaterial(true);
|
||||
RenderingEngine.getRenderPipelineState().setUseShadowMap(true);
|
||||
RenderingEngine.getRenderPipelineState().setUseBones(true);
|
||||
RenderingEngine.getRenderPipelineState().setUseLight(true);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
actor.applyModelMatrix(modelMatrix);
|
||||
actor.draw(true);
|
||||
actor.draw(RenderingEngine.getRenderPipelineState());
|
||||
|
||||
RenderingEngine.setFOV(Globals.verticalFOV);
|
||||
RenderingEngine.setAspectRatio(Globals.aspectRatio);
|
||||
@ -124,7 +141,26 @@ public class ActorPanel implements DrawableElement, DraggableElement {
|
||||
Vector3f boxDimensions = new Vector3f(ndcWidth,ndcHeight,0);
|
||||
|
||||
Globals.renderingEngine.setActiveShader(Globals.assetManager.fetchShader("Shaders/ui/windowContent/windowContent.vs", null, "Shaders/ui/windowContent/windowContent.fs"));
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Set rendering engine state
|
||||
//
|
||||
RenderingEngine.getRenderPipelineState().setUseMeshShader(false);
|
||||
RenderingEngine.getRenderPipelineState().setBufferStandardUniforms(false);
|
||||
RenderingEngine.getRenderPipelineState().setBufferNonStandardUniforms(true);
|
||||
RenderingEngine.getRenderPipelineState().setUseMaterial(true);
|
||||
RenderingEngine.getRenderPipelineState().setUseShadowMap(false);
|
||||
RenderingEngine.getRenderPipelineState().setUseBones(false);
|
||||
RenderingEngine.getRenderPipelineState().setUseLight(false);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Model planeModel = Globals.assetManager.fetchModel(Globals.imagePlaneModelID);
|
||||
if(planeModel != null){
|
||||
planeModel.pushUniformToMesh("plane", "mPosition", boxPosition);
|
||||
@ -132,7 +168,7 @@ public class ActorPanel implements DrawableElement, DraggableElement {
|
||||
planeModel.pushUniformToMesh("plane", "tPosition", texPosition);
|
||||
planeModel.pushUniformToMesh("plane", "tDimension", texScale);
|
||||
planeModel.meshes.get(0).setMaterial(customMat);
|
||||
planeModel.draw(false, false, true, true, false, false, false);
|
||||
planeModel.draw(RenderingEngine.getRenderPipelineState());
|
||||
} else {
|
||||
LoggerInterface.loggerRenderer.ERROR("Actor Panel unable to find plane model!!", new Exception());
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user