error drawing texture

hi, i have a problem with a code, the idea is to iterate over the pixels of an image and get the dark pixels and put them in a new vector, then draw my vector into a texture. The thing is that im getting a wierd behaivor, it seems it grabs the pixels fine, but theres a problem in the way how it draws back into the texture, i can see some kind of pattern in the texture , but i dont know what is going wrong, any idea?

here is an example of the result i get:

http://www.moco.dreamhosters.com/imagen-…-exture.png

and here is the code

  
  
  
#include "testApp.h"  
#include "stdio.h"  
  
//--------------------------------------------------------------  
//testApp::testApp(){  
  
//}  
  
//--------------------------------------------------------------  
void testApp::setup(){  
    if (img.loadImage("ofImage.png")){  
        cout << "Image loaded." << endl;  
        unsigned char * pixels = img.getPixels();  
        int w = img.width;  
        int h = img.height;  
		int acu = 0;  
		int value = 0;  
  
	//en que casos conviene hacer dos iteraciones anidadas y en que caso hacer una sola iteracion?  
        for (int i = 0; i < w * 3; i++){  
            for (int j = 0; j < h * 3 ; j++){  
				value = value + pixels[j * w + j * 3];  
				acu = acu + 1;  
				if(acu == 4 )  
				{  
				acu = 0;  
				value = 0;  
				}  
				  
                //cout << value << endl;  
                if (value >= 0 && value <= 50)  
                    oscuros.push_back(value);  
			  
                else if (value >= 51 && value <= 101)  
                   
					  
					oscuros.push_back(255);  
				  
                else  
               
					oscuros.push_back(255);  
            }  
        }  
        cout << medios.size() << endl;  
  
    }  
    else  
        cout << "Error: Image not load" << endl;  
  
}  
  
  
//--------------------------------------------------------------  
void testApp::update(){  
    //cout << claros.size() << endl;  
	//GL_RGBA  
	tex.allocate(img.width * 3 , img.height * 3, GL_RGB);  
	tex.loadData(&oscuros[0], img.width , img.height , GL_RGB);  
}  
  
  
//--------------------------------------------------------------  
void testApp::draw(){  
    ofSetColor(0xffffff);  
    img.draw(0, 0);  
    tex.draw(540, 0, img.width   , img.height );  
	   
   
  
  
}  
  
//--------------------------------------------------------------  
void testApp::keyPressed  (int key){  
    //cout << key << endl;  
    if (key == 358){  
  
  
    }  
}  
  
//--------------------------------------------------------------  
void testApp::keyReleased(int key){  
  
}  
  
//--------------------------------------------------------------  
void testApp::mouseMoved(int x, int y ){  
}  
  
//--------------------------------------------------------------  
void testApp::mouseDragged(int x, int y, int button){  
}  
  
//--------------------------------------------------------------  
void testApp::mousePressed(int x, int y, int button){  
  
}  
//--------------------------------------------------------------  
void testApp::mouseReleased(int x, int y, int button){  
  
}  
  
  
  
  
  
  

two things look wrong to me:

  
  
//--------------------------------------------------------------  
void testApp::update(){  
    //cout << claros.size() << endl;  
   //GL_RGBA  
   tex.allocate(img.width * 3 , img.height * 3, GL_RGB);  
   tex.loadData(&oscuros[0], img.width , img.height , GL_RGB);  
}  
  

here, you are allocating a texture every frame – not a good idea! it’s just making the computer work more. you should allocate only once – usually setup is a good place to do it.

then, this looks wrong:

  
  
