Good first pass at anime outline shader

This commit is contained in:
austin 2022-03-25 16:09:18 -04:00
parent 4cf3a0e2d4
commit e729c53e3c
20 changed files with 451 additions and 95 deletions

View File

@ -56,7 +56,8 @@
"GRAVITY",
"TARGETABLE",
"CAN_EQUIP",
"INVENTORY"
"INVENTORY",
"OUTLINE"
],
"visualAttributes" : [],
"movementSystems" : [

View File

@ -30,7 +30,8 @@
"GRAVITY",
"BLENDER_TRANSFORM",
"MELEE",
"TARGETABLE"
"TARGETABLE",
"OUTLINE"
],
"equipClass" : "weapon",
"idleAnim" : "Sword|Idle",
@ -55,7 +56,8 @@
"tokens" : [
"GRAVITY",
"RANGED",
"TARGETABLE"
"TARGETABLE",
"OUTLINE"
],
"equipClass" : "weapon",
"collidable": {

View File

@ -0,0 +1,30 @@
#version 420 core
// shader outputs
layout (location = 0) out vec4 frag;
// color accumulation buffer
layout (binding = 0) uniform sampler2D texture;
void main(){
// fragment coordination
ivec2 coords = ivec2(gl_FragCoord.xy);
// fragment color
vec4 color = texelFetch(texture, coords, 0);
float val = color.r;
// if(color.r < 0.5){z
// discard;
// }
vec4 outColor = vec4(0);
if(val == 1){
outColor = vec4(0,0,0,1);
// outColor.a = 1;
}
frag = outColor;
}

View File

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

View File

@ -0,0 +1,134 @@
#version 330 core
out vec4 FragColor;
in vec2 TexCoords;
uniform sampler2D screenTexture;
const float offset = 1.0 / 2000.0;
int posToIndex(int x, int y);
float calculateAveragedEdge(int x, int y, vec3 sT[25]);
void main(){
vec2 offsets[25] = vec2[25](
vec2(-2 * offset, 2 * offset),
vec2(-2 * offset, 1 * offset),
vec2(-2 * offset, 0 * offset),
vec2(-2 * offset, -1 * offset),
vec2(-2 * offset, -2 * offset),
vec2(-1 * offset, 2 * offset),
vec2(-1 * offset, 1 * offset),
vec2(-1 * offset, 0 * offset),
vec2(-1 * offset, -1 * offset),
vec2(-1 * offset, -2 * offset),
vec2( 0 * offset, 2 * offset),
vec2( 0 * offset, 1 * offset),
vec2( 0 * offset, 0 * offset),
vec2( 0 * offset, -1 * offset),
vec2( 0 * offset, -2 * offset),
vec2( 1 * offset, 2 * offset),
vec2( 1 * offset, 1 * offset),
vec2( 1 * offset, 0 * offset),
vec2( 1 * offset, -1 * offset),
vec2( 1 * offset, -2 * offset),
vec2( 2 * offset, 2 * offset),
vec2( 2 * offset, 1 * offset),
vec2( 2 * offset, 0 * offset),
vec2( 2 * offset, -1 * offset),
vec2( 2 * offset, -2 * offset)
);
// vec2 offsets[9] = vec2[](
// vec2(-offset, offset), // top-left
// vec2( 0.0f, offset), // top-center
// vec2( offset, offset), // top-right
// vec2(-offset, 0.0f), // center-left
// vec2( 0.0f, 0.0f), // center-center
// vec2( offset, 0.0f), // center-right
// vec2(-offset, -offset), // bottom-left
// vec2( 0.0f, -offset), // bottom-center
// vec2( offset, -offset) // bottom-right
// );
// float kernel[9] = float[](
// -1, -1, -1,
// -1, 9, -1,
// -1, -1, -1
// );
vec3 sT[25];
for(int x = 0; x < 5; x++){
for(int y = 0; y < 5; y++){
sT[x * 5 + y] = texture(screenTexture, TexCoords.st + offsets[x * 5 + y]).xyz;
}
}
// vec3 Gx = (-sT[0] + sT[2]) + 2 * (-sT[3] + sT[5]) + (-sT[6] + sT[8]);
// vec3 Gy = (sT[0] + 2 * sT[1] + sT[2]) - (sT[6] + 2 * sT[7] + sT[8]);
// vec3 G = sqrt(Gx * Gx + Gy * Gy);
// float averaged = (G.x + G.y + G.z)/3.0;
float vals[9];
for(int x = 0; x < 3; x++){
for(int y = 0; y < 3; y++){
vals[x * 3 + y] = calculateAveragedEdge(x,y,sT);
}
}
float rVal = 0;
float cutoff1 = 0.6;
float cutoff2 = 0.1;
float cutoff3 = 0.5;
float surroundAvg = (vals[0] + vals[2] + vals[6] + vals[8])/4.0;
if(
//center
vals[4] > cutoff1 &&
surroundAvg > cutoff3
// //plus
// vals[1] > cutoff2 &&
// vals[3] > cutoff2 &&
// vals[5] > cutoff2 &&
// vals[7] > cutoff2 //&&
// // //diag
// vals[0] < cutoff3 &&
// vals[2] < cutoff3 &&
// vals[6] < cutoff3 &&
// vals[8] < cutoff3
){
rVal = min(vals[4],1.0);
}
// rVal = calculateAveragedEdge(1,1,sT);
// if(rVal < 0.8){
// rVal = 0;
// }
// vec3 col = vec3(0.0);
// for(int i = 0; i < 9; i++){
// col += sampleTex[i] * kernel[i];
// }
FragColor = vec4(rVal,rVal,rVal,1);
}
float calculateAveragedEdge(int x, int y, vec3 sT[25]){
//compute sobel kernel
vec3 Gx =
(-sT[posToIndex(x,y) + 0] + sT[posToIndex(x,y) + 2]) +
2 * (-sT[posToIndex(x,y) + 5] + sT[posToIndex(x,y) + 7]) +
(-sT[posToIndex(x,y) + 10] + sT[posToIndex(x,y)+ 12]);
vec3 Gy =
(sT[posToIndex(x,y) + 0] + 2 * sT[posToIndex(x,y) + 1] + sT[posToIndex(x,y) + 2]) -
(sT[posToIndex(x,y) + 10] + 2 * sT[posToIndex(x,y)+ 11] + sT[posToIndex(x,y) + 12]);
vec3 G = sqrt(Gx * Gx + Gy * Gy);
//compute laplacian kernel
vec3 L = sT[posToIndex(x,y) + 1] + sT[posToIndex(x,y) + 5] - 4 * sT[posToIndex(x,y) + 6] + sT[posToIndex(x,y) + 7] + sT[posToIndex(x,y) + 11];
float averaged = abs(G.x + G.y + G.z)/3.0;
return averaged;
}
int posToIndex(int x, int y){
return x * 5 + y;
}

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,45 @@
#version 330 core
out vec4 FragColor;
in vec2 TexCoords;
uniform sampler2D screenTexture;
const float offset = 1.0 / 500.0;
void main(){
vec2 offsets[9] = vec2[](
vec2(-offset, offset), // top-left
vec2( 0.0f, offset), // top-center
vec2( offset, offset), // top-right
vec2(-offset, 0.0f), // center-left
vec2( 0.0f, 0.0f), // center-center
vec2( offset, 0.0f), // center-right
vec2(-offset, -offset), // bottom-left
vec2( 0.0f, -offset), // bottom-center
vec2( offset, -offset) // bottom-right
);
// float kernel[9] = float[](
// -1, -1, -1,
// -1, 9, -1,
// -1, -1, -1
// );
vec3 sT[9];
for(int i = 0; i < 9; i++)
{
sT[i] = vec3(texture(screenTexture, TexCoords.st + offsets[i]));
}
vec3 Gx = (-sT[0] + sT[2]) + 2 * (-sT[3] + sT[5]) + (-sT[6] + sT[8]);
vec3 Gy = (sT[0] + 2 * sT[1] + sT[2]) - (sT[6] + 2 * sT[7] + sT[8]);
vec3 G = sqrt(Gx * Gx + Gy * Gy);
// vec3 col = vec3(0.0);
// for(int i = 0; i < 9; i++){
// col += sampleTex[i] * kernel[i];
// }
FragColor = vec4(G,1);
}

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

@ -1,6 +1,6 @@
#version 330 core
out vec4 FragColor;
out vec3 FragColor;
in vec3 FragPos;
@ -8,8 +8,10 @@ in vec3 Normal;
void main(){
vec3 norm = normalize(Normal);
vec3 norm = normalize(Normal) / 2.0;
norm = vec3(norm.x + 0.5,norm.y + 0.5,norm.z + 0.5);
// float dist = gl_FragDepth;
FragColor = vec4(norm,1.0);
FragColor = norm;
}

View File

@ -34,19 +34,22 @@ out vec3 FragPos;
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);
vec4 FinalVertex = vec4(aPos, 1.0);
vec4 FinalNormal = vec4(aNormal, 1.0);
if(hasBones==1){
//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
FinalVertex = BoneTransform * vec4(aPos, 1.0);
FinalNormal = BoneTransform * vec4(aNormal, 1.0);
}
//make sure the W component is 1.0
FinalVertex = vec4(FinalVertex.xyz, 1.0);

