Search code examples
c++videoopenframeworksunsigned-char

Openframeworks, creating a video texture from two video grabbers


I am very new to C++ and image processing in general.

I want to create a new unsigned char*which represents an array of pixels for use with ofTexture. I currently have two similar arrays which are both from ofVideoGrabber objects.

I was hoping to achieve this by processing line by line, pixels of the first VideoGrabber followed by the pixels of the second. So that one video will be on the right and the other on the left.

The final texture will be the width of the combined videoGrabber arrays. where as the height will be the same as a single videoGrabber.

As far as I can tell my logic is sound but my code produces strange results.

unsigned char* videoSample::createSample(unsigned char* left, unsigned char* right)
{
texture = new unsigned char[((vidWidth*2)*vidHeight)*3];
int totalSize = ((vidWidth*2)*vidHeight)*3;
bool drawLeft=true;                             //flag for indicating which video grabber to draw from
int l=0;                                        //for counting the pixels of the left video
int r=0;                                        //for counting the pixels of the right video
for(int i = 0; i < totalSize; i++)
{

    if(i%vidWidth==0)
    {
        drawLeft=!drawLeft;
    }
    if(drawLeft)
    {
        l++;
    }
    else
    {
        r++;
    }
    if(drawLeft)
    {
        texture[i] = left[l];
    }
    else
    {
        texture[i] = right[r];
    }
}
return texture;
}

If anyone could suggest to me a better way of doing this or point out a flaw in my code I'd be pleased to hear it, thank you.


Solution

  • You should probably use the ofTextures of the video grabbers directly and draw them to an FBO to do this as it will be simpler and more efficient. For example:

    videoSample.h:

    #pragma once
    #include "ofMain.h"
    
    class videoSample {
    
        ofFbo fbo;
        /* ... */
    
        public:
            void setup();
            ofTexture& createSample(ofVideoGrabber& v1, ofVideoGrabber& v2);
    };
    

    videoSample.cpp:

    #include "videoSample.h"
    
    void videoSample::setup(){
        // Allocate the FBO
        fbo.allocate(vidWidth * 2, vidHeight, GL_RGBA);
        // Clear its content
        fbo.begin();
            ofClear(0, 0, 0, 0);
        fbo.end();
    }
    
    
    ofTexture& videoSample::createSample(ofVideoGrabber& v1, ofVideoGrabber& v2){
        fbo.begin();
            // Draw the texture of the first video grabber at x = 0 and y = 0
            v1.getTextureReference().draw(0, 0);
            // Draw the texture of the second video grabber at x = vidWidth and y = 0
            v2.getTextureReference().draw(vidWidth, 0);
        fbo.end();  
        // Finally return the reference to the fbo's texture 
        return fbo.getTextureReference();
    }
    

    Don't forget to call setup(), for example in your ofApp::setup() otherwise the FBO won't be allocated and it won't work.