PDA

View Full Version : glDrawPixels seems to "wrap" around viewport



lihom
07-15-2010, 10:37 PM
I'm writing a map maker (based on RPGMaker XP) for some openGL/C++ practice and after a few weeks working on the GUI I'm up to drawing and transferring images around the place.

My problem is that, when the underlying image for the map is larger than the viewport to display it, the tiles which extend past the viewport get duplicated at the beginning (horizontally) of the image. Also any placed at the far left will be likewise duplicated at the end.

In the image there is only one duplicate because the map size is 21 and 21-20=1, if it was 25 there would be 5.
http://img84.imageshack.us/img84/6262/openglproblem.png

The code for the panel drawing is:


glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glViewport(x,y,w,h);
gluOrtho2D(0,w,h,0);

glMatrixMode(GL_MODELVIEW);
glRasterPos2i(0,h);
glPixelStorei(GL_UNPACK_SKIP_ROWS,imageHeight(img)-h-yadj);
glDrawPixels(w,h,GL_RGBA,GL_UNSIGNED_BYTE,imageDat a(img));


and for setting the pixels in the map:



/*
p[0] is the tile x position of the mouse press on the map
p[1] is the tile y position of the mouse press on the map
*/
for (int j=0;j<tH-yoff;j++) {
for (int i=0;i<tW;i++) {
if (p[0]+i>=mappanel->imageW()) break; //to stop drawing if the set of tiles falls off the map
//get/set byte data
int mp = nC*(i+p[0]+(j+p[1])*mappanel->getW()); //get pixel position on map
int tp = nC*(i+j*tW); //and on tile

for (int k=0;k<nC;k++) { //for each channel
imageData(mappanel->image())[mp+k] = imageData(tile)[tp+k]; //copy the byte for each channel
}
}
}


It works perfectly for a width of 20, and I don't allow anything less than that, so it could break there as well and I wouldn't know it.

I can't think why it would happen apart from some obscure viewport/projection trick. Or more likely my pixel copying being wrong.

Any help is appreciated, and if you need more code (or all of it) let me know.

Cheers,
Jono

ZbuffeR
07-16-2010, 12:10 AM
imageData(mappanel->image())
So this is a pointer to a 1D array which is used with glDrawPixels(w,h,...) to draw a 2D rectangle of pixels.
When ever you draw at the far left side, farther than w, your data ends up on the left side on the following line.

You should draw a bunch of textured quads instead of doing heavy array manipulation on the cpu side.

lihom
07-16-2010, 02:00 AM
After you mentioned it I had a look at that image, and... surprise! The left-hand tiles are one pixel lower than they should be.

I thought something like that would be the problem. I should probably stick with the textures, since I know them a lot better but I was hoping to expand my skills.

Looks like I learned an important lesson, let the GPU do the graphics. That probably should have occurred to me earlier :P

Thanks!