getting the pixels out of a texture

hello,

yet another question:

i’m trying to load the pixels out of a GL texture to save them in an array and i’m having a bit of trouble. here’s what i have so far (it crashes the app):

  
  
unsigned char* texPixels = new unsigned char[640*480*4];  
glBindTexture(textureTarget, myTexHandle);  
glGetTexImage(textureTarget, 0, GL_RGBA, GL_UNSIGNED_BYTE, &texPixels);  
  

any ideas what i’m doing wrong?

thanks for the help.

I apologize for bumping this old thread but I was wondering if anyone had any insight about this. It would be much appreciated !!

Hi,
I just tried this and it works fine.

Just make sure that you allocate texPixels to be exactly the size of the texture you are getting. Also check that your texture is GL_RGB or GL_RGBA.

If it’s crashing my guess is that the texture you are getting using glGetTexImage() is larger than 640*480*4.

So I guess my question is, what size is your texture and does it have an alpha channel?

hmm,

be aware that pushing/pulling data to/from video memory is very slow and should be avoided.

why do you want to pull data off the video card anyway? this shouldn’t be necessary unless you’re capturing the screen, or doing rendering to a texture…

d

pulling data from video memory using tried and true methods is indeed slow but if you use pixel buffer objects http://www.songho.ca/opengl/gl-pbo.html it’s actually really fast and you won’t notice any real slowdown.

I’m trying to have character’s leave footprints when they walk across screen, after time those footprints will build up. The footprints would mask an image.

My idea of the process I’d go through to achieve this effect was:

footstepsMask = ofFBOTexture
footPrints = ofImage <-convert the image to pixels then add the A channel and end up with footPrintsRBGA (oftexture);

  
void ofBackgroundLayer::draw(){  
  
ofBackground(255,255,255);  
  
footstepsMask.swapIn();  
myFootseps.draw();     //capture the footsteps into the mask.  
footstepsMask.swapOut();  
  
glPushMatrix();  
footstepsMask.draw(0,0,1280,768);  //displays the footprints fine :-)  
glPopMatrix();  
  
//some how need to convert footstepsMask into pixels to use as the A //channel for the footprints image????  
  
  
ofEnableAlphaBlending();  
footPrintsRGBA.draw(0,0,1280, 768);  
ofDisableAlphaBlending();  
  
myWalkers.draw();  
  
}  

so I guess My question is: does anyone know how to convert a ofTexture to pixels??? I see it can be done using openGL but I don’t think my skill level is up to doing it that way yet (already tried).

Any help or pointers would be greatly appreciated.

so to recap, I’m just wanting to capture footsteps into texture, convert texture to pixels to use as A channel in an texture…

I already know how to add the pixels as the A channel in a RGBA texture, Zach made a nice example up :slight_smile:

Thankyou

Ian

hmm.

instead of working with image data, how about storing a list of the footstep positions and rotations, and redrawing all of the footsteps each frame? with a limited number of footsteps (say < 1000 or 10,000) this would perhaps still be faster than copying the pixels off the video hardware and then back on again…

Hey Damian,

I see, so copying off and on does take a lot of time, even useing ofFBOTexture?. hmm. Because of the nature of the scene, logging individual footsteps wouldn’t work as there’s infinite variations :slight_smile:

Ian

ha, I forgot that ofimage can also screen capture, So I got it working (somewhat).
But its running too slow, 20fps when its set at 50.

My only chance I can think of now is to figure out how to do a luma mask type effect with openGL blending. oh oooo

heres my code anyway could be doing something really dumb, I think its just too much for it to do in runtime:

  
void ofResourceScene::draw(){  
  
ofBackground(255,255,255);  
  
screenMask.draw(0, 100, BlueScratched.width,BlueScratched.height);  
  
 for (int i = 0; i < MAX_SCRAPERS; i++) {  
 myS3Mask[i]->draw();  
   }  
     
screenMask.grabScreen(0, 100, BlueScratched.width,BlueScratched.height);  
screenMask.setImageType(OF_IMAGE_GRAYSCALE);  
  
  
    unsigned char * allPixels = new unsigned char[BlueScratched.width*BlueScratched.height*4];  
	unsigned char * colorPixels = BlueScratched.getPixels();  
	unsigned char * alphaPixels = screenMask.getPixels();  
  
  
  
		for (int i = 0; i < BlueScratched.width; i++){  
		for (int j = 0; j < BlueScratched.height; j++){  
			int pos = (j * BlueScratched.width + i);  
			allPixels[pos*4  ] = colorPixels[pos * 3];  
			allPixels[pos*4+1] = colorPixels[pos * 3+1];  
			allPixels[pos*4+2] = colorPixels[pos * 3+2];      
			allPixels[pos*4+3] = alphaPixels[pos];  
		}  
	}  
  
ofBackground(255,255,255);  
  
	blueScratchedComplete.allocate(BlueScratched.width,BlueScratched.height,GL_RGBA);  
	blueScratchedComplete.loadData(allPixels, BlueScratched.width,BlueScratched.height,GL_RGBA);  
    delete [] allPixels;  
  
    ofEnableAlphaBlending();  
	blueScratchedComplete.draw(0, 100);  
    ofDisableAlphaBlending();  
  
  
 for (int i = 0; i < MAX_SCRAPERS; i++) {  
 myScraper[i]->draw();  
}  
  
}