2013-10-21 105 views
1

我试图通过将纹理的内容复制到附加到FBO的输出纹理来编写GPGPU程序。但是,我发现输入的纹理数据未正确加载/未正确绑定。我不明白什么是错的。从纹理渲染到离屏纹理(FBO)

这里是我的代码:

void render() 
{ 

    int i; 
    float * result, *in; 

    //allocating and filling data in the input texture 

    result = (float *) malloc(4*32*32*sizeof(float)); 
    in = (float *) malloc(4*32*32*sizeof(float)); 
    for(i=0;i<32*32*4; i++) 
    { 
    in[i]=1.0f; 
    } 


makeBuffers(); //makes the vertex and element buffers 
makeTexture(in); //makes the input textures 
makeShaders(); //makes the vertex n pixel shaders 
makeProgram(); //makes the program 

glClearColor(1.0f, 1.0f, 1.0f, 0.0f); 
glClear(GL_COLOR_BUFFER_BIT); 

glBindBuffer(GL_ARRAY_BUFFER, res.vertexBuffer); 
glVertexAttribPointer(res.position, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat)*2, (void*)0); 
glEnableVertexAttribArray(res.position); 
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, res.elementBuffer); 
res.texture= glGetUniformLocation(res.shaderProgram, "intexture"); 

/*绑定质地*/ makefbo(); //使离屏帧缓冲器对象

glActiveTexture(GL_TEXTURE0); 
glBindTexture(GL_TEXTURE_2D, res.texture); 
glUniform1i(res.texture, 0); 


glDrawElements(GL_TRIANGLE_STRIP,4, GL_UNSIGNED_SHORT, (void*)0); 

// glFlush(); // i think drawing would be enough now. 

glReadBuffer(GL_COLOR_ATTACHMENT0_EXT); //reading back data from the framebuffer 
glReadPixels(0, 0, 32, 32,GL_RGBA,GL_FLOAT,result); 

printf(" float values \n"); 
for(i=0; i< 32*4 ; i++) 
    printf(" %f ", result[i]); 
printf(" \n"); 

}

这里是我maketexture()函数

glGenTextures (1, &res.texture); 
glBindTexture(GL_TEXTURE_2D,res.texture); 
// set texture parameters 
glTexParameteri(GL_TEXTURE_2D, 
       GL_TEXTURE_MIN_FILTER, GL_NEAREST); 
glTexParameteri(GL_TEXTURE_2D, 
       GL_TEXTURE_MAG_FILTER, GL_NEAREST); 
glTexParameteri(GL_TEXTURE_2D, 
       GL_TEXTURE_WRAP_S, GL_CLAMP); 
glTexParameteri(GL_TEXTURE_2D, 
       GL_TEXTURE_WRAP_T, GL_CLAMP); 
// define texture with floating point format 
glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA32F, 
      texSize,texSize,0,GL_RGBA,GL_FLOAT,0); 

// transfer data to texture 
glTexSubImage2D(GL_TEXTURE_2D,0,0,0,texSize,texSize, 
       GL_RGBA,GL_FLOAT,data); 

这里是我framebufferoject准备和输出纹理招标:

glGenFramebuffers(1, &res.fbo); 
glBindFramebuffer(GL_FRAMEBUFFER, res.fbo); 
glViewport(0, 0, 32, 32); 

glGenTextures(1, &res.tex); 
glBindTexture(GL_TEXTURE_2D, res.fbo); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); 
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, 
     32, 32, 0, GL_RGBA, GL_FLOAT, 0); 
glFramebufferTexture2DEXT(GL_FRAMEBUFFER, 
         GL_COLOR_ATTACHMENT0, 
         GL_TEXTURE_2D, res.tex, 0); 

数据似乎没有正确读取。我尝试将输入纹理附加到帧缓冲区对象,并尝试立即读回纹理数据,然后数据显示正常。但是当我尝试渲染到屏幕外纹理时,它不会给出正确的输出。它在像素着色器执行结束时只给出一堆零。

像素着色器获取输入纹理并将数据复制到输出纹理中:outColor = texture2D(intexture,texcoord);

有人可以看到这个问题吗?

+1

请不要说你每次渲染帧时都会创建纹理,fbo,vao等。 – Vallentin

+0

我不是每次都渲染,这是一次性操作。我只需要将数据处理一次。 –

回答

1

你的代码缺乏很多上下文,但我的印象是你将所有东西都绑定了一次,然后就这样离开了。这并非如此,它可能无法正常工作。

本质的要点是,如果纹理被用作FBO渲染目标,它不能作为采样源。所以你必须根据需要解除纹理/ FBO的绑定,以便事物不会踩在彼此的脚趾上,或者你正在加载着色器,这些着色器只是禁止纹理访问。恕我直言,解除绑定是更简单的选择(然而,随着OpenGL-4.4的发布,它可能成为4.5中的核心)。

+0

是的,我将所有东西都绑定一次,因为我只需要一次处理数据。我不会再次渲染n。关于解除绑定: –

+0

:我试图将输入纹理复制到输出纹理,这是不是意味着输入和输出纹理应该同时绑定到渲染目标? –

+0

@saipallavi:不,它意味着完全没有这样做。用'glFramebufferTexture'作为颜色附件将输出纹理绑定到FBO。输入纹理必须通过使用'glBindTexture'绑定到纹理单元来选择采样源。 – datenwolf