view TaskManager/Test/simple_render/viewer.cpp @ 26:3f68b2ef4fb0

*** empty log message ***
author gongo
date Sun, 10 Feb 2008 18:31:48 +0900
parents
children 243ee0a1fe6f
line wrap: on
line source

#include <iostream>
#include <SDL.h>
#include <SDL_opengl.h>
#include <math.h>
#include "polygon.h"
//#include "demonstration.h"
//#include "scene.h"
#include "viewer.h"
#include "sys.h"
using namespace std;

extern int create_sgp(SceneGraphPack *sgp, Polygon *sg);
extern int update_sgp(SceneGraphPack *sgp, SceneGraphPack *_sgp);
extern int create_pp(PolygonPack *pp, SceneGraphPack *sgp);

Viewer::Viewer(int b, int w, int h)
{
  bpp = b;
  width = w;
  height = h;
}


void Viewer::sdl_init()
{
  if( SDL_Init( SDL_INIT_VIDEO ) < 0 )
    {
      fprintf(stderr,"Couldn't initialize SDL: %s\n",SDL_GetError());
      exit( 1 );
    }
  screen = SDL_SetVideoMode( width, height, bpp, SDL_HWSURFACE );

  //manager = new TaskManager(1);
  //manager->init();

  manager->set_symbol("CreateSGP", (void*)create_sgp);
  manager->set_symbol("UpdateSGP", (void*)update_sgp);
  manager->set_symbol("CreatePP", (void*)create_pp);
}


void Viewer::init()
{
  if(SDL_Init( SDL_INIT_VIDEO ) < 0)
    {
      cout << "Couldn't initialize SDL:" << SDL_GetError() << endl;
      exit(1);
    }

  /* See if we should detect the display depth */
  if(bpp == 0) 
    {
      if (SDL_GetVideoInfo()->vfmt->BitsPerPixel <= 8)
        {
          bpp = 8;
        }
      else 
        {
          bpp = 16;  /* More doesn't seem to work */
        }
    }

  //video_flags = SDL_OPENGL;
  video_flags = SDL_HWSURFACE;

  /* Initialize the display */
  switch (bpp) 
    {
    case 8:
      rgb_size[0] = 3;
      rgb_size[1] = 3;
      rgb_size[2] = 2;
      break;
    case 15:
    case 16:
      rgb_size[0] = 5;
      rgb_size[1] = 5;
      rgb_size[2] = 5;
      break;
    default:
      rgb_size[0] = 8;
      rgb_size[1] = 8;
      rgb_size[2] = 8;
      break;
    }

  SDL_GL_SetAttribute(SDL_GL_RED_SIZE, rgb_size[0]);
  SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, rgb_size[1]);
  SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, rgb_size[2]);
  SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
  SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);

  SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, 0);

  screen = SDL_SetVideoMode(width, height, bpp, video_flags);
  
  if(screen == NULL)
    {
      cout << "Couldn't set GL mode: " <<  SDL_GetError() << endl;
      SDL_Quit();
      exit(1);
    }

  SDL_WM_SetCaption("SDL GL test", "testgl");

  glViewport(0, 0, width, height);

  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  
  glOrtho(-width/10, width/10, -height/10, height/10, -40.0, 400.0);
  
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
  
  glEnable(GL_DEPTH_TEST);
  
  glDepthFunc(GL_LESS);
  
  glShadeModel(GL_SMOOTH);
}

int Viewer::get_ticks()
{
  int time;
  time = SDL_GetTicks();
  return time;
}

bool Viewer::quit_check()
{
  bool quit = false;
  SDL_Event event;
  while(SDL_PollEvent(&event))
    {
      if(event.type==SDL_QUIT)
	{
	  quit = true;
	  return quit;
	}
    }
  return quit;
}

void Viewer::quit()
{
  SDL_Quit();
}


void Viewer::swap_buffers()
{
  SDL_GL_SwapBuffers();
}


