OIT start

This commit is contained in:
austin 2022-03-18 17:19:45 -04:00
parent 0e073689c4
commit 2f0af2f096
14 changed files with 420 additions and 29 deletions

View File

@ -0,0 +1,55 @@
#version 420 core
// shader outputs
layout (location = 0) out vec4 frag;
// color accumulation buffer
layout (binding = 0) uniform sampler2D accum;
// revealage threshold buffer
layout (binding = 1) uniform sampler2D reveal;
// epsilon number
const float EPSILON = 0.00001f;
// caluclate floating point numbers equality accurately
bool isApproximatelyEqual(float a, float b)
{
return abs(a - b) <= (abs(a) < abs(b) ? abs(b) : abs(a)) * EPSILON;
}
// get the max value between three values
float max3(vec3 v)
{
return max(max(v.x, v.y), v.z);
}
void main()
{
// fragment coordination
ivec2 coords = ivec2(gl_FragCoord.xy);
// fragment revealage
float revealage = texelFetch(reveal, coords, 0).r;
// save the blending and color texture fetch cost if there is not a transparent fragment
if (isApproximatelyEqual(revealage, 1.0f)){
discard;
}
// fragment color
vec4 accumulation = texelFetch(accum, coords, 0);
// suppress overflow
if (isinf(max3(abs(accumulation.rgb)))){
accumulation.rgb = vec3(accumulation.a);
}
// prevent floating point precision bug
vec3 average_color = accumulation.rgb / max(accumulation.a, EPSILON);
// blend pixels
frag = vec4(average_color, 1.0f - revealage);
// frag = vec4(accumulation.rgb, 1.0f - revealage);
// frag = vec4(0,0,0,0);
}

View File

@ -0,0 +1,9 @@
#version 420 core
// shader inputs
layout (location = 0) in vec3 position;
void main()
{
gl_Position = vec4(position, 1.0f);
}

View File

@ -0,0 +1,30 @@
#version 330 core
out vec4 FragColor;
in vec2 TexCoords;
uniform sampler2D screenTexture;
uniform float channel;
void main(){
switch(int(channel)){
case 0:
FragColor = vec4(texture(screenTexture, TexCoords).r,0,0,1);
break;
case 1:
FragColor = vec4(0,texture(screenTexture, TexCoords).g,0,1);
break;
case 2:
FragColor = vec4(0,0,texture(screenTexture, TexCoords).b,1);
break;
case 3:
FragColor = vec4(texture(screenTexture, TexCoords).a,texture(screenTexture, TexCoords).a,texture(screenTexture, TexCoords).a,1);
break;
case 4:
FragColor = vec4(vec3(texture(screenTexture, TexCoords)),1.0);
default:
FragColor = vec4(1,1,1,1);
break;
}
}

View File

@ -0,0 +1,10 @@
#version 330 core
layout (location = 0) in vec2 aPos;
layout (location = 1) in vec2 aTexCoords;
out vec2 TexCoords;
void main(){
gl_Position = vec4(aPos.x, aPos.y, 0.0, 1.0);
TexCoords = aTexCoords;
}

View File

@ -0,0 +1,9 @@
#version 330 core
out vec4 FragColor;
in vec2 TexCoords;
void main(){
vec4(vec3(gl_FragCoord.z), 1.0);
}

View File

@ -0,0 +1,10 @@
#version 330 core
layout (location = 0) in vec2 aPos;
layout (location = 1) in vec2 aTexCoords;
out vec2 TexCoords;
void main(){
gl_Position = vec4(aPos.x, aPos.y, 0.0, 1.0);
TexCoords = aTexCoords;
}

View File

