Help Please!

I am trying to read a .PGM/PPM file and display the image in the screen. I think I am doing everything right. I read the type of file, height,width,etc… at the end I just get a blank screen. I don’t know what I am missing… I just started programming in OPEN GL this week so I am a novice. Here is my code

#include <Windows.h>

#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
//---------------> Experiment <-----------------------
#include <fstream>
//---------------> Experiment <-----------------------
#include <malloc.h>

using namespace std;

/* Global variables */

#define MAXLINE 80 /* maximum length of a line of text */

GLint windW, windH; /* size of the window on the screen */

GLubyte Picture; / Array of pixels */

int filetype;

enum {PGM, PPM}; /* possible file types */

typedef int* ip;

//-----------------> Experiment <------------------------------------
char *image;

int **imatrix(int nrl,int nrh,int ncl,int nch)
{
int i;
int **m;

m = new ip[nrh-nrl+1];
if (!m) {
cout << “allocation failure in matrix”;
exit(1);
}
m -= nrl;
for (i=nrl;i<=nrh;i++) {
m[i] = new int[nch-ncl+1];
if (!m[i]) {
cout << “allocation failure in matrix”;
exit(1);
}
m[i] -= ncl;
}
return m;
}
//-----------------> Experiment <------------------------------------

/* Read in picture from a PPM or PGM file */

void readPPM (char *filename, GLubyte **pic) {

FILE *fp;
char line[MAXLINE];
int i, j, size, rowsize;
GLubyte *ptr;

/* Read in file type */

fp = fopen(filename, “rb”);

fgets (line, MAXLINE, fp); /* 1st line: PPM or PGM */

if (line[1] == ‘5’){
filetype = PGM;
cout << “Reading PGM” << endl; // DEBUG
}
else if (line[1] == ‘6’){
filetype = PPM;
cout << “Reading PPM” << endl; // DEBUG
}
else {
printf("Error: need PPM or PGM file as input!
");
exit(1);
}

/* Read Comments */

fgets (line, MAXLINE, fp); /* 2nd line: Comments */
cout << "Comments: " << line << endl; // DEBUG

/* Read in width and height, & allocate space */

fgets (line, MAXLINE, fp); /* 3rd line: width height */
sscanf(line, “%d %d”, &windW, &windH);

printf ("Width is %d, height is %d
", windW, windH);

if (filetype == PGM) {
size = windH * windW; /* greymap: 1 byte per pixel /
rowsize = windW;
}
else /
filetype == PPM / {
size = windH * windW * 3; /
pixmap: 3 bytes per pixel */
rowsize = windW * 3;
}

*pic = (GLubyte *)malloc (size);

/* Read in maximum value (ignore) /
fgets (line, MAXLINE, fp); /
4th line */
cout << "Scale " << line << endl; // DEBUG

image = new char[size];

/* Read in the pixel array row-by-row: 1st row = top scanline */
fread((void *)image, 1, size, fp);

fclose(fp);
}

/* Initialization: create window */

void Init(void) {
glutInitWindowPosition(0, 0);
glutInitWindowSize(windW, windH);
glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);

if (glutCreateWindow("Image") == GL_FALSE) {
	exit(1);
}

}

/* Draw the picture on the screen */

void Draw(void) {
glRasterPos2i(0, 0);

if (filetype == PGM)	/* greymap: use as illumination values */
      glDrawPixels(windW, windH, GL_LUMINANCE, GL_UNSIGNED_BYTE, image);
else // filetype == PPM
	glDrawPixels(windW, windH, GL_RGB, GL_UNSIGNED_BYTE, Picture);

}

/* Resize the picture */

void Resize(GLint w, GLint h) {
// windW = w;
// windH = h;

glViewport(0, 0, w, h);

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0, windW, 0, windH);
glMatrixMode(GL_MODELVIEW);

}

static void Key(unsigned char key, int x, int y)
{
switch (key) {
case 27:
exit(1);
default:
return;
}
}

/* Main program */

void main(int argc, char **argv)
{
char filename[MAXLINE];

/* Read in the file (allocates space for Picture) */

if (argc &lt; 2) {
	printf ("Enter the name of a PPM or PGM file: ");
	scanf("%s", filename);
	readPPM ((char *)filename, &Picture);
}
else {
	readPPM (argv[1], &Picture);
}

//glutInit(&argc, argv);
Init();
glutDisplayFunc(Draw);
glutReshapeFunc(Resize);
glutKeyboardFunc(Key);
glutSwapBuffers(); 
glutMainLoop();

}

For starters, maybe grab one of the free image loading libraries (e.g. DevIL), so you can be reasonably sure you’re debugging OpenGL rather than your loader.

Next you might check out the redbook examples on texturing.
http://www.opengl.org/resources/code/samples/redbook/

As always, be sure to call glGetError here and there to check for the occasional slip up.

Hey Modus… thank your for your reply. I did look at the DevIL library and they don’t support PPM/PGMs file loading. It’s true. I should be debuggin OPEN GL and not the loading part of the images… do you have any specific suggestions where I can find an example of loading an PPM/PGM image?

sure? According to the docs they’re supported (loading and saving).

Add glutSwapBuffers(); to the end of the draw function

Hi,

there’s a little mess there. For glutSwapBuffers(), you need to be using a double buffered window. You are currently using a single buffered window, as in your glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE) call. Change GLUT_SINGLE for GLUT_DOUBLE for a double buffered window.

glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE)

In order display something, you need to update (swap) your buffer. You need to call glutSwapBuffers(). As you are not calling it nowhere in your Draw() function, it seems like you are not updating your display with anything, and thus the blank screen. You should follow ac_nl post and add glutSwapBuffers() in the end of your Draw() function so that any changes you make to your buffer are displayed.

Hope that helps.

I missed that one, but yes, enunes is correct (although, it still works with SINGLE instead of DOUBLE).

Furthermore, I’m curious as why you first use the ‘image’ variable in ‘glDrawPixels(windW, windH, GL_LUMINANCE, GL_UNSIGNED_BYTE, image);’ for the PGM and later ‘Picture’ in ‘glDrawPixels(windW, windH, GL_RGB, GL_UNSIGNED_BYTE, Picture);’. Why not use ‘image’ in both?

Also, watch out that a comment line is not always included in pgm/ppm files.

/* Get commentary (optional) */
fgets (line, MAXLINE, picture);
while (line[0] == '#') {
	cout &lt;&lt; "Comment: " &lt;&lt; line &lt;&lt; endl;
	fgets (line, MAXLINE, picture);
}

/* Get height and width */
sscanf(line, "%d %d", &width, &height);