Reading vertices on CPU with transform feedback not giving any result

I’m coding an app where I have to render a 3D model on GPU with a moving camera and then get the 3d coordinates of visible vertices.
What I started doing was to get the whole texture of the 3d coordinates after rendering with glGetTexImage .It is pretty expensive, espicially that the camera is far from the object so the texels that contain 3d coordinates are a small part of the texture I use. So I want to only read the texels I need.

I couldn’t find a tutorial that does the same thing so I tried on my own.
What I tried then was to use a geometry shader to emit vertices with non 0 coordinates. Then I use TransformFeedback to get the emitted vertices.
Here are The Vertex and Geometry Shaders :

    //Geometry Shader
    #version 330 compatibility
 
    layout(points) in; 
    layout(points, max_vertices = 1) out; 
 
    uniform sampler2D pos3d; 
    in vec2 io_texCoord;
    out vec3 pos3dOut; 
 
    void main () 
    { 
	 
	ivec2 texelCoord = ivec2(io_texCoord); 
	vec3 position = texelFetch(pos3d, texelCoord, 0).xyz; 
	if(position.x != 0.0 ||position.y != 0.0 ||position.z != 0.0) 
	{
		pos3dOut =position;
		EmitVertex(); 
		EndPrimitive(); 
	   }
    }
    //Vertex Shader
    #version 330 compatibility				
    in vec2 inCoords;
    out uvec2 io_texCoord;

    void main(){
	    gl_Position = vec4(inCoords,0.0,1.0);
	    io_texCoord = uvec2(inCoords);
    }

And then the code to read coordinates:

    //Init
    glUseProgram(program);
    glEnable(GL_RASTERIZER_DISCARD);

    GLuint VAO_transfer = 0, VBO_transfer = 0,TBO_transfer = 0;
    glGenVertexArrays(1, &VAO_transfer);
    glBindVertexArray(VAO_transfer);
    GLfloat* data = new GLfloat[width*height * 2];
    for (int j = 0; j < height; j++)
    {
	    for (int i = 0; i < width; i++)
	    {
		    data[(j*width*2) +(i*2)] = i;
		    data[(j*width * 2) + (i * 2)+1] = j;
	    }
    }
    glGenBuffers(1, &VBO_transfer);
    glBindBuffer(GL_ARRAY_BUFFER, VBO_transfer);
    glBufferStorage(GL_ARRAY_BUFFER, (width*height * 2) * sizeof(GLfloat), data, GL_STATIC_DRAW);
    delete[] data;

    GLint coordsAttrib = glGetAttribLocation(program, "inCoords");
    glEnableVertexAttribArray(coordsAttrib);
    glVertexAttribPointer(coordsAttrib, 2, GL_FLOAT, GL_FALSE,0, 0);


    glBindBuffer(GL_ARRAY_BUFFER,0);
    glBindVertexArray(0);
    glGenBuffers(1, &TBO_transfer);
    glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, TBO_transfer);
    glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, (width*height) * 3 * sizeof(GLfloat), NULL, GL_STREAM_COPY);

    glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, 0);

    GLuint sizeDataToCopy = 3*sizeof(GLfloat)*width * height;
    char dataToCopy[sizeDataToCopy];
    GLuint copyBuffer;
    glGenBuffers(1, &copyBuffer);
    glBindBuffer(GL_COPY_WRITE_BUFFER, copyBuffer);
    glBufferData(GL_COPY_WRITE_BUFFER, sizeDataToCopy, dataToCopy, GL_STATIC_COPY);

    glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, TBO_transfer);
    glCopyBufferSubData(GL_COPY_WRITE_BUFFER, GL_TRANSFORM_FEEDBACK_BUFFER, 0, 0, sizeDataToCopy);


    const float *bufferData = static_cast<float *>(glMapBufferRange(
		GL_TRANSFORM_FEEDBACK_BUFFER, 0, 3*sizeof(GLfloat) * width * height, GL_MAP_READ_BIT));
	

    glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, 0);
    glBindBuffer(GL_COPY_WRITE_BUFFER, 0);
    glDeleteBuffers(1, &copyBuffer);


    ///Transfer
    glActiveTexture(GL_TEXTURE0);
    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, pos3d);

    glUniform1i(glGetUniformLocation(program, "pos3d"), 0);
    glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, TBO_transfer);
    glBindVertexArray(VAO_transfer);

    GLuint primitivesWrittenQuery = 0;
    glGenQueries(1, &primitivesWrittenQuery);
    glBeginQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, primitivesWrittenQuery);
    glBeginTransformFeedback(GL_POINTS);
    glDrawArrays(GL_POINTS, 0, width * height);
    glEndTransformFeedback();
    glEndQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN);

    glDisable(GL_RASTERIZER_DISCARD);
   
    GLint primitiveWritten = 0;
    glGetQueryObjectiv(primitivesWrittenQuery, GL_QUERY_RESULT,&primitiveWritten);
    std::cout << "Primitives Number   : " << primitiveWritten << std::endl;
    for (int i = 0; i < primitiveWritten; i++)
    {
	    bufferData = static_cast<float *>(glMapBufferRange(
		GL_TRANSFORM_FEEDBACK_BUFFER, 0, _sizeOfPrimitive * width * height, GL_MAP_READ_BIT));
	    std::cout << "Primitive " << i << "  :  " << bufferData << std::endl;
    }

    primitiveWritten = 0;
    glUnmapBuffer(GL_TRANSFORM_FEEDBACK_BUFFER);

I don’t know what I’m doing wrong but I’m not getting any results the “primitiveWritten” = 0.
I would appreciate any help or a clear tutorial that does similar things.