void Viewer::write_pixel(int x, int y,float z, Uint32 rgb) {
  SDL_PixelFormat *pf;
  pf = screen->format;
  //printf("x:%d y:%d z:%d\n",x,y,z);

  //cout << "write_pixel" << endl;
  //cout << x << "  " << y << endl;

  //cout << SDL_MapRGB(pf,0,0,150) << endl;

  x += width/2;
  y += height/2;

  static int diffz,diffz1;
  diffz1 = diffz;
  diffz = (zRow[x][y]>z);
  if(diffz != diffz1) {
	//printf("diffz :%d zRow[%d][%d] = %f z = %f\n",diffz,x,y,zRow[x][y],z);
  }
 //printf("x:%d,y:%d,z:%f,zRow:%f\n",x,y,z,zRow[x][y]);
 if(z < zRow[x][y]) { 
//	 printf("x:%d,y:%d,z:%d\n",x,y,z,zRow);
  if(x < width && x > 0 && y > 0 && y < height)
    {
      //pixels[width*y + x] = SDL_MapRGB(pf,70,70,71);
	 zRow[x][y] = z;
	 y = height - y;
      pixels[width*y + x] = rgb;
    }
 }
}

void Viewer::write_line(float x1, float y1, float x2, float y2, Uint32 rgb)
{
  //cout << "write_line("<< x1 << "," << y1 << "," << x2 << "," << y2 << ")"<< endl;

  //Uint32 rgb = 9830400;

  if(x1 > x2)
    {
      float x=0;
      float y=0;
      x=x1;
      y=y1;
      x1 = x2;
      y1 = y2;
      x2 = x;
      y2 = y;
    }
  float s = y1;

  if((int)x1 == (int)x2)
    {
      if(y1 > y2)
	{
	  float y=0;
	  y = y1;
	  y1 = y2;
	  y2 = y;
	}
      for(float i=y1; i<y2; i++)
	{
	  //write_pixel((int)x1,(int)i);
	  write_pixel((int)x1,(int)i,0,rgb);
	}
    }
  else 
    {
      float t = (y2 - y1)/(x2 - x1);
      if(t < -1)
	{
	  float f = 0;
	  for(float i=x1; i<x2; i++)
	    {
	      for(float a=(int)t; a<0; a++)
		{
		  //write_pixel((int)i,(int)s);
		  write_pixel((int)i,(int)s,0,rgb);
		  s--;
		}
	      f += t-(int)t;
	      if(f <= -1)
		{
		  //write_pixel((int)i,(int)s);
		  write_pixel((int)i,(int)s,0,rgb);
		  f = 0;
		  s--;
		}
	    }
	}
      else if(t <= 1)
	{
	  for(float i=x1; i<x2; i++)
	    {
	      //write_pixel((int)i,(int)s);
	      write_pixel((int)i,(int)s,0,rgb);
	      s += t;
	    }
	}
      else
	{
	  float f = 0;
	  for(float i=x1; i<x2; i++)
	    {
	      for(float a=0; a<(int)t; a++)
		{
		  //write_pixel((int)i,(int)s);
		  write_pixel((int)i,(int)s,0,rgb);
		  s++;
		}
	      f += t-(int)t;
	      if(f >= 1)
		{
		  //write_pixel((int)i,(int)s);
		  write_pixel((int)i,(int)s,0,rgb);
		  f = 0;
		  s++;
		}
	    }
	}
    }
}

void Viewer::write_triangle(float x1, float y1, float x2, float y2, float x3, float y3, Uint32 rgb)
{
  write_line(x1,y1,x2,y2,rgb);
  write_line(x2,y2,x3,y3,rgb);
  write_line(x3,y3,x1,y1,rgb);
}

void Viewer::clean_pixels()
{
  for(int i=0; i<width*height; i++)
    {
      pixels[i] = 0x00;
    }
}

void Viewer::graph_line()
{
  int xl = width*height/2;
  int yl = width/2;
  for(int i=0; i<width; i++)
    {
      for(int t=0; t<height; t+=20)
	{
	  pixels[width*t+i] = 0x5a;
	}
      pixels[xl +i] = 0xff;
    }
  for(int i=0; i<height; i++)
    {
      for(int t=0; t<width; t+=20)
	{
	  pixels[i*width+t] = 0x5a;
	}
      pixels[i*width+yl] = 0xff;
    }
}


