Texture data used to draw mesh not used(?) after updating texture in shader

I’m sorry for the ambiguous title. I’m not really sure why this is happening, or even what is happening. But I’ll share some code and ideas about what the problem maybe about. So here’s what I was trying to do;

I’m trying to draw multiple lines seperated at certain intervals using a single mesh. Coordinates of the vertices get updated every frame using a pingpong framebuffer object to update the coordinate data stored in a texture. The problem is that when I use the shader program that updates the texture, the number of lines rendered decreases.

I’m trying to use geometry shader to draw simple lines to thick lines (which are actually rectangles drawn from GL_TRIANGLE_STRIP) using GLSL version 330. The process was intended to work like so;

  1. Set data for the coordinates as a vector, which in turn is put into a framebuffer object as GL_RGB32F texture.
  2. Set vertices for an ofVboMesh object.
  3. Update texture storing positions using a pingpong framebuffer object.
  4. Render GL_LINES_ADJACENCY mesh as GL_TRIANGLE_STRIP using geometry shader.

(code for 1~2 : setup) I was trying to draw tex_w * tex_h number of shapes that are consisted of few lines that are connected to each other. I’m using GL_LINES_ADJACENCY primitive type, because I’m planning to use the adjacent vertex attributes in geometry shader. The reason I’m not using GL_LINE_STRIP_ADJACENCY is because I need the shape to be seperated at certain intervals. According to the code below, it should draw 16 shapes that are each consisted of 2 lines. (2 lines because GL_LINE_ADJACENCY uses 4 points to draw a single line) But It draws only 4 shapes.

    glEnable(GL_DEPTH_TEST);
    ofSetVerticalSync(false);
    
    sh_p_render.setGeometryInputType(GL_LINES_ADJACENCY);
    sh_p_render.setGeometryOutputType(GL_TRIANGLE_STRIP);
    sh_p_render.setGeometryOutputCount(4);
    
    sh_p_render.load("shaders/p_render.vert",
                     "shaders/p_render.frag",
                     "shaders/p_render.geom");
    sh_p_pos.load("shaders/p_pos.vert","shaders/p_pos.frag");
   
    tex_w = 4;
    tex_h = 4;
    c_num = 8;
    
    vector<float> init_pos(tex_w * tex_h * c_num * 3);
    particles_mesh.setMode(OF_PRIMITIVE_LINES_ADJACENCY);
    
    float _x = 0;
    float _y = 0;
    
    for(int y = 0; y < tex_w; y++){
        for(int x = 0; x < tex_h; x++){
            
            for(int k = 0; k < c_num; k++){
                
                int i = ( tex_h * y + x ) * c_num + k;
                
                if(k == 0 || k % 4 == 2)
                {
                    _x = ofRandom(1.0);
                    _y = ofRandom(1.0);
                }
                    
                {
                    init_pos[i*3+0] = _x; //x
                    init_pos[i*3+1] = _y; //y
                    init_pos[i*3+2] = 0.0; //z
                }
                
                particles_mesh.addVertex({ x * c_num + k, y, 0 });

            }
        }
    }
    
    particles_p_PingPong.allocate(tex_w * c_num, tex_h, GL_RGB32F);
    particles_p_PingPong.src->getTexture().loadData(init_pos.data(), tex_w * c_num, tex_h, GL_RGB);
    particles_p_PingPong.dst->getTexture().loadData(init_pos.data(), tex_w * c_num, tex_h, GL_RGB);
    
    fbo_render.allocate(ofGetWidth(), ofGetHeight(), GL_RGB32F);
    fbo_render.begin();
    ofClear(0,0,0,255);
    fbo_render.end();

(Code for 3 : vertex shader)

#version 330

layout (location = 0) in vec4 position;

void main()
{
    gl_Position = position;
}

(Code for 3 : fragment shader)

#version 330

out vec4 FragColor;

uniform sampler2DRect pos_texture;

void main()
{
    vec2 tc = gl_FragCoord.xy - 0.5;
    vec4 pos = texture(pos_texture,tc);
    
    FragColor = pos;
}

