Copy camera ofTexture in to vector<ofTexture>

#1

i can’t figure out how to make a perfect copy of a texture.

i know i could read the texture’s pixels from the GPU back to the CPU and then load them in to a new texture.
but that seems like a lot of back and forth.

memcpy(videoData[nRecorded], vidPlayer.getPixels(), imgW*imgH*imgColors);
nRecorded++;

This does not work either because it only passes on the reference. As soon as oldTex changes newTex has the same data.

ofTexture newTex = oldTex;

someone in the form suggested to make an array of ofFbo’s, draw the old texture inside one ofFbo and so on.
is that the best option?

    frameCollector.push_back(ofFbo());
    frameCollector.back().allocate(fullFBO.getWidth(), fullFBO.getHeight(),GL_RGB);
    frameCollector.back().begin();
    fullFBO.draw(0,0);
    frameCollector.back().end();

Basically i am trying to fill a vector with the last x frames from my video feed.

Optimization: how to reduce data copying with fbo and ofThreadChannel
#2

Hi there!

I used this technique, works great but I don’t know if is the optimal solution: FBO/Texture to Buffer and Buffer To Texture Vector.

vector <ofTexture> previewTexture;
ofBufferObject bufferCopy;
ofTexture temptexture;

Setup:

bufferCopy.allocate(width * height * 4, GL_STATIC_DRAW);
temptexture.allocate(width, height, GL_RGBA);

Update:

/*   FBO to BUFFER   */
fbo.getTexture().copyTo(bufferCopy);

/*   BUFFER to TEXTURE VECTOR  */
temptexture.loadData(bufferCopy, GL_RGBA, GL_UNSIGNED_BYTE);
previewTexture.push_back(temptexture);

(example updated)

2 Likes
No method copyTo in ofTexture on Android?
#3

thanks. i will try and see which performs faster.

#4

Yes the only two ways to copy a texture without downloading to cpu is to draw it into an fbo or copy it to a buffer object and then copy the buffer object into the new texture. Be sure to allocate everything in setup not in update but other than that the examples you both posted are the way to do it.

#5

thanks for the input.
what problems could happen if i allocate during update?
i am using a vector of ofFbos who’s size i sometimes .clear() and then use .push_back() to add new ofFbos.
?

thanks.

#6

it’s way slower, try to allocate everything in setup and then reuse it. you can keep a second vector with references to the originals only with the resources you are using at every moment and clear and push_back into that instead. all the GL resources in OF can be used as references so you can do something like:

std::vector<ofTexture> texturePool;
std::vector<ofTexture> activeTextures;

// setup
texturePool.resize(32);
for(auto & texture, texturePool){
    texture.allocate(w,h,format);
}

// update
for(auto & texture: activeTextures){
    texturePool.push_back(texture);
}
activeTextures.clear();


activeTextures.push_back(texturePool.back())
texturePool.pop_back()

which just moves the texture from one vector to another instead of reallocating memory on every update

1 Like
#7

This approach almost worked for me. The issue I had was that by pushing temptexture multiple times into the vector, all the frames in the vector were equal.

What I did was something like this (in my case the vector size is fixed to 24):

vector <ofTexture> previewTexture;
ofBufferObject bufferCopy;

Setup:

bufferCopy.allocate(width * height * 4, GL_STATIC_DRAW);
previewTexture.resize(24);
for(auto & tex : previewTexture) {
  tex.allocate(width, height, GL_RGBA);
}

Update:

/*   FBO to BUFFER   */
fbo.getTexture().copyTo(bufferCopy);

/*   BUFFER to TEXTURE VECTOR  */
previewTexture[i].loadData(bufferCopy, GL_RGBA, GL_UNSIGNED_BYTE);

I think that if I wanted to use push_back(), I would have to create a new texture each time instead of pushing the same one, to avoid having the same image repeated. At least that’s what I experienced in my program.