int main(int argc, char **argv) 
{ 
	setup_bind_pose();

	GFX gfx;
	gfx.Init(800,600,false,DrawScene);

	timeBeginPeriod(1); 
	glClampColorARB(GL_CLAMP_VERTEX_COLOR_ARB, GL_FALSE);get_GL_error();

	wglSwapIntervalEXT(0);

	#ifdef USE_PBUFFER
	pbuffer.Init(512,512);
	pbuffer.begin();
	gfx.InitGL(512,512);
	#endif

//	manager.load_obj ("../media/trousers.obj");
//	manager.load_obj ("../media/box2.obj");
//	manager.load_obj ("../media/can4.obj");
//	manager.load_obj ("../media/suspension.obj");
//	manager.load_obj ("../media/leg3.obj");
//	manager.load_obj ("../media/female3.obj");
//	manager.load_obj ("../media/char3.obj");
	manager.load_obj ("../media/female-legs.obj");
	

	#ifdef USE_PBUFFER
	pbuffer.end();
	#endif

	manager.print_controls();
	manager.print_materials();
    gfx.Run();
    return 0;
}
示例#2
0
//Set up variables
bool DemoInit()
{
	if(!window.Init("Render To Texture", 640, 480, 32, 24, 8, WINDOWED_SCREEN))
		return 0;											//quit if not created

	camera.Init(VECTOR3D(0.0f, 0.0f, -2.5f), 2.0f, 100.0f);

	//Set up extensions
	if(	!SetUpWGL_ARB_extensions_string())
		return false;

	SetUpEXT_texture_filter_anisotropic();
	SetUpSGIS_generate_mipmap();
		
	//Get the WGL extensions string
	const char * wglExtensions;
	wglExtensions=wglGetExtensionsStringARB(window.hDC);

	//Set up wgl extensions
	if(	!SetUpWGL_ARB_pbuffer(wglExtensions) || !SetUpWGL_ARB_pixel_format(wglExtensions) ||
		!SetUpWGL_ARB_render_texture(wglExtensions))
		return false;


	//Init the pbuffer
	int pbufferExtraIAttribs[]={WGL_BIND_TO_TEXTURE_RGBA_ARB, true,
								0};

	int pbufferFlags[]={WGL_TEXTURE_FORMAT_ARB, WGL_TEXTURE_RGBA_ARB,
						WGL_TEXTURE_TARGET_ARB, WGL_TEXTURE_2D_ARB,
						
						//request mipmap space if mipmaps are to be used
						SGIS_generate_mipmap_supported ? WGL_MIPMAP_TEXTURE_ARB : 0,
						SGIS_generate_mipmap_supported ? true : 0,

						0};

	if(!pbuffer.Init(pbufferSize, pbufferSize, 32, 24, 8, 1, pbufferExtraIAttribs, pbufferFlags))
		return false;
	

	//Create the texture object to relate to the pbuffer
	glGenTextures(1, &pbufferTexture);
	glBindTexture(GL_TEXTURE_2D, pbufferTexture);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

	//Use generated mipmaps if supported
	if(SGIS_generate_mipmap_supported)
	{
		glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, true);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
		glHint(GL_GENERATE_MIPMAP_HINT_SGIS, GL_NICEST);
		useMipmapFilter=true;
	}

	//Use maximum anisotropy if supported
	if(EXT_texture_filter_anisotropic_supported)
	{
		glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maxAnisotropy);
		currentAnisotropy=maxAnisotropy;
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, currentAnisotropy);
	}



	//Load the decal texture
	//Note: This MUST be done when the pbuffer is the current context
	pbuffer.MakeCurrent();
	
	IMAGE decalImage;
	decalImage.Load("decal.bmp");

	glGenTextures(1, &decalTexture);
	glBindTexture(GL_TEXTURE_2D, decalTexture);
	glTexImage2D(	GL_TEXTURE_2D, 0, GL_RGBA8, decalImage.width, decalImage.height,
					0, decalImage.format, GL_UNSIGNED_BYTE, decalImage.data);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);


	
	//reset timer for start
	timer.Reset();
	
	return true;
}
示例#3
0
void DemoShutdown()
{
	pbuffer.Shutdown();

	window.Shutdown();										//Shutdown window
}
示例#4
0
//draw a frame
void RenderFrame()
{
	//Draw to pbuffer
	pbuffer.MakeCurrent();
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glLoadIdentity();										//reset modelview matrix

	gluLookAt(	0.0f, 0.0f, 4.0f,
				0.0f, 0.0f, 0.0f,
				0.0f, 1.0f, 0.0f);

	//Draw scene
	if(drawTextured)
	{
		glBindTexture(GL_TEXTURE_2D, decalTexture);
		glEnable(GL_TEXTURE_2D);
		
		glPushMatrix();
		glRotatef(timer.GetTime()/20, 0.0f, 1.0f, 0.0f);

		glutSolidTeapot(0.8f);
		
		glPopMatrix();

		glDisable(GL_TEXTURE_2D);
	}
	else
	{
		glPushMatrix();
		glRotatef(timer.GetTime()/20, 0.0f, 1.0f, 0.0f);
		glRotatef(55.0f, 1.0f, 0.0f, 0.0f);
		glutWireTorus(0.3f, 1.0f, 12, 24);
		glPopMatrix();

		glPushMatrix();
		glRotatef(timer.GetTime()/20, 0.0f, 1.0f, 0.0f);
		glRotatef(-55.0f, 1.0f, 0.0f, 0.0f);
		glutWireTorus(0.3f, 1.0f, 12, 24);
		glPopMatrix();
	}


	
	//Draw to window
	window.MakeCurrent();
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	camera.SetupViewMatrix();
	glLoadMatrixf(camera.viewMatrix);


	glBindTexture(GL_TEXTURE_2D, pbufferTexture);
	//use the pbuffer as the texture
	wglBindTexImageARB(pbuffer.hBuffer, WGL_FRONT_LEFT_ARB);


	//Draw simple rectangle
	glBegin(GL_TRIANGLE_STRIP);
	{
		glTexCoord2f(0.0f, 0.0f);
		glVertex3f(-1.0f, -1.0f, 0.0f);
		glTexCoord2f(0.0f, 1.0f);
		glVertex3f(-1.0f,  1.0f, 0.0f);
		glTexCoord2f(1.0f, 0.0f);
		glVertex3f( 1.0f, -1.0f, 0.0f);
		glTexCoord2f(1.0f, 1.0f);
		glVertex3f( 1.0f,  1.0f, 0.0f);
	}
	glEnd();

	//release the pbuffer for further rendering
	wglReleaseTexImageARB(pbuffer.hBuffer, WGL_FRONT_LEFT_ARB);



	fpsCounter.Update();											//update frames per second counter
	glColor4f(1.0f, 1.0f, 0.0f, 1.0f);
	window.StartTextMode();
	window.Print(0, 28, "FPS: %.2f", fpsCounter.GetFps());			//print the fps
	glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
	window.Print(0, 48, "%dx Anisotropy", currentAnisotropy);
	glColor4f(0.0f, 1.0f, 0.0f, 1.0f);
	window.Print(0, 68, "%s", useMipmapFilter ?	"LINEAR_MIPMAP_LINEAR filtering" :
												"LINEAR filtering");
	window.EndTextMode();
	glColor4f(1.0f, 1.0f, 1.0f, 1.0f);

	if(window.isKeyPressed(VK_F1))
	{
		window.SaveScreenshot();
		window.SetKeyReleased(VK_F1);
	}

	window.SwapBuffers();									//swap buffers

	//check for any opengl errors
	window.CheckGLError();

	//quit if necessary
	if(window.isKeyPressed(VK_ESCAPE))
		PostQuitMessage(0);
}
示例#5
0
//Set up openGL
bool GLInit()
{
	//Set up for pbuffer
	pbuffer.MakeCurrent();

	//set viewport
	glViewport(0, 0, pbufferSize, pbufferSize);

	//set up projection matrix
	glMatrixMode(GL_PROJECTION);							//select projection matrix
	glLoadIdentity();										//reset
	gluPerspective(45.0f, 1.0f, 1.0f, 100.0f);
	
	//load identity modelview
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();

	//other states
	//shading
	glShadeModel(GL_SMOOTH);
	glClearColor(	pbufferBackgroundColor.r,
					pbufferBackgroundColor.g,
					pbufferBackgroundColor.b,
					pbufferBackgroundColor.a);
	glColor4f(1.0f, 1.0f, 1.0f, 1.0f);

	//depth
	glClearDepth(1.0f);
	glEnable(GL_DEPTH_TEST);
	glDepthFunc(GL_LEQUAL);

	//hints
	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);





	//Set up for window
	window.MakeCurrent();

	//set viewport
	int height;
	if (window.height==0)
		height=1;
	else
		height=window.height;
	
	glViewport(0, 0, window.width, height);					//reset viewport

	//set up projection matrix
	glMatrixMode(GL_PROJECTION);							//select projection matrix
	glLoadIdentity();										//reset
	gluPerspective(45.0f, (GLfloat)window.width/(GLfloat)height, 1.0f, 100.0f);
	
	//load identity modelview
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();

	//other states
	//shading
	glShadeModel(GL_SMOOTH);
	glClearColor(	windowBackgroundColor.r,
					windowBackgroundColor.g,
					windowBackgroundColor.b,
					windowBackgroundColor.a);
	glColor4f(1.0f, 1.0f, 1.0f, 1.0f);

	//depth
	glClearDepth(1.0f);
	glEnable(GL_DEPTH_TEST);
	glDepthFunc(GL_LEQUAL);

	//hints
	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);

	glEnable(GL_TEXTURE_2D);


	return true;
}
void DrawScene()
{
	mouse_keyboard();

	#ifdef USE_PBUFFER
	pbuffer.begin();
	#endif

	
	vec3f p ( 0,4,0 );
	vec3f d1 ( 0,0,6 );
	vec3f d2 ( GFX::mouseX*4-2 , -GFX::mouseY*8+4 , 1);
	d2.normalize();
	d2 = d2 * 6;
	vec3f normal; 
	normal.cross(d1,d2);
	normal.normalize();
	float angle = normal.angle2( vec3f (0,1,0) , d1 );
	float twist = 0;//GFX::mouseX*10-5;
	//manager.controls[0]->set_spline(p , p+d1, p+d1+d2, angle,twist);

	//static int texture = GFX::LoadTex("data/textures/flare.bmp");
	static int white   = GFX::LoadTex("../media/textures/white.bmp");

	glLoadIdentity();			// Reset The View
	glRotatef(rot.x,1,0,0);		// Move Left 1.5 Units And Into The Screen 6.0
	glRotatef(rot.y,0,1,0);		// Move Left 1.5 Units And Into The Screen 6.0
	glTranslatef(pos.x,pos.y,pos.z);		// Move Left 1.5 Units And Into The Screen 6.0
	glGetFloatv (GL_MODELVIEW_MATRIX, (GLfloat*)model_view44.m); 
	model_view_inverse44 = model_view44;
	model_view_inverse44.invert();

	matrix44 correct44 = matrix44
	(	0.5,  0,0  ,0,
		0  ,0.5,0  ,0,
		0  ,  0,0.5,0,
		0.5,0.5,0.5,1);

	bool light_change = false;
	if ( GFX::mousePressed[2] )
	{
		light_view44.m[3][0] -= (GFX::mouseDX)*50;
		light_view44.m[3][1] += (GFX::mouseDY)*50;
		light_change = true;
	}
	if ( GFX::mousePressed[1] )
	{
		light_view44.m[3][2] += (GFX::mouseDY)*50;
		light_change = true;
	}
	//if ( GFX::keyPressed[13] )//enter
	{
		glGetFloatv (GL_MODELVIEW_MATRIX, (GLfloat*)light_view44.m); 
		light_change = true;
	}
	if ( light_change )
	{
		matrix44 light_inverse44 = light_view44; 
		light_inverse44.invert();		
		light_pos_in = light_inverse44 * vector3(0,0,0);
	}

	matrix44 projection44;
	glGetFloatv (GL_PROJECTION_MATRIX, (GLfloat*)projection44.m);
	light_2_shadow =  light_view44 * projection44 * correct44;

	//static FBO fbo; 
	static bool init = true;
	static glShaderManager shader_manager;

	static int bridge_start;

	if (init)
	{
		pshader_manager = &shader_manager;

		if(0)
		for (int a=0;a<10;a++)
		{
			int i = manager.new_control_from (5);
			if( a==0) bridge_start = i;
		}
		int max_draw_buffers;
		glGetIntegerv(GL_MAX_DRAW_BUFFERS_ARB, &max_draw_buffers);
		printf("MaxDrawBuffers:%d\n",max_draw_buffers);

	//	fbo.init( 512,512 );
		
		shader_deform = shader_manager.loadfromFile(
			"shaders/deform.vert",
			"shaders/deform.frag"
			);
		
		shader_normal = shader_manager.loadfromFile(
			"shaders/normal.vert",
			"shaders/normal.frag"
			);
		
		shader_matrices = shader_manager.loadfromFile(
			"shaders/matrices.vert",
			"shaders/matrices.frag"
			);
		
		shader_matrices2 = shader_manager.loadfromFile(
			"shaders/matrices2.vert",
			"shaders/matrices2.frag"
			);
		/*
		shader_shadow = shader_manager.loadfromFile(
			"shaders/shadow.vert",
			"shaders/shadow.frag"
			);
		*/	
		const int sb_w=32,sb_h=3*num_characters,pose_h=64+1;
		
		// nbtp = normal binormal tangent pos
		static float *mem_spline_nbtpx= new float[sb_w*(sb_h+pose_h*2)*4];
		static float *mem_spline_nbtpy= new float[sb_w*(sb_h+pose_h*2)*4];
		static float *mem_spline_nbtpz= new float[sb_w*(sb_h+pose_h*2)*4];

		const int   spline_num_params = 6;
		static float mem_spline_params[sb_h*spline_num_params*4];

		for (int y=0;y<pose_h*2;y++)
		for (int x=0;x<sb_w;x++)
		{
			float pos_x = float(x) / float (sb_w);
			float pos_y = float(y) / float (pose_h-1);

			vec3f f_dx_dz_1 = displacement_map_front.get_f_fdx_fdy(pos_x,pos_y);
			vec3f f_dx_dz_2 = displacement_map_left_right.get_f_fdx_fdy(pos_x,pos_y);
			vec3f f_dx_dz_3 = displacement_map_back.get_f_fdx_fdy(pos_x,pos_y);

			if (y==pose_h-1)
			{
				f_dx_dz_1 = vec3f(1,0,0);
				f_dx_dz_2 = vec3f(1,0,0);
				f_dx_dz_3 = vec3f(1,0,0);

				if(pos_x>0.5)
				{
					f_dx_dz_1.x =  0.1+0.9*sqrt(sin((pos_x-0.4) * M_PI));
					f_dx_dz_1.y =  0.9*0.25*(cos((pos_x-0.4) * M_PI));
				}else
				{
					f_dx_dz_1.x =  0.1+0.9*sqrt(-sin((pos_x-0.6) * M_PI));
					f_dx_dz_1.y =  -0.9*0.25*(cos((pos_x-0.6) * M_PI));
				}
				//f_dx_dz_1 = vec3f(1,0,0);
				float limit = 0.4;
				/*
				if(pos_x<limit)
				{
					f_dx_dz_1.x += -cos(pos_x * 2*M_PI/limit)*0.25+0.25;
					f_dx_dz_1.y += sin(pos_x * 2*M_PI/limit)*0.25;
				}*/
				f_dx_dz_1.z =  0;

				limit = 0.4;
				/*
				if(pos_x<limit)
				{
					f_dx_dz_2.x = -cos(pos_x * 2*M_PI/limit)*0.15+1.15;
					f_dx_dz_2.z = -sin(pos_x * 2*M_PI/limit)*0.15;
					f_dx_dz_2.y =  0;
				}
				*/
				if(pos_x>0.25)
				if(pos_x<0.75)
				{
					//f_dx_dz_2.x +=-cos(((pos_x-0.25)*2) * 2*M_PI)*0.15+0.15;
					//f_dx_dz_2.z +=-sin(((pos_x-0.25)*2) * 2*M_PI)*0.15;
				}
				if(pos_x>0.25)
				if(pos_x<0.75)
				{
					//f_dx_dz_3.x +=-cos(((pos_x-0.25)*2) * 2*M_PI)*0.15+0.15;
					//f_dx_dz_3.y +=-sin(((pos_x-0.25)*2) * 2*M_PI)*0.15;
				}
				//f_dx_dz_3.x = cos(pos_x * 2*M_PI)*0.25+0.75;
				//f_dx_dz_3.y = sin(pos_x * 2*M_PI)*0.25;
				//f_dx_dz_3.z = 0;
			}
			else
			if ((x<5)||(x>sb_w-5)||(y<5)||(y>pose_h-5))
			{
				f_dx_dz_1 = vec3f(1,0,0);
				f_dx_dz_2 = vec3f(1,0,0);
				f_dx_dz_3 = vec3f(1,0,0);
			}

			if (y>=pose_h)
			{
				f_dx_dz_1 = vec3f(1,0,0);
				f_dx_dz_2 = vec3f(1,0,0);
				f_dx_dz_3 = vec3f(1,0,0);
			}
			//f_dx_dz_1 = vec3f(1,0,0);
			//f_dx_dz_2 = vec3f(1,0,0);
			//f_dx_dz_3 = vec3f(1,0,0);

			vec3f dx1 ( 1 ,-f_dx_dz_1.z ,0 );
			vec3f dz1 ( 0, -f_dx_dz_1.y ,1 );
			vec3f normal_1;normal_1.cross(dz1,dx1);

			vec3f dx2 ( 1 ,-f_dx_dz_2.z ,0 );
			vec3f dz2 ( 0, -f_dx_dz_2.y ,1 );
			vec3f normal_2;normal_2.cross(dz2,dx2);

			vec3f dx3 ( 1 ,-f_dx_dz_3.z ,0 );
			vec3f dz3 ( 0, -f_dx_dz_3.y ,1 );
			vec3f normal_3;normal_3.cross(dz3,dx3);

			int ofs = (x+(sb_h+y)*sb_w)*4;
			
			mem_spline_nbtpx[ofs+0] = normal_1.x;//normal.x;//deform.m[0][0];//*scale;
			mem_spline_nbtpx[ofs+1] = normal_1.y;//normal.y;//deform.m[1][0];//*scale;
			mem_spline_nbtpx[ofs+2] = normal_1.z;//deform.m[2][0];//normal.z;//deform.m[2][0];//*scale;
			mem_spline_nbtpx[ofs+3] = f_dx_dz_1.x;//deform.m[3][0];//f_dx_dz.x;////1;//deform.m[3][0];//*scale;

			mem_spline_nbtpy[ofs+0] = normal_2.x;//deform.m[0][1];//*scale;
			mem_spline_nbtpy[ofs+1] = normal_2.y;//deform.m[1][1];//*scale;
			mem_spline_nbtpy[ofs+2] = normal_2.z;//deform.m[2][1];//*scale;
			mem_spline_nbtpy[ofs+3] = f_dx_dz_2.x;//deform.m[3][1];//*scale;

			mem_spline_nbtpz[ofs+0] = normal_3.x;//deform.m[0][2];//*scale;
			mem_spline_nbtpz[ofs+1] = normal_3.y;//deform.m[1][2];//*scale;
			mem_spline_nbtpz[ofs+2] = normal_3.z;//deform.m[2][2];//*scale;
			mem_spline_nbtpz[ofs+3] = f_dx_dz_3.x;//deform.m[3][2];//*scale;
		}

		SplineTex tex;
		tex.num_params= spline_num_params;
		tex.width	= sb_w;
		tex.height	= sb_h;
		tex.data_nbtpx = (float*) mem_spline_nbtpx;
		tex.data_nbtpy = (float*) mem_spline_nbtpy;
		tex.data_nbtpz = (float*) mem_spline_nbtpz;
		tex.data_params= (float*) mem_spline_params;

		matrix44 mats_body	[sb_w];
		matrix44 mats_arm	[sb_w];
		matrix44 mats_elbow	[sb_w];

		setup_bind_pose( 0 , 0 );
		spline_body.bind_normal	= spline_body.bind_normal_cmp ;
		spline_arm.bind_normal	= spline_arm.bind_normal_cmp ;
		spline_elbow.bind_normal	= spline_elbow.bind_normal_cmp ;

		for (int c=0;c<num_characters;c++)
		{
			spline_body	.sample(tex,0+c*3);
			spline_arm		.sample(tex,1+c*3);
			spline_elbow	.sample(tex,2+c*3);
		}
		tex.handle_nbtpx=  GFX::NewFloat16Tex(sb_w,sb_h+pose_h*2,(char*)mem_spline_nbtpx,true);
		tex.handle_nbtpy=  GFX::NewFloat16Tex(sb_w,sb_h+pose_h*2,(char*)mem_spline_nbtpy,true);
		tex.handle_nbtpz=  GFX::NewFloat16Tex(sb_w,sb_h+pose_h*2,(char*)mem_spline_nbtpz,true);
		tex.handle_params= -1;
		spline_tex = tex;

		init = false;
	}

	static int t1  = timeGetTime();
	       int t2  = timeGetTime();
	static int fps = 0;
	static int tps = 0;

	tps += rendered_triangles;

	if( t2-t1 >= 1000 )
	{
		float ms = (t2-t1)/float(fps+1);
		printf("Fps:%d, %3.3f ms %3.2f MTps %3.2f MVps Scene:%3.2f MVerts %d Characters\r",
			fps,ms,float(tps)/1000000.0,float(tps)*3.0/1000000.0,float(rendered_triangles)*3.0/1000000.0,rendered_models); 
		//printf("Fps:%d, %3.3f ms Light: %3.3f %3.3f %3.3f r %3.3f %3.3f %3.3f\r",fps,ms,pos.x,pos.y,pos.z,rot.x,rot.y,rot.z); 
		fps = 0;
		t1 = t2;
		tps = 0;
	}
	fps++;

	renderpass = SHADOW;

	/*
	fbo.enable();
	glDrawBuffer( GL_NONE );

	glEnable (GL_POLYGON_OFFSET_FILL);
	glPolygonOffset (12, 12);

	glPushMatrix();
	glLoadMatrixf((GLfloat*)light_view44.m);
	glClearColor(0.5f, 0.5f, 0.5f, 0.0f);		// This Will Clear The Background Color To Black
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);		// Clear The Screen And The Depth Buffer
	//manager.draw();
	glPopMatrix();

	glDisable (GL_POLYGON_OFFSET_FILL);

	fbo.disable();
	*/
	//glDrawBuffer( GL_BACK );

	renderpass = NORMAL;

	light_tex = white;//texture;
	depth_tex = white;//fbo.depth_tex;

	glClearColor(1.0f, 1.0f, 1.0f, 0.0f);		// This Will Clear The Background Color To Black
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);		// Clear The Screen And The Depth Buffer

	int viewport[4];
	glGetIntegerv(GL_VIEWPORT, viewport);
	int tex_width=viewport[2];
	int tex_height=viewport[3];
	glMatrixMode(GL_MODELVIEW); glPushMatrix();	glLoadIdentity(); 
	glMatrixMode(GL_PROJECTION);glPushMatrix();	glLoadIdentity();
	gluOrtho2D(0.0,tex_width,0.0,tex_height);	
	glMatrixMode(GL_MODELVIEW); 
	glDisable(GL_CULL_FACE);
	glDisable(GL_DEPTH_TEST);
	glDepthMask(GL_FALSE);
	glBegin(GL_QUADS); 
	float r1=0.5;//0.2;
	float g1=0.5;//0.2;
	float b1=0.5;//0.6;
	float r2=1.0;
	float g2=1.0;
	float b2=1.0;
	glColor3f(r1,g1,b1);
	glVertex2f(0, 0);
	glColor3f(r1,g1,b1);
	glVertex2f(tex_width,0);
	glColor3f(r2,g2,b2);
	glVertex2f(tex_width, tex_height);
	glColor3f(r2,g2,b2);
	glVertex2f(0, tex_height);
	glEnd();
	glEnable(GL_CULL_FACE);
	glEnable(GL_DEPTH_TEST);
	glDepthMask(GL_TRUE);
	glMatrixMode(GL_PROJECTION);glPopMatrix();
	glMatrixMode(GL_MODELVIEW); glPopMatrix();
	glDrawBuffer(GL_BACK);

	static float rnd[8] ={
		vec3f::random_float(),vec3f::random_float(),
		vec3f::random_float(),vec3f::random_float(),
		vec3f::random_float(),vec3f::random_float(),
		vec3f::random_float(),vec3f::random_float()
	};

	rendered_triangles = 0;

	static int style = 0;
	if ( GFX::keyPressed['1'] ) style=0; 
	if ( GFX::keyPressed['2'] ) style=1; 

	spline_body  	.set_style(1);
	spline_arm		.set_style(1);
	spline_elbow	.set_style(style);

	spline_body  	.set_hardness(1.5);
	spline_arm		.set_hardness(1);
	spline_elbow	.set_hardness(2);

	spline_body  	.set_twist_adjust(1);
	spline_arm		.set_twist_adjust(1);
	spline_elbow	.set_twist_adjust(1);

	static float mx=0;
	static float my=0;

	mx = 0.1*mx + GFX::mouseX*0.9;
	my = 0.1*my + GFX::mouseY*0.9;

	for (int c=0;c<num_characters;c++)
	{
		float a = 4*0.5*sin(mx*4+rnd[c&7]*(float(c)*20/float(num_characters)));
		float b = 4*0.5*sin(my*4+rnd[c&7]*(float(c)*20/float(num_characters)));
		//if(c==0)
		//	setup_bind_pose( (GFX::mouseX-0.5)*3,(GFX::mouseY-0.5)*6 );
		//else
			setup_bind_pose( a , b );

		//setup_bind_pose( (GFX::mouseX-0.5)*3 , (GFX::mouseY-0.5)*3 );

		spline_body  	.set_params_to_tex(spline_tex,0+c*3);
		spline_arm		.set_params_to_tex(spline_tex,1+c*3);
		spline_elbow	.set_params_to_tex(spline_tex,2+c*3);
	}
	spline_tex.update_params();
	render_index=0;
	setup_bind_pose( 0,0 );
	manager.draw();

	vec3f lp ( light_pos_in.x,light_pos_in.y,light_pos_in.z );

	glDisable(GL_DEPTH_TEST);
	
