Regarding glDrawPixels using GLUT

Hi, currently I’m trying to use GLUT and glDrawPixels to draw out an image captured from my webcam. The image I saved it as my own format at 640x480x24bit color in a format like RGBRGBRGB… up to 921600 elements and each element is 1 byte of unsigned char ( ie 8-bit level of that component )

My program is like trying to read in a frame of 640x480 from the file and display it in a window using OpenGL thru GLUT. Below is a short code of my method, but it only display a black screen window. I’m using MS VC++ 6.0 to compile. May I know what goes wrong here? I can verify that my image data is correct cuz I can read in the same file and write it out as a bmp file, which displays alrite.

#include <assert.h>
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <sys/timeb.h>
#include <GL/glut.h>
#include <GL/gl.h>

char fn[32];
int i,j;
FILE* sav;
unsigned char *buffer;
long lSize;
int wrt;

void display(void){

glClear(GL_COLOR_BUFFER_BIT);
glRasterPos3f(0.0,0.0,-20.0);
glDrawPixels(640, 480, GL_RGB, GL_UNSIGNED_BYTE, buffer);
glFlush();
free(buffer);

}

void init(){

glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glShadeModel(GL_SMOOTH);

sav = fopen ("RGB.raw","rb");

fseek (sav , 0 , SEEK_END);
lSize = ftell (sav);
rewind (sav);
printf("Total size of file is %d bytes

", lSize);

buffer = (unsigned char*) malloc (921600);
wrt=fread(buffer,1,921600,sav);

}

void
reshape(int w, int h)
{
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0, w, h, 0);
glMatrixMode(GL_MODELVIEW);
}

int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB );
glutInitWindowSize(640, 480);

glutCreateWindow(“Testing”);
init();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMainLoop();

return 0;

}

BTW, I will be eventually trying to read in a big file of many frames of RGB data, and displaying it like a video stream, ala a WMP using opengl. Later I will extend it to displaying it realtime on the live capture from my webcam. So I need to get this right on this simple code of reading in only one frame and displaying it. ( which I couldn’t =p from the above code)

Thanks for ur help.

OpenGL has the origin in the lower left corner, and every image drawn (unless you modify the pixel pack and/or unpack values) from the raster position and upwards. With your projection matrix you place the raster position in the upper left corner. Since OpenGL draws the image upwards, and it starts on the uppermost row… you can figure out what’s happening.

Another problem is that you place the raster position way outside the view volume, and it will be clipped and marked as invalid. The gluOrtho2D call set’s the near and far clip plane to -1 and 1 respectively, but you set the Z-coordinate of the raster position to -20, which is not between the two clip planes.

I suggest you use glRasterPos2f instead and ditch the last parameter, and then swap the two last parameters of gluOrtho2D to set the origin in the lower left corner instead, which is the “natural” place for OpenGL.

Hi, thanks for the tip. I’ve set the glRasterPos2f(-1,-1) and it works ok. (0,0) actually sets the lower left corner to the center of the GLUT window.

As what u had mention, I’d encounter this inverted image, because my image data pixel pack is from top to bottom format, whereas opengl draw from bottom to top. I created a function to flip the image in memory b4 passing to glDrawPixels, but seems like it will slow down the framerate ( I’m trying to display 640x480x24bit image at 30Hz ). Are there any ways to make OpenGL draw from top to bottom?

Everything is the same you have just inverted your image I don;t see how this can slow down your framerate. Your not inverting ‘every frame’ are you!?

You should flip once, and use that one all the time. Unless you get some streaming video from an external source or something similar of course. But in that case, I recomend a texture instead. The texture can be flipped for free.

other options set the viewport upside down (if you are filing the window) or use glScalef with a negative value. I assume these would work. Never tried, but not as quick as texturing, maybe what you want though.