@ -30,13 +30,16 @@ THE FLAME FUNCTION IS ONE CREATED BY ME BLENDING A LOG2 INTO A EXPONENTIAL.
*/
//version
#version 330 core
#version 420 core
//macros
#extension GL_ARB_explicit_uniform_location : enable
//output
out vec4 fragColor;
// out vec4 fragColor;
layout (location = 0) out vec4 accum;
layout (location = 1) out float reveal;
//input
in vec3 FragPos;
@ -49,6 +52,7 @@ in vec4 modelCoord;
uniform float time;
//layout uniforms
layout (location = 3) uniform sampler2D shadowMap;
layout (location = 5) uniform sampler2D volumeDepthFrontface;
layout (location = 6) uniform sampler2D volumeDepthBackface;
@ -104,6 +108,8 @@ void main(){
float blue = 0.7366;
float alpha = volume * 10.0;
// alpha = 0.5;
// float red = volume * 10.0;
// float green = volume * 10.0;
// float blue = volume * 10.0;
@ -115,13 +121,26 @@ void main(){
blue,
alpha
);
// weight function
float weight = clamp(pow(min(1.0, color.a * 10.0) + 0.01, 3.0) * 1e8 * pow(1.0 - gl_FragCoord.z * 0.9, 3.0), 1e-2, 3e3);
// weight = 1.0;
// store pixel color accumulation
accum = vec4(color.rgb * color.a, color.a) * weight;
// store pixel revealage threshold
reveal = color.a;
// reveal = 1.0;
// if(val < 0.3){
// discard;
// }
// Output to screen
fragColor = color;
// fragColor = color;
}

View File

@ -1,5 +1,5 @@
//Vertex Shader
#version 330 core
#version 420 core
@ -40,5 +40,8 @@ void main() {
modelCoord = FinalVertex;
//set final position with opengl space
gl_Position = projection * view * model * FinalVertex;
vec4 outVec = projection * view * model * FinalVertex;
// outVec.z = outVec.z - 0.1f;
// outVec.z = -0.9;
gl_Position = outVec;
}

View File

