首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >用glGetTexImage从计算着色器用imageStore读取纹理数据

用glGetTexImage从计算着色器用imageStore读取纹理数据
EN

Stack Overflow用户
提问于 2022-01-26 00:06:12
回答 1查看 320关注 0票数 2

我正在生成噪声到三维纹理在计算着色器,然后建立网格在CPU上。当我在主循环中这样做时,它工作得很好,但我注意到,在第一次渲染时,我只得到了1%的噪声。下面是一个很小的例子,在这里,我试图用着色器中的一个填充3D纹理,但得到零或噪声作为回报:

代码语言:javascript
运行
复制
#include <glad/glad.h>
#include <GLFW/glfw3.h>

#include <stdio.h>
#include <stdlib.h>

void error(const char* message) { ... }

const char* slurp_file(const char* filename) { ... }

int main() {
  glfwInit();

  glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
  glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
  glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

  GLFWwindow* window = glfwCreateWindow(100, 100, "", NULL, NULL);
  glfwMakeContextCurrent(window);
  gladLoadGL();
  
  // create texture
  GLuint texture;
  glGenTextures(1, &texture);
  glActiveTexture(GL_TEXTURE0);
  glBindTexture(GL_TEXTURE_3D, texture);

  glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);

  // allocate it
  size_t size = 4;
  glTexImage3D(GL_TEXTURE_3D, 0, GL_R32F, size, size, size, 0, GL_RED, GL_FLOAT, NULL);

  // create shader
  const char* shader_source = slurp_file("shaders/example.comp");
  GLuint shader = glCreateShader(GL_COMPUTE_SHADER);
  glShaderSource(shader, 1, &shader_source, NULL);
  glCompileShader(shader);

  // check it
  int code;
  glGetShaderiv(shader, GL_COMPILE_STATUS, &code);
  if (!code) error("shader compilation failed");

  // create program
  int program = glCreateProgram();
  glAttachShader(program, shader);
  glLinkProgram(program);

  // check it
  glGetProgramiv(program, GL_LINK_STATUS, &code);
  if (!code) error("program linkage failed");

  // run shader
  glUseProgram(program);
  // i don't think it's needed, as 0 would be a default value
  int uniform_loc = glGetUniformLocation(program, "img_output");
  glUniform1i(uniform_loc, 0);

  // dispatch and sync
  glDispatchCompute(size, size, size);
  // originally i had GL_TEXTURE_FETCH_BARRIER_BIT here
  glMemoryBarrier(GL_ALL_BARRIER_BITS);

  // read texture data
  float* data = malloc(size * size * size * sizeof(float));
  glBindImageTexture(0, texture, 0, GL_TRUE, 0, GL_READ_WRITE, GL_R32F);
  glGetTexImage(GL_TEXTURE_3D, 0, GL_RED, GL_FLOAT, data);

  // prints 0s or noise, but i expect all 1s
  for (int i = 0; i < size * size * size; i++)
    printf("%f ", data[i]);
}

这是着色器:

代码语言:javascript
运行
复制
#version 430

layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
layout(binding = 0, r32f) writeonly uniform image3D img_output;

void main() {
  ivec3 texture_coords = ivec3(gl_GlobalInvocationID.xyz);

  vec4  pixel = vec4(1, 0, 0, 0);

  imageStore(img_output, texture_coords, pixel);
}

glDispatchCompute之后添加睡眠没有什么作用,所以我想我错过了一些锁定吗?或者纹理应该以其他方式配置?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-01-26 06:06:38

在执行计算着色器之前,需要将纹理绑定到图像单元。纹理对象与着色器之间的绑定是通过纹理图像单元建立的。着色器知道单元,因为您设置了单元变量或使用布局限定符指定了绑定点,但还需要将对象绑定到该单元:

代码语言:javascript
运行
复制
glBindImageTexture(0, texture, 0, GL_TRUE, 0, GL_READ_WRITE, GL_R32F);
glDispatchCompute(size, size, size);
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70857263

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档