// Setup
depthTexture = glGenTextures();
glBindTexture(GL_TEXTURE_2D, depthTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, width, height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, (FloatBuffer) null);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTexture, 0);
computeProgram = ShaderProgram.fromFiles("src\\game\\test.compute", "offscreenrenderer", 0);
quad = new FullscreenQuad();
computeProgram.use();
glBindImageTexture(0, renderedTexture, 0, false, 0, GL_READ_ONLY, GL_RGBA32F);
glBindImageTexture(1, depthTexture, 0, false, 0, GL_READ_ONLY, GL_R32F);
glBindImageTexture(2, processedTexture, 0, false, 0, GL_WRITE_ONLY, GL_RGBA32F);
computeProgram.unuse();
// Methods in the code for starting the rendering and for doing the post processing:
public void start() {
glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);
//glBindRenderbuffer(GL_RENDERBUFFER, depthBuffer);
glViewport(0, 0, width, height);
}
public void runPostProcess() {
computeProgram.use();
glDispatchCompute((int) Math.ceil(width / 16.0), (int) Math.ceil(height / 16.0), 1);
glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
computeProgram.unuse();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glClear(GL_COLOR_BUFFER_BIT);
quad.setTexture(processedTexture);
quad.render();
}
#version 430
layout(local_size_x = 16, local_size_y = 16) in;
layout(binding = 0, rgba32f) uniform image2D inputImage; // Works
layout(binding = 1, r32f) uniform image2D depthImage; // Doesn't work
layout(binding = 2, rgba32f) uniform image2D outputImage; // Works
void main() {
ivec2 pos = ivec2(gl_GlobalInvocationID.xy);
imageStore(outputImage, pos, imageLoad(depthImage, pos));
}
// Java
int t3dim = 64;
int[] tex3d_r = new int[t3dim*t3dim*t3dim*4];
int r,g,b,a,color;
for(int i=0;i<(t3dim*t3dim*t3dim);i++) {
r = (int)(Mati.fRand_static()*255.0f);
g = (int)(Mati.fRand_static()*255.0f);
b = (int)(Mati.fRand_static()*255.0f);
a = (int)(Mati.fRand_static()*255.0f);
color = (a << 24) | (r << 16) | (g << 8) | b;
tex3d_r[i]=color;
}
glTexImage3D(GL_TEXTURE_3D, 0, GL30.GL_RGBA, t3dim , t3dim , t3dim , 0, GL30.GL_RGBA, GL_UNSIGNED_BYTE, tex3d_r);
// GLSL
if(volumeMode>0) {
pixel = texture(volumeMap, vec3(uvs_vs0.xy,dbg_val1));
return;
}
Quote from: bonenaut7 on May 13, 2024, 02:11:24That's interesting, i was using MemoryStack only in try-with-resources blocks, but in example i provided in #1 post it looks like that's... unnecessary? There is callback when vertex buffer is built, BGFXMemory is no more required to stay and memory could be freed(and it happens exactly when at least a frame with some delay passed), is this callback bad in some way?Allocating native memory (especially in a game loop) is slow (regardless of language). The advantage with the above MemoryStack method is that you just allocate a chunk of memory at initialisation and then reuse it continuously in the game loop.
Quote from: spasi on May 12, 2024, 09:39:10The Java-side buffer object that wraps a native pointer is reclaimed as usual by the GC, when there are no longer any references pointing to it.Oh, got it, thanks!
Quote from: kappa on May 12, 2024, 05:47:35One potential solution for frame data which changes every frame (e.g. immediate mode 2d graphics made up of many small allocations) is to use LWJGL's MemoryStack, just push all your data in there and pop (release) it after 2 frames. e.g. Use 3 MemoryStack's (one for current frame data and two holding data for the previous two frames) and just cycle through the MemoryStack's.