Рендеринг OpenGL Compute Shader в 3D текстуру, похоже, ничего не делает - PullRequest
1 голос
/ 13 марта 2020

Я написал небольшой шейдер для установки значений цвета трехмерного тома.

#version 430

layout (local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
layout (r8, binding = 0) uniform image3D destTex;

void main() 
{
    imageStore(destTex, ivec3(gl_GlobalInvocationID.xyz), vec4(0.33, 0, 1.0, 0.5));
}

Он компилируется и связывается без ошибок.

Том создан, а вычислительный шейдер - отправлено вот так

    generateShader->use();

    glEnable(GL_TEXTURE_3D);
    glGenTextures(1, &densityTex);

    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_3D, densityTex);

    glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

    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);

    glTexImage3D(GL_TEXTURE_3D, 0, GL_R8, chunksize + 1, chunksize + 1, chunksize + 1, 0, GL_RED, GL_UNSIGNED_BYTE, NULL);
    glBindImageTexture(0, densityTex, 0, GL_TRUE, 0, GL_READ_WRITE, GL_R8);

    glDispatchCompute(chunksize + 1, chunksize + 1, chunksize + 1);
    // make sure writing to image has finished before read
    glMemoryBarrier(GL_ALL_BARRIER_BITS);

asdf(0); //Here I print the content of my texture. 
         //Strangely it contains the values 205 everywhere and independent of what I set in the shader: vec4(0.33, 0, 1.0, 0.5)

    glBindTexture(GL_TEXTURE_3D, 0);

Метод печати данных изображения выглядит следующим образом:

void Chunk::asdf(int slice) {

    GLubyte* image;
    image = new GLubyte[(chunksize + 1) * (chunksize + 1) * (chunksize + 1)];

    glGetTexImage(GL_TEXTURE_3D, 0, GL_R8, GL_UNSIGNED_BYTE, image);
    std::cout << "Reading texels" << std::endl;
    for (int i = 0; i < (chunksize + 1); i++) {
        for (int j = 0; j < (chunksize + 1); j++) {

            int start = (((chunksize + 1) * (chunksize + 1) * slice) + (i * (chunksize + 1)) + j);
            std::cout << "Texel at " << i << " " << j << " " << slice << " has color " << (float)image[start] << std::endl;
        }
    }

    delete[] image;
}

Что не так в этом коде? Нужен ли какой-то особый метод для получения данных после установки их на GPU? Кроме того, я не совсем понимаю, как значение устанавливается в графическом процессоре, потому что при использовании imageStore необходимо установить значение vec4, но текстура содержит только один канал для красного (это не имеет значения, если я использую формат RGBA)

edit: Оказывается, я не понял проблему правильно. Я написал себе шейдер для отображения содержимого моей 3D-текстуры на экране. Кажется, моя функция печати (asdf) не получает правильные значения текстуры, потому что при отображении на экране значения цвета отличаются 1 slice of the texture rendered to the screen

, как вы можете видеть это до сих пор выглядит не совсем правильно, но я предполагаю, что это топи c для другой проблемы?

1 Ответ

0 голосов
/ 15 марта 2020
glGetTexImage(GL_TEXTURE_3D, 0, GL_R8, GL_UNSIGNED_BYTE, image);

Это не копирует данные в image, а только генерирует ошибку GL_INVALID_ENUM. GL_R8 - это не параметр vaild format. Вы, скорее всего, имеете в виду GL_RED здесь (обратите внимание, что это то же самое, что вы использовали для параметра glTexImage3D format. GL_R8 является только перечислением для internalFormat, и оно никогда не относится к чему-либо, что вы видите в OpenGL на стороне клиента, см. также этот вопрос ).

В качестве более общей рекомендации, я действительно советую всем использовать Отладочный вывод OpenGL во время разработки, чтобы не было OpenGL ошибка будет go незамеченной.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...