2015-07-01 2 views
2

Я пытаюсь хранить данные в 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, он по-прежнему не работает.

+0

Возможный дубликат [Вычислить шейдер, не изменяя 3d-текстуру] (http://stackoverflow.com/ вопросы/17015132/compute-shader-not-modifying-3d-texture) – jozxyqk

+0

Я попробовал. Я также не использую компьютерный шейдер, а скорее фрагментарный шейдер. – user975989

+0

Тогда не обман. Я не вижу ничего очевидного. Вы уверены, что фрагменты на самом деле рисуются? Попробуйте переместить 'imageStore' в вершинный шейдер как тест. – jozxyqk

ответ

3

glUseProgram(voxelProg) и glGetUniformLocation(mainProg, "M") ссылки различные программы шейдеров. Следовательно, матрица M не установлена, вершины образуют вырожденные треугольники, и никакие фрагменты не растеризуются, поэтому imageStore никогда не вызывает вызова.

Также glBindImageTexture обрабатывает 3D-текстуры как «слоистые» 2D-текстуры, поэтому многоуровневый аргумент должен быть GL_TRUE. см. this.

[EDIT] В этом случае M не правильно проектирует геометрию по другим причинам (см. Комментарии). Чтобы изменить M так, чтобы он масштабировал и переводил сетку в кубик от -1 до 1, чтобы соответствовать 3D-изображению, см.: How to normalize a mesh into -1 to 1, then revert from normalized mesh to original one?

+0

Я изменил оба из них, но я до сих пор не писал текстуру. – user975989

+0

@ user975989 Имеет ли 'getModelMatrix' какие-либо необходимые матрицы проекций и представлений?Вы уверены, что ваша геометрия верна? Может быть, вмешательство задней стороны мешает? По какой-то причине геометрия не растеризуется. – jozxyqk

+0

Хм, ты прав. Идея этого заключается в том, чтобы произвести вокселизацию модели. Я думал, что правильный способ сделать это - не использовать проекцию или матрицу вида, а скорее только модельную матрицу. Когда я умножил их, он работал нормально. Однако проблема заключается в том, что матрица проекции является перспективной, а матрица представления зависит от того, где я. Я хочу обновить модель независимо от этих двух характеристик. Должна ли не только модельная матрица? Кроме того, «GL_DEPTH_TEST» и «GL_CULL_FACE» оба отключены. – user975989

Смежные вопросы