View File

@ -13,19 +13,16 @@ layout (binding = 1) uniform sampler2D reveal;
const float EPSILON = 0.00001f;
// caluclate floating point numbers equality accurately
bool isApproximatelyEqual(float a, float b)
{
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)
{
float max3(vec3 v) {
return max(max(v.x, v.y), v.z);
}
void main()
{
void main(){
// fragment coordination
ivec2 coords = ivec2(gl_FragCoord.xy);

View File

@ -3,7 +3,6 @@
// shader inputs
layout (location = 0) in vec3 position;
void main()
{
void main(){
gl_Position = vec4(position, 1.0f);
}

View File

@ -750,6 +750,7 @@ public class LoadingThread extends Thread {
Entity shrine = EntityUtils.spawnDrawableEntity("Models/shrine2.fbx");
EntityUtils.getPosition(shrine).set(15,0,15);
EntityUtils.getRotation(shrine).rotationX((float)-Math.PI/2.0f);
shrine.putData(EntityDataStrings.DRAW_OUTLINE, true);
// goblin = CreatureUtils.spawnBasicCreature("Goblin");

View File

@ -20,6 +20,7 @@ public class EntityDataStrings {
public static final String DRAW_TRANSPARENT_PASS = "drawTransparentPass";
public static final String DRAW_CAST_SHADOW = "castShadow";
public static final String DRAW_VOLUMETRIC = "drawVolumetric";
public static final String DRAW_OUTLINE = "drawOutline";
/*

View File

@ -202,6 +202,9 @@ public class CreatureUtils {
case "INVENTORY":
rVal.putData(EntityDataStrings.NATURAL_INVENTORY,UnrelationalInventoryState.createUnrelationalInventory(10));
break;
case "OUTLINE":
rVal.putData(EntityDataStrings.DRAW_OUTLINE, true);
break;
}
}
//variants

View File

@ -109,6 +109,9 @@ public class ItemUtils {
case "TARGETABLE":
Globals.entityManager.registerTargetableEntity(rVal);
break;
case "OUTLINE":
rVal.putData(EntityDataStrings.DRAW_OUTLINE, true);
break;
}
}
if(item.getEquipWhitelist() != null){

View File

@ -73,82 +73,82 @@ public class TerrainGen {
public static int current_Region_X = 0;
public static int current_Region_Y = 0;
public static void main(String args[]){
// public static void main(String args[]){
TerrainGenerator tergen = new TerrainGenerator();
tergen.set_Dimension(DIMENSION);
tergen.set_Lifespan(15000);
tergen.run();
elevation = tergen.get_Terrain();
// TerrainGenerator tergen = new TerrainGenerator();
// tergen.set_Dimension(DIMENSION);
// tergen.set_Lifespan(15000);
// tergen.run();
// elevation = tergen.get_Terrain();
elevation = interpolate_Elevation_Raws(elevation);
DIMENSION = DIMENSION * 2;
// elevation = interpolate_Elevation_Raws(elevation);
// DIMENSION = DIMENSION * 2;
elevation = compression_filter(elevation);
elevation = three_halves_filter(elevation);
elevation = smooth_Terrain_Further(elevation);
elevation = small_Kernel_Sharpen(elevation);
elevation = smooth_Terrain_Further(elevation);
elevation = three_halves_filter(elevation);
elevation = small_Kernel_Smooth(elevation);
elevation = small_Kernel_Sharpen(elevation);
elevation = smooth_Terrain_Further(elevation);
elevation = smooth_Terrain_Further(elevation);
elevation = land_exponential_filter(elevation);
elevation = land_exponential_filter(elevation);
elevation = land_exponential_filter(elevation);
elevation = land_exponential_filter(elevation);
// elevation = compression_filter(elevation);
// elevation = three_halves_filter(elevation);
// elevation = smooth_Terrain_Further(elevation);
// elevation = small_Kernel_Sharpen(elevation);
// elevation = smooth_Terrain_Further(elevation);
// elevation = three_halves_filter(elevation);
// elevation = small_Kernel_Smooth(elevation);
// elevation = small_Kernel_Sharpen(elevation);
// elevation = smooth_Terrain_Further(elevation);
// elevation = smooth_Terrain_Further(elevation);
// elevation = land_exponential_filter(elevation);
// elevation = land_exponential_filter(elevation);
// elevation = land_exponential_filter(elevation);
// elevation = land_exponential_filter(elevation);
mountainParsed = new int[DIMENSION][DIMENSION];
oceanParsed = new int[DIMENSION][DIMENSION];
continentIdField = new int[DIMENSION][DIMENSION];
// mountainParsed = new int[DIMENSION][DIMENSION];
// oceanParsed = new int[DIMENSION][DIMENSION];
// continentIdField = new int[DIMENSION][DIMENSION];
mountainParsed = parse_Mountainscapes(elevation);
// mountainParsed = parse_Mountainscapes(elevation);
oceanParsed = parse_Oceans(elevation);
// oceanParsed = parse_Oceans(elevation);
wind_field = map_Wind_Field();
// wind_field = map_Wind_Field();
precipitationChart = calculate_Rain_Shadows(elevation,oceanParsed,wind_field);
// precipitationChart = calculate_Rain_Shadows(elevation,oceanParsed,wind_field);
temperatureChart = generate_Temperature_Chart();
// temperatureChart = generate_Temperature_Chart();
climateCategory = infer_Climate_Category();
// climateCategory = infer_Climate_Category();
determine_Continents();
// determine_Continents();
fill_Continents();
// fill_Continents();
//for display tbh
anchor_To_Real_Region();
// //for display tbh
// anchor_To_Real_Region();
display_toggle = 0;
// display_toggle = 0;
create_Frame();
// create_Frame();
while(true){
if(brightness_increasing){
if(brightness < 100){
brightness++;
} else {
}
} else {
if(brightness > 0){
brightness--;
} else {
brightness_increasing = true;
display_toggle++;
if(display_toggle > 1){
display_toggle = 0;
}
}
}
frame.repaint();
Utilities.sleep(10);
}
}
// while(true){
// if(brightness_increasing){
// if(brightness < 100){
// brightness++;
// } else {
// }
// } else {
// if(brightness > 0){
// brightness--;
// } else {
// brightness_increasing = true;
// display_toggle++;
// if(display_toggle > 1){
// display_toggle = 0;
// }
// }
// }
// frame.repaint();
// Utilities.sleep(10);
// }
// }
public TerrainModel generateModel(){
TerrainModel rVal;

View File

@ -852,10 +852,10 @@ public class Mesh {
incrementer++;
}
} else {
glUniform1i(Globals.renderingEngine.getActiveShader().shaderVertexHasBonesLoc, 0);
glUniform1i(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "hasBones"), 0);
}
} else {
glUniform1i(Globals.renderingEngine.getActiveShader().shaderVertexHasBonesLoc, 0);
glUniform1i(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "hasBones"), 0);
}

View File

@ -178,6 +178,18 @@ public class RenderingEngine {
// static Texture volumeVerticalFrontfaceTexture;
// static Framebuffer volumeVerticalFrontfaceBuffer;
/*
Post processing effects (ie kernels) textures, framebuffers, shaders
*/
static Texture normalsOutlineTexture;
static Framebuffer normalsOutlineFrambuffer;
static ShaderProgram normalsOutlineShader;
/*
compositing functions
*/
static ShaderProgram compositeAnimeOutline;
// public static boolean renderHitboxes = false;
// public static boolean renderPhysics = false;
@ -187,7 +199,7 @@ public class RenderingEngine {
ShaderProgram activeProgram;
static int outputFramebuffer = 0;
static int outputFramebuffer = 6;
public void createOpenglContext(){
@ -312,7 +324,8 @@ public class RenderingEngine {
static ShaderProgram renderNormalsShader;
*/
gameImageNormalsTexture = FramebufferUtils.generateScreenTextureColor(Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT);
gameImageNormalsFramebuffer = FramebufferUtils.generateScreenTextureFramebuffer(Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT, gameImageNormalsTexture);
Texture gameImageNormalsDepthTexture = FramebufferUtils.generateScreenTextureDepth(Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT);
gameImageNormalsFramebuffer = FramebufferUtils.generateScreenTextureFramebuffer(Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT, gameImageNormalsTexture, gameImageNormalsDepthTexture);
renderNormalsShader = ShaderProgram.loadSpecificShader("Shaders/anime/renderNormals.vs", "Shaders/anime/renderNormals.fs");
//
@ -328,6 +341,24 @@ public class RenderingEngine {
//projection matrices
nearVolumeProjectionMatrix.setPerspective((float)(Globals.verticalFOV * Math.PI /180.0f), (float)Globals.WINDOW_WIDTH / (float)Globals.WINDOW_HEIGHT, 0.1f, 100);
//
//Postprocessing textures and buffers
//
/*
static Texture normalsOutlineTexture;
static Framebuffer normalsOutlineFrambuffer;
static ShaderProgram normalsOutlineShader;
*/
normalsOutlineTexture = FramebufferUtils.generateScreenTextureColorAlpha(Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT);
normalsOutlineFrambuffer = FramebufferUtils.generateScreenTextureFramebuffer(Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT, normalsOutlineTexture);
// normalsOutlineShader = ShaderProgram.loadSpecificShader("Shaders/anime/outlineNormals.vs", "Shaders/anime/outlineNormals.fs");
Globals.assetManager.addShaderToQueue("Shaders/anime/outlineNormals.vs", "Shaders/anime/outlineNormals.fs");
//
//Compositing shaders
//
compositeAnimeOutline = ShaderProgram.loadSpecificShader("Shaders/anime/compositeAnimeOutline.vs", "Shaders/anime/compositeAnimeOutline.fs");
//instantiate light manager
lightManager = new LightManager();
@ -432,7 +463,8 @@ public class RenderingEngine {
if(Globals.RENDER_FLAG_RENDER_SCREEN_FRAMEBUFFER_CONTENT){
renderGameContent();
renderDebugContent();
renderNormals();
renderNormalsForOutline();
applyKernelsAndPostprocessing();
compositeGameImage();
}
@ -822,7 +854,7 @@ public class RenderingEngine {
}
}
static void renderNormals(){
static void renderNormalsForOutline(){
/*
gameImageNormalsTexture;
@ -833,8 +865,11 @@ public class RenderingEngine {
//bind screen fbo
gameImageNormalsFramebuffer.bind();
glEnable(GL_DEPTH_TEST);
glDisable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDepthFunc(GL_LESS);
glDepthMask(true);
glViewport(0, 0, Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT);
///
@ -855,6 +890,7 @@ public class RenderingEngine {
if(
(boolean)currentEntity.getData(EntityDataStrings.DATA_STRING_DRAW) &&
currentEntity.getData(EntityDataStrings.DRAW_SOLID_PASS) != null &&
currentEntity.getData(EntityDataStrings.DRAW_OUTLINE) != null &&
drawPoint(cameraPos,new Vector3f((float)position.x,(float)position.y,(float)position.z))
){
//fetch actor
@ -874,9 +910,41 @@ public class RenderingEngine {
}
}
static void applyKernelsAndPostprocessing(){
//
// Outline normals
//
glDepthFunc(GL_ALWAYS);
glDepthMask(false);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
normalsOutlineFrambuffer.bind();
ShaderProgram program = Globals.assetManager.fetchShader("Shaders/anime/outlineNormals.vs", null, "Shaders/anime/outlineNormals.fs");
if(program != null){
Globals.renderingEngine.setActiveShader(program);
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, gameImageNormalsTexture.getTexturePointer());
glDrawArrays(GL_TRIANGLES, 0, 6);
glBindVertexArray(0);
}
}
static void compositeGameImage(){
//
// Pass Three: Composite transparency on top of solids
//Setup to render screen textures & bind screen framebuffer
//
glDepthFunc(GL_ALWAYS);
// glDepthMask(false);
@ -884,10 +952,33 @@ public class RenderingEngine {
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
screenFramebuffer.bind();
Globals.renderingEngine.setActiveShader(oitCompositeProgram);
glBindVertexArray(screenTextureVAO);
//
//Draw anime outline
//
Globals.renderingEngine.setActiveShader(compositeAnimeOutline);
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, normalsOutlineTexture.getTexturePointer());
glDrawArrays(GL_TRIANGLES, 0, 6);
//
//Composite transparency on top of solids
//
Globals.renderingEngine.setActiveShader(oitCompositeProgram);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, 0);
glActiveTexture(GL_TEXTURE1);
@ -903,6 +994,9 @@ public class RenderingEngine {
glDrawArrays(GL_TRIANGLES, 0, 6);
glBindVertexArray(0);
}
static void renderScreenFramebuffer(){
@ -948,9 +1042,7 @@ public class RenderingEngine {
} else if(outputFramebuffer == 5){
glBindTexture(GL_TEXTURE_2D, gameImageNormalsTexture.getTexturePointer());
} else if(outputFramebuffer == 6){
Globals.renderingEngine.setActiveShader(drawChannel);
glUniform1f(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "channel"),0);
glBindTexture(GL_TEXTURE_2D, transparencyRevealageTexture.getTexturePointer());
glBindTexture(GL_TEXTURE_2D, normalsOutlineTexture.getTexturePointer());
} else if(outputFramebuffer == 7){
Globals.renderingEngine.setActiveShader(drawChannel);
glUniform1f(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "channel"),4);

View File

@ -78,6 +78,21 @@ public class FramebufferUtils {
return texture;
}
public static Texture generateScreenTextureColorAlpha(int width, int height){
int texturePtr = glGenTextures();
glBindTexture(GL_TEXTURE_2D,texturePtr);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, 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);