for (int i = 0; i < w * 3; i++){  
            for (int j = 0; j < h * 3 ; j++){  
            value = value + pixels[j * w + j * 3];  
  

I’m thinking it should be:

  
  
for (int i = 0; i < w; i++){  
            for (int j = 0; j < h ; j++){  
            value = value + pixels[ (j * w + i) * 3];  
  

I usually don’t do the * 3 in the for loop, but in the access:

ie, if you have a 5x5 image, and you want pixel 1,2 (and the first pixel is 0,0)

rgb rgb rgb rgb rgb
rgb rgb rgb rgb rgb
rgb rgb rgb rgb rgb
rgb rgb rgb rgb rgb
rgb rgb rgb rgb rgb

it’s (2*5+1)*3 = 33

rgb rgb rgb rgb rgb rgb rgb rgb rgb rgb rgb rgb

you’ll see 33 r,g,bs before the one we want.

if you wanted green, it’s

(2*5+1)*3 + 1

blue is:

(2*5+1)*3 + 2

hope that helps!
zach

thanks for the reply, what about if my image doesnt have the same weight and height for example if its 5 X 8 pixels

Should i multiply with witdh or height? and why?
(2* ? +1)*3

by the way i tried what you said but now im getting a black image with little pixels. i still doesnt know whats wrong in the code, any idea would be great , thanks

heres is what i get
http://www.moco.dreamhosters.com/imagen-…-xture2.png

and here the fixed code:

  
  
#include "testApp.h"  
#include "stdio.h"  
  
//--------------------------------------------------------------  
//testApp::testApp(){  
  
//}  
  
//--------------------------------------------------------------  
void testApp::setup(){  
    if (img.loadImage("ofImage.png")){  
        cout << "Image loaded." << endl;  
        unsigned char * pixels = img.getPixels();  
        int w = img.width;  
        int h = img.height;  
		int acu = 0;  
		int value = 0;  
  
        for (int i = 0; i < w ; i++){  
            for (int j = 0; j < h  ; j++){  
				value = value + pixels[ (j * w + i) * 3];  
				acu = acu + 1;  
				if(acu == 4 )  
				{  
				acu = 0;  
				value = 0;  
				}  
				  
                //cout << value << endl;  
                if (value >= 0 && value <= 50)  
                    oscuros.push_back(value);  
			  
                else if (value >= 51 && value <= 101)  
                   
					  
					oscuros.push_back(255);  
				  
                else  
               
					oscuros.push_back(255);  
            }  
        }  
        cout << medios.size() << endl;  
  
    }  
    else  
        cout << "Error: Image not load" << endl;  
		  
		  
		tex.allocate(img.width * 3 , img.height * 3, GL_RGB);  
		tex.loadData(&oscuros[0], img.width , img.height  , GL_RGB);  
  
}  
  
  
//--------------------------------------------------------------  
void testApp::update(){  
  
}  
  
  
//--------------------------------------------------------------  
void testApp::draw(){  
    ofSetColor(0xffffff);  
    img.draw(0, 0);  
    tex.draw(540, 0, img.width   , img.height );  
	   
   
  
  
}  
  
//--------------------------------------------------------------  
void testApp::keyPressed  (int key){  
    //cout << key << endl;  
    if (key == 358){  
  
  
    }  
}  
  
//--------------------------------------------------------------  
void testApp::keyReleased(int key){  
  
}  
  
//--------------------------------------------------------------  
void testApp::mouseMoved(int x, int y ){  
}  
  
//--------------------------------------------------------------  
void testApp::mouseDragged(int x, int y, int button){  
}  
  
//--------------------------------------------------------------  
void testApp::mousePressed(int x, int y, int button){  
  
}  
//--------------------------------------------------------------  
void testApp::mouseReleased(int x, int y, int button){  
  
}  
  
  
  

ok now the problem with your code is that you are saving one byte per pixel but you need three (red, green and blue). it should be:

  
if (value >= 0 && value <= 50){  
oscuros.push_back(red);  
oscuros.push_back(green);  
oscuros.push_back(blue);  
} else{  
oscuros.push_back(255);  
oscuros.push_back(255);  
oscuros.push_back(255);  
}  

this is because you do:

  
  
tex.loadData(&oscuros[0], img.width , img.height  , GL_RGB);  
  

(you are uploading RGB data)

to be sure, your total number of bytes should be w*h*3 for the color texture.

you can get red / green blue as:

  
  
redValue = pixels[ (j * w + i) * 3];  
greenValue = pixels[ (j * w + i) * 3 + 1];  
blueValue = pixels[ (j * w + i) * 3 + 2];  
  

this looks wrong:

  
  
tex.allocate(img.width * 3 , img.height * 3, GL_RGB);  
  

should be:

  
  
tex.allocate(img.width , img.height, GL_RGB);  
  

thanks for the reply, what about if my image doesnt have the same weight and height for example if its 5 X 8 pixels

Should i multiply with witdh or height? and why?
(2* ? +1)*3

general formula for pixel x,y is :
y * w + x

if it’s color, to get to the given pixel (since pixels are interleaved r,g,b) is:
(y * w + x) * 3

hope that helps!
zach

perfect! thanks