All pastes #202963 Raw Edit

Something

public text v1 · immutable
#202963 ·published 2006-10-14 21:09 UTC
rendered paste body
#include "PhotoBox.h"

// C'tor.
PhotoBox::PhotoBox()
{
	mpScreen = NULL;
	mbDone = false;
	mbWritten = false;	
}

// D'tor.
PhotoBox::~PhotoBox()
{
}

int PhotoBox::ResizeWindow(int iWidth, int iHeight)
{

	return 0;
    /* Height / width ration */
    GLfloat ratio;
 
    /* Protect against a divide by zero */
   if ( iHeight == 0 )
	iHeight = 1;

    ratio = ( GLfloat )iWidth / ( GLfloat )iHeight;

    /* Setup our viewport. */
    glViewport( 0, 0, ( GLsizei )iWidth, ( GLsizei )iHeight );

    /* change to the projection matrix and set our viewing volume. */
    glMatrixMode( GL_PROJECTION );
    glLoadIdentity( );

    /* Set our perspective */
    gluPerspective( 45.0f, ratio, 0.1f, 100.0f );

    /* Make sure we're chaning the model view and not the projection */
    glMatrixMode( GL_MODELVIEW );

    /* Reset The View */
    glLoadIdentity( );
	return (1);
}
/**
 * Setup SDL
 *
 * @version 0.1 [2006.10.07]
 */
bool PhotoBox::Init()
{
	if (!InitSDL())
		return (false);

	if (!InitCamera())
		return (false);
	
	//if (!InitOpenGL())
	//	return (false);
	
	return (true);
}


// Initialize OpenGL
bool PhotoBox::InitOpenGL()
{
	 // Sets up OpenGL double buffering 
	SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1 );
	SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
	SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
	SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
	SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
	

	glViewport(0,0, SCREEN_WIDTH, SCREEN_HEIGHT);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glOrtho(0,1,0,1,0,1);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	glEnable(GL_TEXTURE_2D);
	glDisable(GL_DEPTH_TEST);
	
	

    // Really Nice Perspective Calculations 
    //glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST );
	//ResizeWindow(SCREEN_WIDTH, SCREEN_HEIGHT);
	return (true);
}

// Initialize SDL
bool PhotoBox::InitSDL()
{
	int result = 0;

	// Initialize SDL's subsystems - in this case, only video.
	if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) 
	{
		fprintf(stderr, "Unable to init SDL: %s\n", SDL_GetError());
		exit(1);
	}
	atexit(SDL_Quit);
	
	// Video flag info.
	int videoFlags		 = 0;
	//videoFlags			|= SDL_OPENGL;
	
	// Store the palette in hardware 
    videoFlags			|= SDL_HWPALETTE;       
	
	// Enable window resizing 
    videoFlags			|= SDL_RESIZABLE;       
	
	//videoFlags			|= SDL_FULLSCREEN;

	// Get information from the videoinfo.
	const SDL_VideoInfo *videoInfo;
	videoInfo = SDL_GetVideoInfo( );
    if ( !videoInfo )
	{
	    fprintf( stderr, "Video query failed: %s\n",
		     SDL_GetError( ) );
	    return (false);
	}

	// HW supported?
    if ( videoInfo->hw_available )
		videoFlags |= SDL_HWSURFACE;
    else
		videoFlags |= SDL_SWSURFACE;

    // This checks if hardware blits can be done 
    if ( videoInfo->blit_hw )
		videoFlags |= SDL_HWACCEL;

	// Create the main sdl surface
	mpScreen = SDL_SetVideoMode( 
			 SCREEN_WIDTH
			,SCREEN_HEIGHT
			,SCREEN_BPP
			,videoFlags
	);

	if ( mpScreen == NULL ) 
	{
		return (false);
	}
	return (true);
}

