I'm trying to apply a compute shader to a texture to update its values. I know it's not a very good question to just state something doesn't work, but I did spend a lot of hours trying to get this work.
The shader program compiles well. Changing the glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
line to glMemoryBarrier(GL_ALL_BARRIER_BITS); glFinish();
doesn't make a difference.
Below is a minimal program to show the issue. SDL is merely for creating an invisible window for the GL context. The program is expected fill the texture with 0.5
s and print them, but only 0
s are printed..
#define SDL_MAIN_HANDLED
#include <stdio.h>
#include <assert.h>
#include <GL/glew.h>
#include <SDL2/SDL.h>
#define WIDTH 512
#define HEIGHT WIDTH
static const char *SHADER =
"#version 430\n" // "#version 310 es\n"
"layout (local_size_x = 1, local_size_y = 1) in;\n"
"layout (rgba32f, binding = 0) uniform image2D image;\n"
"void main() {\n"
"imageStore(image, ivec2(gl_GlobalInvocationID.xy), vec4(0.5f));\n"
"}\n";
int main() {
SDL_SetMainReady();
assert(!SDL_Init(SDL_INIT_VIDEO));
SDL_Window *window = SDL_CreateWindow("", SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED, 0, 0, SDL_WINDOW_HIDDEN | SDL_WINDOW_OPENGL);
assert(window);
SDL_GLContext gl = SDL_GL_CreateContext(window);
assert(gl);
assert(glewInit() == GLEW_OK);
GLuint tex;
glGenTextures(1, &tex);
glBindTexture(GL_TEXTURE_2D, tex);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, WIDTH, HEIGHT, 0, GL_RGBA,
GL_FLOAT, 0);
glBindImageTexture(0, tex, 0, 0, 0, GL_READ_WRITE, GL_RGBA32F);
GLuint shader = glCreateShader(GL_COMPUTE_SHADER);
glShaderSource(shader, 1, &SHADER, 0);
glCompileShader(shader);
GLuint program = glCreateProgram();
glAttachShader(program, shader);
glLinkProgram(program);
glUseProgram(program);
glDispatchCompute(WIDTH, HEIGHT, 1);
glMemoryBarrier(GL_ALL_BARRIER_BITS);
glFinish();
static float a[WIDTH * HEIGHT * 4];
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_FLOAT, a);
puts((const char *)glGetString(GL_VERSION));
for (int i = 0; i < 16; i) printf("%f\n", a[i]);
return 0;
}
CodePudding user response:
If you do not generate mipmaps (with glGenerateMipmap
), you have to change the GL_TEXTURE_MIN_FILTER
. Since the default filter is GL_NEAREST_MIPMAP_LINEAR
, the texture would be "Mipmap Incomplete" if you do not change the minimize function to GL_NEAREST
or GL_LINEAR
.
glBindTexture(GL_TEXTURE_2D, tex);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, WIDTH, HEIGHT, 0, GL_RGBA, GL_FLOAT, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glBindImageTexture(0, tex, 0, 0, 0, GL_READ_WRITE, GL_RGBA32F);