2012-11-19 143 views
2

编辑:认为我已经缩小了这个问题。跳到正在运行的部分。GLSL:顶点着色器中的sampler3D,纹理显示为空

我想在我的顶点着色器中采样一个3d纹理,我将在行进多维数据集中使用texel值作为角点值。我遇到的问题是不管用什么方法来对它进行采样,我总是得到(0,0,0,0)。我试过使用texelFetch和texture3D,但都没有效果。

我也在使用变换反馈,但据我所知,不应该引起这个问题。

着色器设置:

glEnable(GL_TEXTURE_3D); 

Shader vertListTriangles(GL_VERTEX_SHADER_ARB); 
vertListTriangles.setSource(lst_tri_vert); //Util to load from file. 
vertListTriangles.compile(); 
vertListTriangles.errorCheck(); //Prints errors to console if they exist - shader compiles fine. 

Shader geomListTriangles(GL_GEOMETRY_SHADER_ARB); 
geomListTriangles.setSource(lst_tri_geom); //Util to load from file 
geomListTriangles.compile(); 
geomListTriangles.errorCheck(); //Prints errors to console if they exist - shader compiles fine. 

program.attach(vertListTriangles); 
program.attach(geomListTriangles); 

//Setup transform feedback varyings, also works as expected. 
const GLchar* varyings1[1]; 

varyings1[0] = "gTriangle"; 
glTransformFeedbackVaryings(program.getID(), 1, varyings1, GL_INTERLEAVED_ATTRIBS); 

program.link(); 

program.checkLink(); //Prints link errors to console - program links fine aparently. 

纹理设置:

glBindTexture(GL_TEXTURE_3D, textureID); 
errorCheck("texture bind"); //<- Detects GL errors, I actually get a GL_INVALID_OPERATION here, not sure if its the cause of the problem though as all subsuquent binds go smoothly. 

if(!(glIsTexture(textureID)==GL_TRUE)) consolePrint("Texture Binding Failed."); //Oddly the texture never registers as failed despite the previous error message. 

//Generate Texture 
GLfloat volumeData[32768*3]; 

for(int z = 0; z < 32; z++) 
{ 
    for(int y = 0; y < 32; y++) 
    { 
     for(int x = 0; x < 32; x++) 
     { 
      //Set all 1s for testing purposes 
      volumeData[(x*3)+(y*96)+(z*3072)] = 1.0f; 
      volumeData[(x*3)+(y*96)+(z*3072)+1] = 1.0f; 
      volumeData[(x*3)+(y*96)+(z*3072)+2] = 1.0f; 
     } 
    } 
} 

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_MAX_LEVEL, 0); 
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_BASE_LEVEL, 0); 
glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB8, 32, 32, 32, 0, GL_RGB, 
     GL_FLOAT, volumeData); 

glBindTexture(GL_TEXTURE_3D, 0); 

运行的着色器: 编辑:这里变得有趣起来。如果我指定一个不正确的统一名称或注释掉下面的行,它似乎工作。

program.use(); 

//Disable Rastering 
glEnable(GL_RASTERIZER_DISCARD); 

//Input buffer: Initial vertices 
glBindBuffer(GL_ARRAY_BUFFER, mInitialDataBuffer); 

glEnableVertexAttribArray(0); 
glVertexAttribIPointer(0, 1, GL_UNSIGNED_INT, 0, 0); //Initial input is array of uints 

//Output buffer: Triangles 
glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, mTriangleBuffer); //Triangle Markers, in the form of uints. NOT actual triangles. 

//Texture setup 

//If I comment out from here.... 
GLint sampler = glGetUniformLocation(program.getID(), "densityVol"); 
glUniform1i(sampler, GL_TEXTURE0); 
glActiveTexture(GL_TEXTURE0); 
//To here. It appears to work. 

glBindTexture(GL_TEXTURE_3D, textureID); 

//Just using this to debug texture. 
//test is all 1s, so the texture is uploading correctly. 
GLfloat test[32768*3]; 
memset(test, 0, sizeof(test)); 
glGetTexImage(GL_TEXTURE_3D, 0, GL_RGB, GL_FLOAT, test); 

//Transform Feedback and Draw 
glBeginTransformFeedback(GL_POINTS); 

    glDrawArrays(GL_POINTS, 0, 29790); 

glEndTransformFeedback(); 

//Re-enable Rastering and cleanup 
glDisable(GL_RASTERIZER_DISCARD); 
glDisableVertexAttribArray(0); 
glBindBuffer(GL_ARRAY_BUFFER, 0); 

我的代码是在现实中多了几分传播出去,但我希望我设法将其修改成什么凝聚力。无论如何,如果我映射到输出缓冲区,它确实输出了一些信息,但是它处理好像所有的纹理数据都是0。我砍死着色器只是输出一些测试结果,而不是,但我无法找到着色器正确使用质地任何证据:

#version 410 
#extension GL_EXT_gpu_shader4 : require 

layout (location = 0) in int x_y_z; 
uniform sampler3D densityVol; 

out Voxel 
{ 
    /* 
    Each triangle is the edges it joins. There are 12 edges and so we need 12 bits. 4 For each edge. 
    There are up to 32 voxels, which means we need 6 bits for each coord, which is 18. 
    30 bits total. 
    int format 00xxxxxxyyyyyyzzzzzz111122223333 
    */ 
    uint triangles[5]; 
    uint triangleCount; 

} vVoxel; 

//... Omitted some huge ref tables. 

void main() 
{ 
    vec4 sample0 = texture3D(densityVol, vec3(0.1,0.1,0.1)); 
    vec4 sample1 = texture3D(densityVol, vec3(0.9,0.9,0.9)); 
    vec4 sample2 = texture3D(densityVol, vec3(0.1,0.1,0.9)); 
    vec4 sample3 = texture3D(densityVol, vec3(0.9,0.9,0.1)); 

    if(sample0.r > 0.0f) 
    { 
     vVoxel.triangles[1] = 1; 
    } 
    if(sample1.r > 0.0f) 
    { 
     vVoxel.triangles[2] = 2; 
    } 
    if(sample2.r > 0.0f) 
    { 
     vVoxel.triangles[3] = 3; 
    } 
    if(sample3.r > 0.0f) 
    { 
     vVoxel.triangles[4] = 4; 
    } 

    vVoxel.triangleCount = 5; 
} 

没有最好的设计测试,但我不想写东西,从刮。如果我将if子句更改为if(true)测试输出正确。如上所述编译着色器时,缓冲区为空白。我使用GS来传递。

任何人都可以在那里看到一个明显的错误?我已经被困了大约2个小时了,我看不出我在做什么不同于许多GLSL纹理教程。

+0

'#extension GL_EXT_gpu_shader4:require'我认为这一行是为了解决驱动程序的bug,是吗?否则,这是毫无意义的。 –

+0

这是试图解决......的东西。我不记得了,虽然我可能不再需要它了。无论如何,我认为我以其他方式修复了它。 –

回答

3

好吧,算出来。

glUniform1i(sampler, GL_TEXTURE0); 

GL_TEXTURE0在这里不正确。

glUniform1i(sampler, 0); 

它应该是怎样的。

相关问题