// Initialize the camera using ARToolkit
bool PhotoBox::InitCamera()
{
	// Initialize the ARToolKit video subsystem
	int result = 0;
	char *vconf = "camera.xml";
	result = arVideoOpen(vconf);  
	if (result == -1)
	{
		return (false);
	}

	// This function returns the size of the captured video frame, in pixels.
	result = arVideoInqSize( &mDim[0], &mDim[1] );
	if (result == -1)
	{
		return (false);
	}

	// Start capturing.
	result = arVideoCapStart();
	if (result == -1)
	{	
		return (false);
	}

	mTexBuf = new unsigned char[mDim[0] * mDim[1] * 3];

	// Create a video surface for the camera
	Uint32 rmask, gmask, bmask, amask;
	#if SDL_BYTEORDER == SDL_BIG_ENDIAN

		rmask = 0x00ff0000;
		gmask = 0x0000ff00;
		bmask = 0xff000000;
		amask = 0x000000ff;
	#else
		rmask = 0x000000ff;
	    gmask = 0x0000ff00;
	    bmask = 0x00ff0000;
		amask = 0xff000000;
	#endif

	mpVideoSurface = SDL_CreateRGBSurface(
			SDL_HWSURFACE
			,mDim[0]			// width
			,mDim[1]
			,32
			,rmask
			,gmask
			,bmask
			,amask
	);
	return (true);
}

// Render a camera frame.
void PhotoBox::RenderCamera()
{
	ARUint8* buffer = NULL;
	buffer = arVideoGetImage();
	static unsigned char** ss_rows;
	if (buffer != NULL)
	{
		int y_offset = 0;
		unsigned char c;
		int pixel = 0;
		for (int y = 0; y < mDim[1]; ++y)
		{
			y_offset = y * mDim[0] * 3;
			for (int x = 0; x < mDim[0]; ++x)
			{
			
				// The << 2 multiplies the position by 4 moving
				// it to the correct location of the Uint8 buffer.
			
				c = buffer[ (((y) * mDim[0]+(x)) << 2) + 0];
				mTexBuf[y_offset + x * 3 + 0] = c;
 
				c = buffer[ (((y) * mDim[0]+(x)) << 2) + 1];
				mTexBuf[y_offset + x * 3 + 1] = c;
 
				c = buffer[ (((y) * mDim[0]+(x)) << 2) + 2];
				mTexBuf[y_offset + x * 3 + 2] = c;
			
			}
		}
		if (!mbWritten)
		{
			WritePNG("test.png",mTexBuf, mDim[0], mDim[1]);
//			LOG("Image written.\n");
			mbWritten = true;
		}

		// Draw the image to the screen
		SDL_Rect dstrect;
		//mpVideoSurface->pixels = mTexBuf;
		mpVideoSurface->pixels = buffer;
		dstrect.x = (mpScreen->w-mpVideoSurface->w)/2;
		dstrect.y = (mpScreen->h-mpVideoSurface->h)/2;
		dstrect.w = mpVideoSurface->w;
		dstrect.h = mpVideoSurface->h;
		if ( SDL_BlitSurface(mpVideoSurface, NULL, mpScreen, &dstrect) < 0 ) {
		    SDL_FreeSurface(mpVideoSurface);
		}

	}
	arVideoCapNext();
}

SDL_Surface *PhotoBox::CreateCompatibleSurface( int width, int height )
{
  SDL_Surface     *screen = SDL_GetVideoSurface();
   SDL_PixelFormat *PixelFormat = screen->format;
   int             flags = (screen->flags & SDL_HWSURFACE);
   SDL_Surface     *surf;

   surf = SDL_CreateRGBSurface( flags, width, height,
                               PixelFormat->BitsPerPixel,
                               PixelFormat->Rmask, PixelFormat->Gmask,
                               PixelFormat->Bmask, PixelFormat->Amask
                              );

   if ( !surf ) return NULL;

   if ( PixelFormat->palette && surf->format->palette )
   {
     memcpy( surf->format->palette->colors,
             PixelFormat->palette->colors,
             PixelFormat->palette->ncolors*sizeof(SDL_Color)
           );
     surf->format->palette->ncolors = PixelFormat->palette->ncolors;
   }
   return surf;
 }

