Home > Blockchain >  Texture doesn't get updated after applying a compute shader
Texture doesn't get updated after applying a compute shader

Time:07-31

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.5s and print them, but only 0s 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);
  • Related