//	setup_bind_pose( (GFX::mouseX-0.5)*3 , (GFX::mouseY-0.5)*3 );
		float a = 4*0.5*sin(mx*4+rnd[1&7]*(float(1)*20/float(num_characters)));
		float b = 4*0.5*sin(my*4+rnd[1&7]*(float(1)*20/float(num_characters)));

	setup_bind_pose( a,b );
	spline_arm.draw();
	spline_elbow.draw();
	spline_body.draw();

	//GFX::Line( spline_body.p3, spline_arm.p1, vec3f(0,1,0) );
	//GFX::Line( spline_arm.p3, spline_elbow.p1, vec3f(0,1,0) );

	glBindTexture  (GL_TEXTURE_2D, 	white );
	glColor3f(1,0,0);
	//Box( lp , vec3f(0.1,0.1,0.1) );
	glEnable(GL_DEPTH_TEST);

	vec3f p1 (0,-10+0,0);
	vec3f p2 (0,-10+5,0);
	vec3f p3 (5,-10+5,0);
	vec3f p4 (5,-10+0,0);
	vec3f p12=(p1+p2)*0.5;
	vec3f p23=(p2+p3)*0.5;
	vec3f p34=(p3+p4)*0.5;
	vec3f p41=(p4+p1)*0.5;


	#ifdef USE_PBUFFER
	pbuffer.end();
	
	glClearColor(0.5f, 0.5f, 0.5f, 0.0f);		// This Will Clear The Background Color To Black
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);		// Clear The Screen And The Depth Buffer
	glLoadIdentity();				// Reset The View
	glTranslatef(0,0,-30);
	//glRotatef( (GFX::mouseX-0.5)*100 , 1,0,0);
	glBindTexture (GL_TEXTURE_2D, 	pbuffer.pbufferTexture );
	//use the pbuffer as the texture
	wglBindTexImageARB(pbuffer.hBuffer, WGL_FRONT_LEFT_ARB);
	Box( vec3f (0,0,0) , vec3f(10,10,5) );
	wglReleaseTexImageARB(pbuffer.hBuffer, WGL_FRONT_LEFT_ARB);
	#endif

	GFX::Flip();
}