Send a texture buffer to a shader

Hello everyone.

I’m trying to send a texture buffer to my fragment shader. This texture buffer contains the coordinates of control points to make a Bézier interpolation in my shader.
These coordinates are float included in [0;1]

The buffer is correctly filled with the data because if I do a glGetBufferSubData just before my glUniform1i, I get the correct coordinates of my control points.

Right now, my shader just picks up 3 values of that buffer and put it in the gl_FragColor to see if it’s empty in the shader.

My problem is that it is empty and I have a black screen. I hardly see if it comes from the sending of the data in my C++ program of if it comes from the reading of the data in my shader…

Your help is welcomed !

Here’s the code :

Buffer filling (the glGen functions are made somewhere else)


glEnable(GL_TEXTURE_BUFFER);
    
    m_Data = new float[m_BaseGrid.size()*2];
    
    for(int i=0; i<m_BaseGrid.size() ; i++){
        m_Data[2*i]=m_BaseGrid[i].x;        
        m_Data[2*i+1]=m_BaseGrid[i].y;
    }
    

    glActiveTexture(GL_TEXTURE0+m_texId);
    glBindTexture(GL_TEXTURE_BUFFER, m_texId);

    glBindBuffer(GL_TEXTURE_BUFFER, m_texId);
    glBufferData(GL_TEXTURE_BUFFER, m_BaseGrid.size()*2*sizeof(float), m_Data, GL_STATIC_DRAW);
    glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32F, m_texId);    
    glBindTexture(GL_TEXTURE_BUFFER, m_texId);

glDisable(GL_TEXTURE_BUFFER);

In my Display function


glActiveTexture(GL_TEXTURE0+renderer.m_texId);
    glBindTexture(GL_TEXTURE_2D, renderer.m_texId);
    GLint texLoc = glGetUniformLocation(program, "texture");
    glUniform1i(texLoc, renderer.m_texId);    
    
    glActiveTexture(GL_TEXTURE0+warping->m_texId);
    glBindTexture(GL_TEXTURE_BUFFER, warping->m_texId);    
    GLint datLoc = glGetUniformLocation(program, "data");
    glUniform1i(datLoc, warping->m_texId);
    
    GLint nbPointsLoc = glGetUniformLocation(program, "nbPoints");
    glUniform1i(nbPointsLoc, warping->m_NbPtsH*warping->m_NbPtsV);

My fragment shader


#extension GL_EXT_gpu_shader4 : enable

uniform samplerBuffer data;
uniform int nbPoints;

float readBuffer(int i){

    float value = texelFetchBuffer(data, i*nbPoints).r;
    return value;
}

//******************************************************************************
//MAIN
//******************************************************************************
void main(){    
    

    gl_FragColor = vec4(readBuffer(46),readBuffer(47),readBuffer(48),0);
}

Thank you for your help.

glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32F, m_texId);  

That’s not how you set up a buffer texture. glTexBuffer takes the buffer object, not the texture object. It associates the given buffer object with whatever texture is bound to GL_TEXTURE_BUFFER.

Also, your fragment shader logic is… nonsensical. Your buffer texture uses GL_RGBA32F format. Which means every read will read four values. A texture coordinate of 3 refers to the 13th float in the array you uploaded to the buffer object. And yet, your readBuffer function discards the GBA part of the image, returning only one value. And then you do 3 sequential reads.

If you wanted to fetch 4 values from the texture, you should actually keep the RGBA components, rather than only keeping R the way you do.

Thank you for your answer Alfonse.

I ) THE BUFFER OBJECT

In fact, i tried the proper way before but without success. I was doing this :


glBindBuffer(GL_TEXTURE_BUFFER, m_bufferId);
    glBufferData(GL_TEXTURE_BUFFER,m_BaseGrid.size()*2*sizeof(float),m_Data,GL_DYNAMIC_DRAW);    
    glBindBuffer(GL_TEXTURE_BUFFER, 0);

//If I try to read the buffer here, it's ok : filled with coordinates
     
    glBindTexture(GL_TEXTURE_BUFFER, m_bufferId);
    glTexBuffer(GL_TEXTURE_BUFFER, GL_R32F, m_bufferId);
    glTexParameteri(GL_TEXTURE_BUFFER, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_BUFFER, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 

//If I try to read the buffer here, it's filled with 0
   
    glBindTexture(GL_TEXTURE_BUFFER, 0);

So I searched in forums and found the first method. It was working for the guy using it and the fact is that as I said, my texture buffer was correctly filled with coordinates with this method…

I’m surely making a mistake with the proper method but can’t find where.

II ) FORMAT

Yep sorry, I tried several things to check why my buffer was filled with 0 and changing format was one of them. I forgot to set it back to GL_R32F.
As the data I want to send is a 1 dimension array of floats, my readBuffer function is ok with GL_R32F, right ?

Thank you for your help.

glBindTexture(GL_TEXTURE_BUFFER, m_bufferId);

Why are you binding a buffer object with glBindTexture?

Also, I checked your original code and found this:

glActiveTexture(GL_TEXTURE0+m_texId);

No. You’re adding a texture object name to GL_TEXTURE0. That never makes sense.

Please stop copy-and-paste coding; it’s not helping anyone. Try to understand what these functions actually do. If something isn’t working, you shouldn’t just fiddle around with it until it does. You need to understand why it doesn’t work, and then understand why your change makes it work.

Yes you are right.

I’ve been trying to use that technique but I don’t even understand how it works…

I’m very sorry that you lose your time.

Thank you.

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.