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 OpenGLbool 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 SDLbool 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 ARToolkitbool 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 = 0xff000000; gmask = 0x00ff0000; bmask = 0x0000ff00; amask = 0x000000ff; #else rmask = 0x000000ff; gmask = 0x0000ff00; bmask = 0x00ff0000; amask = 0xff000000; #endif mpVideoSurface = SDL_CreateRGBSurface( SDL_HWSURFACE ,mDim[0] // width ,mDim[1] ,8 ,rmask ,gmask ,bmask ,amask ); return (true);}// 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();}// 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) { 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; // 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();}/** * 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);}