UpdateRect produces a black screen

Hi

I have been working through a tutorial book that uses SDL. I have a piece of code that reads a ppm file and displays the image on the screen. The program seems to read the file and set the hight and width correctly creating a window the width and hight as the image but there is no image. If i move the image file the program return an error incating the image is missing so i know its reading it. Any help would be greatly appreicated. I have included the code.

Thankd

Steve

Code:
#include <stdio.h>
#include <stdlib.h>
#include <SDL.h>
#include <string.h>

//A public class is the same as a 'struct’
class CImage {
public:
unsigned char red;
unsigned char green;
unsigned char blue;
};

void ppm_read_comments ( FILE *fp )
{
int c;
while ( (c = getc ( fp ) ) == ‘#’ ) {
while ( getc( fp ) != ‘\n’ )
;
}
ungetc ( c, fp );
}

class ppm_error
{
public:
ppm_error() {
printf("\nIncorrect PPM format!\n");
exit ( 1 );
}
};

//change from (R, G, B) to (B, G, R)
void ppm2sdl ( CImage *ibuf, int width, int height )
{
unsigned char temp;

for ( int i = 0; i < height; ++i ) {
int row_offset = i * width;
for ( int j = 0; j < width; ++j ){
int offset = row_offset + j;
temp = ibuf[offset].red;
ibuf[offset].red = ibuf[offset].blue;
ibuf[offset].blue = temp;
}
}
}

