2013-06-09 9 views
6

Ich möchte die Initialisierung meiner 3D-Textur von der CPU auf die GPU verschieben. Als Test habe ich einen Shader geschrieben, um alle Voxel auf einen konstanten Wert zu setzen, aber die Textur wird überhaupt nicht verändert. Wie kann ich es funktionieren lassen?Compute Shader nicht 3D-Textur ändern

Compute Shader:

#version 430 

layout(local_size_x=1, local_size_y=1, local_size_z=1) in; 
layout(r8, location = 0) uniform image3D volume; 

void main() 
{ 
    imageStore(volume, ivec3(gl_WorkGroupID), vec4(0)); 
} 

Invocation:

glEnable(GL_TEXTURE_3D); 
glActiveTexture(GL_TEXTURE0); 
glGenTextures(1, &volume_tid); 
glBindTexture(GL_TEXTURE_3D, volume_tid); 
glTexImage3D(GL_TEXTURE_3D, 0, GL_R8, volume_dims[0], volume_dims[1], volume_dims[2], 0, GL_RED, GL_UNSIGNED_BYTE, voxels); 

ShaderProgram computeVolumeShader; 
computeVolumeShader.loadShader(GL_COMPUTE_SHADER, "compute_volume.glsl"); 
computeVolumeShader.link(); 
computeVolumeShader.use(); 
computeVolumeShader.uniform("volume", 0); 
glBindImageTexture(0, volume_tid, 0, GL_FALSE, 0, GL_READ_WRITE, GL_R8); 
glDispatchCompute(volume_dims[0], volume_dims[1], volume_dims[2]); 
glBindImageTexture(0, 0, 0, GL_FALSE, 0, GL_READ_WRITE, GL_R8); 
computeVolumeShader.unUse(); 
glMemoryBarrier(GL_ALL_BARRIER_BITS); 

Anmerkung: voxels zugeführt glTexImage3D enthält die CPU initialisiert Daten.

+0

Haben Sie versucht, anstelle von 'GL_RED' ein reales Bildformat zu verwenden? –

+0

@Nicol Wenn ich 'GL_R8UI' benutze, sehe ich auch ohne den Compute Shader nichts mehr. Ich benutze 'sampler3D' zum Rendern, macht das einen Unterschied? Da 'GL_RED' in Tabelle 1 aufgelistet ist (http://www.opengl.org/sdk/docs/man/xhtml/glTexImage3D.xml), dachte ich, es ist in Ordnung, es zu benutzen? Sie sprechen über den Parameter 'internalFormat', richtig? –

+0

Aber Sie wissen nicht, was 'GL_RED' eigentlich bedeutet. Es könnte dir 'GL_R8' geben. Es könnte dir 'GL_R16' geben. Wenn Sie kein * spezifisches * Format wählen, geben Sie das Recht auf, ein Format zu wählen. Und es funktioniert nicht mehr, wenn Sie 'GL_R8UI' verwendet haben, weil Sie Ihre Pixelübertragung wahrscheinlich nicht auf [integrale Daten hochladen anstelle von normalisierten Gleitkommazahlen] gesetzt haben (http://www.opengl.org/wiki/Pixel_Transfer#Integer_format). –

Antwort

13

Ugh. Also muss eine 3D-Textur scheinbar als Layer gebunden sein, sonst kann der Shader keine uvw-Koordinate mit w> 0 verändern.

glBindImageTexture(0, volume_tid, 0, /*layered=*/GL_TRUE, 0, GL_READ_WRITE, GL_R8); 

macht den Trick.

+0

danke schön! :) –

+1

Ich habe dazu einen halben Tag verloren. Vielen Dank!!! Ich glaube nicht, dass ich es jemals herausgefunden hätte. –

+0

Habe gerade auch einen verrückten Ausflug durch diese verbracht. Das war sehr verwirrend, da es auf einem Nvidia GM107 aber nicht GK110b (beide neuesten Treiber) funktioniert. : - / – FHoenig