@ -732,6 +732,8 @@ public class LoadingThread extends Thread {
EntityUtils.getActor(water).addTextureMask(RenderUtils.generateVolumetricTextureMask("Cube"));
//set draw volumetric
water.putData(EntityDataStrings.DRAW_VOLUMETRIC, true);
water.removeData(EntityDataStrings.DRAW_SOLID_PASS);
water.putData(EntityDataStrings.DRAW_TRANSPARENT_PASS, true);
// goblin = CreatureUtils.spawnBasicCreature("Goblin");

View File

@ -16,6 +16,8 @@ public class EntityDataStrings {
public static final String DATA_STRING_MODEL_PATH = "modelPath";
public static final String DATA_STRING_ACTOR = "actor";
public static final String DATA_STRING_DRAW = "drawFlag";
public static final String DRAW_SOLID_PASS = "drawSolidPass";
public static final String DRAW_TRANSPARENT_PASS = "drawTransparentPass";
public static final String DRAW_CAST_SHADOW = "castShadow";
public static final String DRAW_VOLUMETRIC = "drawVolumetric";

View File

@ -48,6 +48,7 @@ public class EntityUtils {
rVal.putData(EntityDataStrings.DATA_STRING_ROTATION, new Quaternionf().identity());
rVal.putData(EntityDataStrings.DATA_STRING_SCALE, new Vector3f(1,1,1));
rVal.putData(EntityDataStrings.DATA_STRING_DRAW, true);
rVal.putData(EntityDataStrings.DRAW_SOLID_PASS, true);
Globals.entityManager.registerEntity(rVal);
Globals.entityManager.registerDrawableEntity(rVal);
return rVal;
@ -60,6 +61,7 @@ public class EntityUtils {
rVal.putData(EntityDataStrings.DATA_STRING_ROTATION, new Quaternionf().rotateAxis((float)0, new Vector3f(1,0,0)));
rVal.putData(EntityDataStrings.DATA_STRING_SCALE, new Vector3f(1,1,1));
rVal.putData(EntityDataStrings.DATA_STRING_DRAW, true);
rVal.putData(EntityDataStrings.DRAW_SOLID_PASS, true);
Globals.entityManager.registerEntity(rVal);
Globals.entityManager.registerDrawableEntity(rVal);
return rVal;

View File

@ -73,10 +73,22 @@ import static org.lwjgl.opengl.GL11.GL_FOG_MODE;
import static org.lwjgl.opengl.GL11.GL_FOG_START;
import static org.lwjgl.opengl.GL11.GL_LINEAR;
import static org.lwjgl.opengl.GL11.GL_NEAREST;
import static org.lwjgl.opengl.GL11.GL_LESS;
import static org.lwjgl.opengl.GL11.GL_LEQUAL;
import static org.lwjgl.opengl.GL11.GL_EQUAL;
import static org.lwjgl.opengl.GL11.GL_GREATER;
import static org.lwjgl.opengl.GL11.GL_ONE_MINUS_SRC_ALPHA;
import static org.lwjgl.opengl.GL11.GL_SRC_ALPHA;
import static org.lwjgl.opengl.GL11.GL_TEXTURE_2D;
import static org.lwjgl.opengl.GL11.GL_TRIANGLES;
import static org.lwjgl.opengl.GL11.GL_FALSE;
import static org.lwjgl.opengl.GL11.GL_ONE;
import static org.lwjgl.opengl.GL11.GL_ZERO;
import static org.lwjgl.opengl.GL11.GL_COLOR;
import static org.lwjgl.opengl.GL11.GL_ONE_MINUS_SRC_COLOR;
import static org.lwjgl.opengl.GL11.GL_ALWAYS;
import static org.lwjgl.opengl.GL11.glDepthFunc;
import static org.lwjgl.opengl.GL11.glDepthMask;
import static org.lwjgl.opengl.GL11.glBindTexture;
import static org.lwjgl.opengl.GL11.glBlendFunc;
import static org.lwjgl.opengl.GL11.glClear;
@ -91,15 +103,22 @@ import static org.lwjgl.opengl.GL13.GL_TEXTURE1;
import static org.lwjgl.opengl.GL13.GL_TEXTURE2;
import static org.lwjgl.opengl.GL13.GL_TEXTURE3;
import static org.lwjgl.opengl.GL13.glActiveTexture;
import static org.lwjgl.opengl.GL14.GL_FUNC_ADD;
import static org.lwjgl.opengl.GL20.glGetUniformLocation;
import static org.lwjgl.opengl.GL20.glUniformMatrix4fv;
import static org.lwjgl.opengl.GL20.glUseProgram;
import static org.lwjgl.opengl.GL20.glUniform1f;
import static org.lwjgl.opengl.GL30.GL_FRAMEBUFFER;
import static org.lwjgl.opengl.GL30.GL_RENDERBUFFER;
import static org.lwjgl.opengl.GL30.GL_COLOR_ATTACHMENT0;
import static org.lwjgl.opengl.GL30.GL_COLOR_ATTACHMENT1;
import static org.lwjgl.opengl.GL30.glBindFramebuffer;
import static org.lwjgl.opengl.GL30.glBindRenderbuffer;
import static org.lwjgl.opengl.GL30.glBindVertexArray;
import static org.lwjgl.opengl.GL30.glBlitFramebuffer;
import static org.lwjgl.opengl.GL30.glClearBufferfv;
import static org.lwjgl.opengl.GL40.glBlendFunci;
import static org.lwjgl.opengl.GL40.glBlendEquation;
import static org.lwjgl.system.MemoryUtil.NULL;
public class RenderingEngine {
@ -108,14 +127,27 @@ public class RenderingEngine {
public static final int GL_DEFAULT_FRAMEBUFFER = 0;
public static final int GL_DEFAULT_RENDERBUFFER = 0;
static Texture screenTextureColor;
static Texture screenTextureDepth;
static Framebuffer screenFramebuffer;
static Renderbuffer screenRenderbuffer;
static int screenTextureVAO;
static ShaderProgram screenTextureShaders;
static ShaderProgram drawChannel;
//depth framebuffer/shader for shadow mapping
static ShaderProgram lightDepthShaderProgram;
static Framebuffer lightDepthBuffer;
//framebuffers for transparent textures
static float[] transparencyAccumulatorClear;
static Texture transparencyAccumulatorTexture;
static float[] transparencyRevealageClear;
static Texture transparencyRevealageTexture;
static Framebuffer transparencyBuffer;
static ShaderProgram oitCompositeProgram;
static Matrix4f nearVolumeProjectionMatrix = new Matrix4f();
static Matrix4f midVolumeProjectionMatrix = new Matrix4f();
static Matrix4f farVolumeProjectionMatrix = new Matrix4f();
@ -223,10 +255,17 @@ public class RenderingEngine {
// screenTextureShaders = ShaderProgram.loadSpecificShader("/Shaders/screentexture/drawDepthBuffer/drawDepthBuffer.vs", "/Shaders/screentexture/drawDepthBuffer/drawDepthBuffer.fs");
//generate framebuffers
screenFramebuffer = FramebufferUtils.generateScreensizeTextureFramebuffer();
screenTextureColor = FramebufferUtils.generateScreenTextureColor(Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT);
screenTextureDepth = FramebufferUtils.generateScreenTextureDepth(Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT);
screenFramebuffer = FramebufferUtils.generateScreenTextureFramebuffer(Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT, screenTextureColor, screenTextureDepth);
glBindFramebuffer(GL_FRAMEBUFFER, GL_DEFAULT_FRAMEBUFFER);
glBindRenderbuffer(GL_RENDERBUFFER, GL_DEFAULT_RENDERBUFFER);
//
//Channel debug program
//
drawChannel = ShaderProgram.loadSpecificShader("/Shaders/screentexture/drawChannel/drawChannel.vs", "/Shaders/screentexture/drawChannel/drawChannel.fs");
//
//create light depth framebuffer/shader for shadowmapping
//
@ -244,10 +283,19 @@ public class RenderingEngine {
volumeDepthBackfaceFramebuffer = FramebufferUtils.generateDepthBuffer(Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT, volumeDepthBackfaceTexture);
volumeDepthFrontfaceTexture = FramebufferUtils.generateDepthBufferTexture(Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT);
volumeDepthFrontfaceFramebuffer = FramebufferUtils.generateDepthBuffer(Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT, volumeDepthFrontfaceTexture);
//
//Transparency framebuffers
//
transparencyAccumulatorClear = new float[]{0.0f, 0.0f, 0.0f, 0.0f};
transparencyAccumulatorTexture = FramebufferUtils.generateOITAccumulatorTexture(Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT);
transparencyRevealageClear = new float[]{1.0f, 0.0f, 0.0f, 0.0f};
transparencyRevealageTexture = FramebufferUtils.generateOITRevealageTexture(Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT);
transparencyBuffer = FramebufferUtils.generateOITFramebuffer(Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT, transparencyAccumulatorTexture, transparencyRevealageTexture, screenTextureDepth);
oitCompositeProgram = ShaderProgram.loadSpecificShader("Shaders/oit/composite.vs", "Shaders/oit/composite.fs");
//projection matrices
nearVolumeProjectionMatrix.setPerspective((float)(Globals.verticalFOV * Math.PI /180.0f), (float)Globals.WINDOW_WIDTH / (float)Globals.WINDOW_HEIGHT, 0.1f, 100);
// midVolumeProjectionMatrix.setPerspective((float)(Globals.verticalFOV * Math.PI /180.0f), (float)Globals.WINDOW_WIDTH / (float)Globals.WINDOW_HEIGHT, 0.01f, 7);
// farVolumeProjectionMatrix.setPerspective((float)(Globals.verticalFOV * Math.PI /180.0f), (float)Globals.WINDOW_WIDTH / (float)Globals.WINDOW_HEIGHT, 0.1f, 50);
//instantiate light manager
@ -489,16 +537,22 @@ public class RenderingEngine {
//bind screen fbo
screenFramebuffer.bind();
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
glDepthMask(true);
glViewport(0, 0, Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT);
///
/// R E N D E R I N G S T U F F
///
//Sets the background color.
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//
// Pass One: Solids
//
//
// D R A W A L L E N T I T I E S
//
@ -506,15 +560,14 @@ public class RenderingEngine {
modelTransformMatrix = new Matrix4f();
for(Entity currentEntity : Globals.entityManager.getDrawable()){
Vector3d position = EntityUtils.getPosition(currentEntity);
if((boolean)currentEntity.getData(EntityDataStrings.DATA_STRING_DRAW) && drawPoint(cameraPos,new Vector3f((float)position.x,(float)position.y,(float)position.z))){
if(
(boolean)currentEntity.getData(EntityDataStrings.DATA_STRING_DRAW) &&
currentEntity.getData(EntityDataStrings.DRAW_SOLID_PASS) != null &&
drawPoint(cameraPos,new Vector3f((float)position.x,(float)position.y,(float)position.z))
){
//fetch actor
Actor currentActor = EntityUtils.getActor(currentEntity);
currentActor.incrementAnimationTime(0.001);
//increment animations
//this is incremented in the shadow calculations
// if(currentActor.getCurrentAnimation() != null){
// currentActor.incrementAnimationTime(deltaTime * 500);
// }
//calculate camera-modified vector3f
Vector3f cameraModifiedPosition = new Vector3f((float)position.x,(float)position.y,(float)position.z).sub(CameraEntityUtils.getCameraCenter(Globals.playerCamera));
//calculate and apply model transform
@ -525,22 +578,77 @@ public class RenderingEngine {
currentActor.applyModelMatrix(modelTransformMatrix);
//draw
currentActor.draw();
// Model currentModel = Globals.assetManager.fetchModel(EntityUtils.getEntityModelPath(currentEntity));
// if(currentModel != null){
// if(currentModel.currentAnimation != null){
// currentModel.incrementTime(deltaTime * 500);
// }
// currentModel.modelMatrix = new Matrix4f();
// currentModel.modelMatrix.translate(new Vector3f(EntityUtils.getEntityPosition(currentEntity)).sub(CameraEntityUtils.getCameraCenter(Globals.playerCamera)).sub(new Vector3f(0,1,0)));
// currentModel.modelMatrix.rotate(EntityUtils.getEntityRotation(currentEntity));
// currentModel.modelMatrix.scale(EntityUtils.getEntityScale(currentEntity));
// currentModel.draw();
// }
}
}
//
// Pass Two: Transparency Accumulator + Revealage
//
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);
glBlendEquation(GL_FUNC_ADD);
transparencyBuffer.bind();
glClearBufferfv(GL_COLOR,0,transparencyAccumulatorClear);
glClearBufferfv(GL_COLOR,1,transparencyRevealageClear);
for(Entity currentEntity : Globals.entityManager.getDrawable()){
Vector3d position = EntityUtils.getPosition(currentEntity);
if(
(boolean)currentEntity.getData(EntityDataStrings.DATA_STRING_DRAW) &&
currentEntity.getData(EntityDataStrings.DRAW_TRANSPARENT_PASS) != null &&
drawPoint(cameraPos,new Vector3f((float)position.x,(float)position.y,(float)position.z))
){
//fetch actor
Actor currentActor = EntityUtils.getActor(currentEntity);
currentActor.incrementAnimationTime(0.001);
//calculate camera-modified vector3f
Vector3f cameraModifiedPosition = new Vector3f((float)position.x,(float)position.y,(float)position.z).sub(CameraEntityUtils.getCameraCenter(Globals.playerCamera));
//calculate and apply model transform
modelTransformMatrix.identity();
modelTransformMatrix.translate(cameraModifiedPosition);
modelTransformMatrix.rotate(EntityUtils.getRotation(currentEntity));
modelTransformMatrix.scale(EntityUtils.getScale(currentEntity));
currentActor.applyModelMatrix(modelTransformMatrix);
//draw
currentActor.draw();
}
}
//
// Pass Three: Composite transparency on top of solids
//
glDepthFunc(GL_ALWAYS);
// glDepthMask(false);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
screenFramebuffer.bind();
Globals.renderingEngine.setActiveShader(oitCompositeProgram);
glBindVertexArray(screenTextureVAO);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, 0);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, 0);
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, 0);
glActiveTexture(GL_TEXTURE3);
glBindTexture(GL_TEXTURE_2D, 0);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, transparencyAccumulatorTexture.getTexturePointer());
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, transparencyRevealageTexture.getTexturePointer());
glDrawArrays(GL_TRIANGLES, 0, 6);
glBindVertexArray(0);
// glBindVertexArray(0);
}
@ -732,6 +840,18 @@ public class RenderingEngine {
glBindTexture(GL_TEXTURE_2D, volumeDepthBackfaceTexture.getTexturePointer());
} else if(outputFramebuffer == 3){
glBindTexture(GL_TEXTURE_2D, volumeDepthFrontfaceTexture.getTexturePointer());
} else if(outputFramebuffer == 4){
glBindTexture(GL_TEXTURE_2D, transparencyAccumulatorTexture.getTexturePointer());
} else if(outputFramebuffer == 5){
glBindTexture(GL_TEXTURE_2D, transparencyRevealageTexture.getTexturePointer());
} else if(outputFramebuffer == 6){
Globals.renderingEngine.setActiveShader(drawChannel);
glUniform1f(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "channel"),0);
glBindTexture(GL_TEXTURE_2D, transparencyRevealageTexture.getTexturePointer());
} else if(outputFramebuffer == 7){
Globals.renderingEngine.setActiveShader(drawChannel);
glUniform1f(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "channel"),4);
glBindTexture(GL_TEXTURE_2D, screenTextureDepth.getTexturePointer());
}
glDrawArrays(GL_TRIANGLES, 0, 6);
glBindVertexArray(0);
@ -766,6 +886,8 @@ public class RenderingEngine {
//set the viewport to shadow map size
glViewport(0, 0, Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
glDepthMask(true);
//stop rendering front faces
GL15.glEnable(GL15.GL_CULL_FACE);
@ -966,7 +1088,7 @@ public class RenderingEngine {
public static void incrementOutputFramebuffer(){
outputFramebuffer++;
if(outputFramebuffer > 3){
if(outputFramebuffer > 7){
outputFramebuffer = 0;
}
}

View File

@ -4,6 +4,7 @@ import electrosphere.logger.LoggerInterface;
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.glBindFramebuffer;
import static org.lwjgl.opengl.GL30.glCheckFramebufferStatus;

View File

@ -4,9 +4,13 @@ import electrosphere.logger.LoggerInterface;
import electrosphere.main.Globals;
import electrosphere.renderer.texture.Texture;
import java.nio.IntBuffer;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.lwjgl.BufferUtils;
import static org.lwjgl.opengl.GL11.GL_DEPTH_COMPONENT;
import static org.lwjgl.opengl.GL11.GL_FLOAT;
import static org.lwjgl.opengl.GL11.GL_LINEAR;
@ -31,13 +35,20 @@ import static org.lwjgl.opengl.GL11.glTexParameterfv;
import static org.lwjgl.opengl.GL11.glTexParameteri;
import static org.lwjgl.opengl.GL12.GL_CLAMP_TO_EDGE;
import static org.lwjgl.opengl.GL13.GL_CLAMP_TO_BORDER;
import static org.lwjgl.opengl.GL20.glDrawBuffers;
import static org.lwjgl.opengl.GL30.GL_COLOR_ATTACHMENT0;
import static org.lwjgl.opengl.GL30.GL_COLOR_ATTACHMENT1;
import static org.lwjgl.opengl.GL30.GL_DEPTH24_STENCIL8;
import static org.lwjgl.opengl.GL30.GL_DEPTH_ATTACHMENT;
import static org.lwjgl.opengl.GL30.GL_DEPTH_STENCIL_ATTACHMENT;
import static org.lwjgl.opengl.GL30.GL_FRAMEBUFFER;
import static org.lwjgl.opengl.GL30.GL_FRAMEBUFFER_COMPLETE;
import static org.lwjgl.opengl.GL30.GL_RENDERBUFFER;
import static org.lwjgl.opengl.GL30.GL_RGBA16F;
import static org.lwjgl.opengl.GL30.GL_HALF_FLOAT;
import static org.lwjgl.opengl.GL30.GL_R8;
import static org.lwjgl.opengl.GL30.GL_RED;
import static org.lwjgl.opengl.GL30.glBindFramebuffer;
import static org.lwjgl.opengl.GL30.glBindRenderbuffer;
import static org.lwjgl.opengl.GL30.glCheckFramebufferStatus;
import static org.lwjgl.opengl.GL30.glFramebufferRenderbuffer;
@ -51,8 +62,58 @@ import static org.lwjgl.system.MemoryUtil.NULL;
* @author amaterasu
*/
public class FramebufferUtils {
public static Texture generateScreenTextureColor(int width, int height){
int texturePtr = glGenTextures();
glBindTexture(GL_TEXTURE_2D,texturePtr);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
//these make sure the texture actually clamps to the borders of the quad
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
Texture texture = new Texture(texturePtr);
return texture;
}
public static Texture generateScreenTextureDepth(int width, int height){
int texturePtr = glGenTextures();
glBindTexture(GL_TEXTURE_2D,texturePtr);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, width, height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
Texture texture = new Texture(texturePtr);
return texture;
}
public static Framebuffer generateScreenTextureFramebuffer(int width, int height, Texture colorTexture, Texture depthTexture){
Framebuffer buffer = new Framebuffer();
buffer.bind();
//texture
// int texture = glGenTextures();
// glBindTexture(GL_TEXTURE_2D,texture);
// glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// //these make sure the texture actually clamps to the borders of the quad
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
buffer.setTexturePointer(colorTexture.getTexturePointer());
//bind texture to fbo
int mipMapLevel = 0;
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTexture.getTexturePointer(), mipMapLevel);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTexture.getTexturePointer(), mipMapLevel);
//check make sure compiled
if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE){
System.out.println("Framebuffer is not complete!");
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
return buffer;
}
public static Framebuffer generateScreensizeTextureFramebuffer(){
Framebuffer buffer = new Framebuffer();
buffer.bind();
@ -202,5 +263,61 @@ public class FramebufferUtils {
return buffer;
}
public static Texture generateOITAccumulatorTexture(int width, int height){
int texturePtr = glGenTextures();
glBindTexture(GL_TEXTURE_2D,texturePtr);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, width, height, 0, GL_RGBA, GL_HALF_FLOAT, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glBindTexture(GL_TEXTURE_2D, 0);
Texture texture = new Texture(texturePtr);
return texture;
}
public static Texture generateOITRevealageTexture(int width, int height){
int texturePtr = glGenTextures();
glBindTexture(GL_TEXTURE_2D,texturePtr);
glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, width, height, 0, GL_RED, GL_FLOAT, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glBindTexture(GL_TEXTURE_2D, 0);
Texture texture = new Texture(texturePtr);
return texture;
}
public static Framebuffer generateOITFramebuffer(int width, int height, Texture accumulatorTex, Texture revealageTex, Texture depthTexture){
Framebuffer buffer = new Framebuffer();
buffer.bind();
//texture
buffer.setTexturePointer(accumulatorTex.getTexturePointer());
//bind texture to fbo
int mipMapLevel = 0;
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, accumulatorTex.getTexturePointer(), mipMapLevel);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, revealageTex.getTexturePointer(), mipMapLevel);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTexture.getTexturePointer(), mipMapLevel);
// const GLenum transparentDrawBuffers[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 };
// glDrawBuffers(2, transparentDrawBuffers);
IntBuffer drawBuffers = BufferUtils.createIntBuffer(2);
drawBuffers.put(GL_COLOR_ATTACHMENT0);
drawBuffers.put(GL_COLOR_ATTACHMENT1);
drawBuffers.flip();
glDrawBuffers(drawBuffers);
//check make sure compiled
if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE){
System.out.println("Framebuffer is not complete!");
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
return buffer;
}
}