int main( int argc, char* args[] )
{
int ppmh[20], c; //PPM header
int width, height; //image width and height
SDL_Surface *screen;
char filename[] = “C:/data/beach.ppm”;

FILE *input = fopen (filename, “rb”); //PPM file for testing read
if ( !input ) {
printf("\nError opening input file %s!\n", filename);
return 1;
}

//read PPM input file
ppm_read_comments ( input ); //read comments
char temp[100];
fscanf ( input, “%2s”, temp );
temp[3] = 0;
if ( strncmp ( temp, “P6”, 2 ) )
throw ppm_error();
ppm_read_comments ( input );
fscanf ( input, “%d”, &width );
ppm_read_comments ( input );
fscanf ( input, “%d”, &height );
ppm_read_comments ( input );
int colorlevels;
fscanf ( input, “%d”, &colorlevels );
printf("\n%s PPM file: “, temp );
printf(” \n\twidth=%d\theight=%d\tcolorlevles=%d\n", width,height,colorlevels+1 );
ppm_read_comments ( input );
while ( ( c = getc ( input )) == ‘\n’ ); //get rid of extra line returns
ungetc ( c ,input );

// May use CImage ibuf[width][height] if we do not use SDL_QUIT;
CImage *ibuf = (CImage *) malloc ( width * height * 3 );
fread ( ibuf, 3, width * height, input ); //read image data from file
fclose ( input );

//initialize video system
if ( SDL_Init( SDL_INIT_VIDEO ) < 0 ) {
fprintf(stderr, “Unable to init SDL: %s\n”, SDL_GetError());
exit(1);
}
//ensure SDL_Quit is called when the program exits
atexit(SDL_Quit); //if not use this, we need to
// do house cleaning manually when program ends

//set video mode of width x height with 24-bit pixels
screen = SDL_SetVideoMode( width, height, 24, SDL_SWSURFACE);
if ( screen == NULL ) {
fprintf(stderr, “Unable to set %dx%d video: %s\n”, width, height, SDL_GetError());
exit(1);
}

//convert PPM format (R, G, B) to SDL format (B, G, R)
ppm2sdl ( ibuf, width, height );

screen->pixels = ibuf; //point framebuffer to data buffer

//  ibuf needs to be dynamically allocated if SDL_QUIT is used
printf("update rect\n"   );
SDL_UpdateRect ( screen, 0, 0, 0, 0 );	//blit data to screen

// SDL_Flip(screen);
// SDL_CreateRGBSurface(screen, 0, 0, 0, 0,0,0,0);

SDL_Delay ( 4000 ); //delay 4 seconds before exit
printf(“Displaying PPM image %s successful!\n”, filename );

//do NOT free( ibuf ) if use SDL_QUIT which does the house cleaning
return 0;
}------------------------
Steve

I have been doing some work trying to figure this out, i have read into the program a ppm file containing red square and tested its in memory using the following code

Code:
printf(" \n\tred=%d\tgreen=%d\tblue=%d\n", ibuf->red, ibuf->green, ibuf->blue);

which gives the expected result

red=255 green=0 blue=0

I think the problem is in the following section of code

Code:
screen->pixels = ibuf; //point framebuffer to data buffer

//  ibuf needs to be dynamically allocated if SDL_QUIT is used
printf("update rect\n"   );
SDL_UpdateRect ( screen, 0, 0, 0, 0 );   //blit data to screen

// SDL_Flip(screen);
// SDL_CreateRGBSurface(screen, 0, 0, 0, 0,0,0,0);

i point the screen pixels to the buffer then run SDL_UpdateRect and still a black screen, could anybody offer a sugestion to why this is?

Many thanks

Steve------------------------
Steve

Is there any particular reason you’re doing it that way? I don’t recommend
messing with the pixels member if you aren’t positive what is happening
behind the scenes, especially with the display (screen) surface. For
example, if the format and size of your “ibuf” isn’t identical to the
screen’s size and format, you might be asking SDL to run off the end of an
array.

I would suggest using SDL_CreateRGBSurfaceFrom() to make a surface out of
your PPM data and then blit (copy) it to the screen surface with
SDL_BlitSurface().

Also, you can load PPM formatted images with SDL_image and you don’t have
to do any extra, messy work.

Jonny DOn Mon, Feb 13, 2012 at 11:29 AM, ecomsteve wrote:

**
I have been doing some work trying to figure this out, i have read into
the program a ppm file containing red square and tested its in memory using
the following code

Code:

printf(" \n\tred=%d\tgreen=%d\tblue=%d\n", ibuf->red, ibuf->green,
ibuf->blue);

which gives the expected result

red=255 green=0 blue=0

I think the problem is in the following section of code

Code:

screen->pixels = ibuf; //point framebuffer to data buffer

//  ibuf needs to be dynamically allocated if SDL_QUIT is used
printf("update rect\n"   );
SDL_UpdateRect ( screen, 0, 0, 0, 0 );   //blit data to screen

// SDL_Flip(screen);
// SDL_CreateRGBSurface(screen, 0, 0, 0, 0,0,0,0);

i point the screen pixels to the buffer then run SDL_UpdateRect and still
a black screen, could anybody offer a sugestion to why this is?

Many thanks

Steve


Steve


SDL mailing list
SDL at lists.libsdl.org
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org

If all you’re wanting to do is load an image and display it on the screen, there are much easier ways of doing it. Let me know and I can put together a very small piece of code to do this for you.------------------------
The Legend of Edgar. A 2D platformer for Windows and Linux. (http://www.parallelrealities.co.uk/p/legend-of-edgar.html)

Thanks for the responses, the reason this code is more complicated is that my final goal is to have SDL to read a stream of data pixels through a USB connection. The video data will be delivered in a non-standard format, i was hoping to buffer each frame then blit the pixels to the screen, in doing this will creating a moving image.

I have set the buffer using the memory allocation function below

Code:

CImage *ibuf = (CImage *) malloc ( width * height * 3 );

I could look into the information regarding the pixel member to try and figure it out. I won’t need that piece of code riksweeney but thank you anyway------------------------
Steve

I have made some progess and managed to get an image displayed using the code listed my first post. The only issue is that the image is only capable of being displayed when the SDL_SetVideoMode is set to full screen, as shown below

Code:

screen = SDL_SetVideoMode(width, height, 24, SDL_SWSURFACE|SDL_FULLSCREEN);

Does anyone know why this works at full screen and and when in a window it is black? I would like to see the image in a window.

Thanks

Steve------------------------
Steve