2013-06-09 3 views
6

Voglio spostare l'inizializzazione della mia texture 3D dalla CPU alla GPU. Come test, ho scritto uno shader per impostare tutti i voxel su un valore costante, ma la texture non è stata modificata affatto. Come posso farlo funzionare?Compute shader che non modifica la trama 3d

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

Invocazione:

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

Nota: voxels immessa glTexImage3D contiene i dati della CPU inizializzato.

+0

Hai provato a utilizzare un formato immagine reale invece di 'GL_RED'? –

+0

@Nicol Quando uso 'GL_R8UI', non vedo più nulla, anche senza shader di calcolo. Io uso 'sampler3D' per il rendering, questo fa la differenza? Poiché 'GL_RED' è elencato [qui] (http://www.opengl.org/sdk/docs/man/xhtml/glTexImage3D.xml) nella tabella 1, ho pensato che fosse ok usarlo? Stai parlando del parametro 'internalFormat', giusto? –

+0

Ma non sai cosa significhi realmente 'GL_RED'. Potrebbe darti 'GL_R8'. Potrebbe darti 'GL_R16'. Quando non si seleziona un formato * specifico *, si rinuncia al diritto di scegliere un formato. E ha smesso di funzionare quando hai usato 'GL_R8UI' perché probabilmente non hai impostato il trasferimento dei pixel su [carica i dati integrali invece dei float normalizzati] (http://www.opengl.org/wiki/Pixel_Transfer#Integer_format). –

risposta

13

Ugh. Quindi apparentemente una trama 3D deve essere associata come sovrapposta, altrimenti lo shader non è in grado di modificare alcuna coordinata uvw con w> 0.

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

fa il trucco.

+0

danke schön! :) –

+1

Ho perso mezza giornata a questo. Grazie!!! Non credo che l'avrei mai capito. –

+0

Anche solo trascorso una pazza escursione attraverso questo. Questo è stato molto confuso perché ha funzionato su una Nvidia GM107 ma non su GK110b (entrambi i driver più recenti). : - / – FHoenig