Я пытаюсь хранить данные в 3D-текстуре, но, похоже, она не работает. Я создал текстуру, как это:Как использовать хранилище изображений с 3D-текстурами?
glGenTextures(1, &voxelTexture);
glBindTexture(GL_TEXTURE_3D, voxelTexture);
unsigned char clearData[VoxelSize* VoxelSize* VoxelSize];
memset(clearData, 5, sizeof(clearData));
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);
glTexImage3D(GL_TEXTURE_3D, 0, GL_R8UI, VoxelSize, VoxelSize, VoxelSize, 0, GL_RED_INTEGER, GL_UNSIGNED_BYTE, clearData);
Позже я пишу к текстуре:
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glViewport(0, 0, VoxelSize, VoxelSize);
glUseProgram(voxelProg);
glBindTexture(GL_TEXTURE_3D, voxelTexture);
glBindImageTexture(0, voxelTexture, 0, GL_TRUE, 0, GL_WRITE_ONLY, GL_R8UI);
for(const auto & i : models){
glUniformMatrix4fv(glGetUniformLocation(voxelProg, "M"), 1, GL_FALSE, glm::value_ptr(i->getModelMatrix()));
glBindVertexArray(i->getMesh()->vao);
glDrawElements(GL_TRIANGLES, i->getMesh()->nbVertices, GL_UNSIGNED_INT, 0);
}
Я знаю, что операция Жеребьевка работает нормально, потому что я использовал его с тенью карты в другой части программа.
Наконец, я пытаюсь прочитать данные из текстуры:
glMemoryBarrier(GL_SHADER_IMAGE_ACCESS_BARRIER_BIT);
static char data[VoxelSize * VoxelSize *VoxelSize] = {0};
glGetTexImage(GL_TEXTURE_3D, 0, GL_RED_INTEGER, GL_UNSIGNED_BYTE, data);
for(auto & i : data){
if(i!=5)
std::cout << (int)i << " ";
}
endl(std::cout);
Как вы можете видеть, если данные были изменены, то он будет печатать cout
. Я установил данные в 5, чтобы вы могли видеть, что glGetTexImage
действительно считывает данные текстуры (поскольку в противном случае это были бы все нули).
Программа, которую я использую, это как буфер вершин:
#version 430
layout(location = 0) in vec3 position;
uniform mat4 M;
void main(){
gl_Position = M* vec4(position, 1.0);
}
И это в качестве буфера фрагмента:
#version 430
layout(binding = 0, r8ui)writeonly restrict uniform uimage3D dataTexture;
void main(){
imageStore(dataTexture, ivec3(6,6,6), uvec4(30));
}
Я использовал произвольное место, чтобы писать, а не тот, который затронутый самим фрагментом, так что я мог бы хотя бы быть уверен, что если какой-либо фрагмент пройден через него, это повлияет на текстуру. Однако ничего не работает. Я попытался изменить, где пишет imageStore
, я попытался масштабировать gl_Position
в буфере вершин различными способами. Любая помощь будет оценена по достоинству.
Edit:
После выполнения возможных дублей решения об изменении слоистых настроек от false
до true
, он по-прежнему не работает.
Возможный дубликат [Вычислить шейдер, не изменяя 3d-текстуру] (http://stackoverflow.com/ вопросы/17015132/compute-shader-not-modifying-3d-texture) – jozxyqk
Я попробовал. Я также не использую компьютерный шейдер, а скорее фрагментарный шейдер. – user975989
Тогда не обман. Я не вижу ничего очевидного. Вы уверены, что фрагменты на самом деле рисуются? Попробуйте переместить 'imageStore' в вершинный шейдер как тест. – jozxyqk