(Code : update)

    glm::mat4 projection;
    glm::mat4 view = glm::mat4(1.0f);
    glm::mat4 model = glm::mat4(1.0f);
    
    float fov_angle = 45.0f;
    float camera_distance = (2.0 * 0.5) / tan(glm::radians(fov_angle * 0.5));
    
    projection = glm::perspective(glm::radians(fov_angle), (float)ofGetWidth() / (float)ofGetHeight(), 0.1f, 100.0f);
    model = glm::rotate(model, glm::radians(0.0f), glm::vec3(1.0f, 0.0f, 0.0f));
    view = glm::translate(view, glm::vec3(0.0f, 0.0f, -camera_distance));
    
    particles_p_PingPong.dst->begin();
    ofClear(0);
    {
        sh_p_pos.begin();
        
        sh_p_pos.setUniformTexture("pos_texture", particles_p_PingPong.src->getTexture(), 1);
       
        particles_p_PingPong.src->draw(0, 0);
        
        sh_p_pos.end();
    }
    particles_p_PingPong.dst->end();
    particles_p_PingPong.swap();
    
    fbo_render.begin();
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    {
        sh_p_render.begin();
        
        sh_p_render.setUniformMatrix4f("projection", projection);
        sh_p_render.setUniformMatrix4f("view", view);
        sh_p_render.setUniformMatrix4f("model", model);
        
        sh_p_render.setUniform1f("_LineWidth",0.05);
        sh_p_render.setUniformTexture("pos_texture", particles_p_PingPong.src->getTexture(), 1);
        sh_p_render.setUniform2f("res", (float)ofGetWidth(), (float)ofGetHeight());
        
        particles_mesh.draw();
        
        sh_p_render.end();
    }
    fbo_render.end();

(Code : draw)

    ofBackground(0);
    
    fbo_render.draw(0,0,ofGetWidth(),ofGetHeight());
    
    ofSetColor(255);
    ofDrawBitmapString("fps: " + ofToString((int)ofGetFrameRate()), 20, 20);

The wierd thing is when I comment out the code below from update, the program renders 16 shapes as intended. So I am guessing that the main problem is within the shader program.

    particles_p_PingPong.dst->begin();
    ofClear(0);
    {
        sh_p_pos.begin();
        
        sh_p_pos.setUniformTexture("pos_texture", particles_p_PingPong.src->getTexture(), 1);
       
        particles_p_PingPong.src->draw(0, 0);
        
        sh_p_pos.end();
    }
    particles_p_PingPong.dst->end();
    particles_p_PingPong.swap();

Another question I have is the part where I add the vertices to the mesh in setup.

for(int y = 0; y < tex_w; y++){
        for(int x = 0; x < tex_h; x++){
            
            for(int k = 0; k < c_num; k++){
                
                int i = ( tex_h * y + x ) * c_num + k;
                
                if(k == 0 || k % 4 == 2)
                {
                    _x = ofRandom(1.0);
                    _y = ofRandom(1.0);
                }
                    
                {
                    init_pos[i*3+0] = _x; //x
                    init_pos[i*3+1] = _y; //y
                    init_pos[i*3+2] = 0.0; //z
                }
                
                particles_mesh.addVertex({ x * c_num + k, y, 0 });

            }
        }
    }

I thought that adding vertices to a mesh is simply adding coordinates to the object, so initially I thought that I should put the values of _x and _y, but when I did that, no lines rendered on screen. So I think I’m not fully understanding what addVertex() actually does.

I omitted the code for the shader program that uses geometry shader because that part seems to be working ok for the moment.
It would be nice if I could get some information about how to deal with this problem. Thank you.

So I know now why changing input values of
particles_mesh.addVertex({ x * c_num + k, y, 0 });
had an affect on the final shape. It was because the rendering shader program was using the vertex coordinates as texture coordinates to get values from a texture. like so;
(vertex shader for rendering)

#version 330

layout (location = 0) in vec4 position;

uniform sampler2DRect pos_texture;
uniform vec2 res;

void main()
{
    vec2 verPos = position.xy;
    vec4 pos = texture(pos_texture,verPos);
    pos.xy = 2. * pos.xy - 1.;
    pos.x *= res.x / res.y;
    gl_Position = pos;
}

But I’m still at a loss to why the number of lines have decreased when I updated the texture with a seperate shader program.

This is the current problem. When I use the texture updating shader program, the number of line decreases. The below case is when I tried to draw 16 shapes each consisted of 2 lines.
(when I commented out the texture updating shader program)


(when I used the texture updating shader program)

I checked the texture image that I was using, and it turned out that exactly three quarters of the original image was disappearing.


This happens same with different width and height ratios.

I solved the problem! So basically, exactly three quarters of the texture data disappearing gave me the hint. It turns out the vertex shader used to update the texture did not pass the correct coordinates. I needed to multiply the position attributes by 2 and subtract 1 from it.

So the above code need to be fixed like below.

#version 330

layout (location = 0) in vec4 position;

void main()
{
    gl_Position = 2. * position - 1.;
}

I’m sorry again for the confusing explanations I have given above.