void Viewer::run()
{
  int frames = 0;
  int start_time, this_time;

  HTaskPtr task_update_sgp = NULL;
  HTaskPtr task_create_pp = NULL;
  int fd_update_sgp;
  int fd_create_pp;

  start_time = get_ticks();

  SDL_Surface *bitmap = NULL;
  SDL_PixelFormat *pf;
  pf = screen->format;

  Uint32 background;
  background = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);

  pixels = new Uint32[width*height];

  Polygon *p = new Polygon;
  p->set_data("cube.xml");
  //p->set_data("cube-p.xml");

  p->viewer = this;
  //p->screen = screen;
  /*
  p->next->viewer = this;
  p->next->next->viewer = this;
  p->next->next->next->viewer = this;
  p->next->next->next->next->viewer = this;
  p->next->next->next->next->next->viewer = this;
  p->next->next->next->next->next->next->viewer = this;
  p->next->next->next->next->next->next->next->viewer = this;
  p->next->next->next->next->next->next->next->next->viewer = this;
  p->next->next->next->next->next->next->next->next->next->viewer = this;
  */

  SceneGraphPack *sgp = new SceneGraphPack;
  create_sgp(sgp,p);

  PolygonPack *pp = new PolygonPack;

  graph_line();

  float r = 0;
  float x = 0;
  float y = 0;
  float z = 0;

  // Loop until done.
  while(1)
    {
      // Destroy our GL context, etc.
      //if(quit_check() || scene->action_scene==NULL)
      if(quit_check())
	{
	  this_time = get_ticks();
	  if (this_time != start_time) 
	    {
	      cout<<((float)frames/(this_time-start_time))*1000.0<<" FPS\n";
	    }
	  SDL_FreeSurface(bitmap);
	  delete pixels;
	  p->delete_data();
	  delete p;
	  delete sgp;
	  delete pp;
	  quit();
	  break;
	}
      /////////////////////
      clean_pixels();

      this->zRow_init();
      graph_line();

      if(r > 360) r = 0;
      r+= 1.0;
      // r= 0;
      p->angle[0] = 0;
      p->angle[1] = r;
      p->angle[2] = 0;
      //p->child->angle[1] = r*2;
      //p->child->brother->angle[1] = r*3;
      //p->child->brother->child->angle[1] = r*4;
      x += 0.5;
      y += 0.5;
      z += 0.5;
      //p->xyz[0] = x;
      //p->xyz[1] = y;
      //p->xyz[2] = z;
      //p->tree_draw();


      update_sgp(sgp, sgp);
      //create_pp(pp, sgp);

      //fd_update_sgp = manager->open("UpdateSGP");
      fd_create_pp = manager->open("CreatePP");
#if 1
      //task_update_sgp = manager->create_task(fd_update_sgp,
      //sizeof(SceneGraphPack),
      //(unsigned int)sgp,
      //				     (unsigned int)sgp,
      //NULL);

      task_create_pp = manager->create_task(fd_create_pp,
					    sizeof(SceneGraphPack),
					    (unsigned int)sgp,
					    (unsigned int)pp,
					    NULL);
      //manager->set_task_depend(task_update_sgp, task_create_pp);
      //manager->spawn_task(task_update_sgp);
      manager->spawn_task(task_create_pp);

      manager->run();
#endif
      //p->draw(sgp);
      p->draw(pp);

      bitmap = SDL_CreateRGBSurfaceFrom((void *)pixels,width,height,32,width*4,0x00ff0000,0x0000ff00,0x000000ff,0);
      SDL_FillRect(screen, NULL, background);
      SDL_BlitSurface(bitmap,NULL,screen,NULL);
      SDL_UpdateRect(screen,0,0,0,0);


      /////////////////////

      //swap_buffers();
      ++frames;
    }
}

void Viewer::zRow_init() {
	int i,j;
	for(i = 0;i < 640; i++) {
		for(j = 0; j < 480; j++) {
			zRow[i][j] = 65535;
		}
	}
}