// Helper function which writes a PNG image from a RGB color array.
int PhotoBox::WritePNG(char *fn, unsigned char *raster, unsigned int w, unsigned int h)
{
	FILE *fp;
	png_structp png;
	png_infop info;
	png_bytepp row_pointers;
	int i;

	/* create file */
	fp = fopen (fn, "wb");
	if (!fp) {
	   // xe_msg (1, "Can not create %s:\n%s", fn, syserrstr());
	    return (-1);
	}

	/* build list of pointers to each row */
	row_pointers = (png_bytepp) malloc (h * sizeof(png_bytep));
	if (!row_pointers) {
	   // xe_msg (1, "Can not malloc %d PNG row pointers", h);
	    fclose (fp);
	    return (-1);
	}
	for (i = 0; i < h; i++)
	    row_pointers[i] = raster + i*(w*3);

	/* write png */
	png = png_create_write_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
	info = png_create_info_struct (png);
	if (setjmp (png_jmpbuf (png))) {
	   // xe_msg (1, "PNG error");
	    png_destroy_write_struct (&png, &info);
	    free (row_pointers);
	    fclose (fp);
	    return (-1);
	}
	png_init_io(png, fp);
	png_set_IHDR (
			png								// png struct pointer
			,info							// header info
			,w								// width
			,h								// height
			,8								// bit depth
			,PNG_COLOR_TYPE_RGB				// color_type
			,PNG_INTERLACE_NONE				// interlace type
			,PNG_COMPRESSION_TYPE_DEFAULT	// compresssion type
			,PNG_FILTER_TYPE_DEFAULT		// filter type
	);
	
	png_write_info (png, info);
	png_write_image (png, row_pointers);
	png_write_end (png, info);
	png_destroy_write_struct (&png, &info);
	free (row_pointers);

	/* check for io error */
	if (ferror(fp)) {
	   // xe_msg (1, "Write error %s:\n%s", fn, syserrstr());
	    fclose (fp);
	    return (-1);
	}

	/* ok */
	fclose (fp);
	return (0);

}

/**
 * Execute the main loop, and capture events.
 *
 * @version 0.1 [2006.10.07]
 */
int PhotoBox::Exec()
{

	while (!mbDone)
	{
		// Render stuff
		Render();

		// Poll for events, and handle the ones we care about.
		SDL_Event event;
		
		while (SDL_PollEvent(&event)) 
		{
			// Handle input if the console is used.
			switch (event.type) 
			{
					case SDL_KEYDOWN:
						break;
					case SDL_KEYUP:
						// If escape is pressed, return (and thus, quit)
						if (event.key.keysym.sym == SDLK_ESCAPE)
						return 0;
						break;
					case SDL_QUIT:
					{
						ShutDown();
						mbDone = true;
						break;
					}
			}
		}
	}
	return(1);
}

/**
 * Renders the screen.
 *
 * @version 0.1 [2006.10.07]
 */
void PhotoBox::Render()
{
//    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

//	DisplayBMP("image.bmp");
	RenderCamera();
	SDL_UpdateRect(mpScreen, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);    
	
	
	//SDL_GL_SwapBuffers();
}


/**
 * Shuts down SDL, OGLConsole, OpenGL
 *
 * @version 0.1 [2006.10.07]
 */
void PhotoBox::ShutDown()
{                                                                          

    // Cleanup SDL
    SDL_Quit( );
}
	

// From SDL documentation, for testing purpose.
void PhotoBox::DisplayBMP(char *pFile)
{
 SDL_Surface *image;

    /* Load the BMP file into a surface */
    image = SDL_LoadBMP(pFile);
    if (image == NULL) {
        fprintf(stderr, "Couldn't load %s: %s\n", pFile, SDL_GetError());
//		LOG("File error");
        return;
    }

    /* Blit onto the screen surface */
    if(SDL_BlitSurface(image, NULL, mpScreen, NULL) < 0)
        fprintf(stderr, "BlitSurface error: %s\n", SDL_GetError());

    SDL_UpdateRect(mpScreen, 0, 0, image->w, image->h);

    /* Free the allocated BMP surface */
    SDL_FreeSurface(image);
}