예제 #1
0
/**
 *  Function for creating and holding of shared context.
 *  Generation and uploading of new textures over some period with sleep time.
 */
void AsyncFetcher::run()
{
    EQASSERT( !_sharedContextWindow );
    _sharedContextWindow = initSharedContextWindow( _wnd );
    _outQueue.push( TextureId( )); // unlock pipe thread
    if( !_sharedContextWindow )
        return;

    _objectManager = new ObjectManager( glewGetContext( ));
    EQINFO << "async fetcher initialized: " << _wnd << std::endl;

    int i = 0;
    bool running = true;
    co::base::sleep( 1000 ); // imitate loading of the first texture
    while( running )
    {
        // generate new texture
        eq::util::Texture* tx = _objectManager->newEqTexture( ++i,
                                                              GL_TEXTURE_2D );
        tx->init( GL_RGBA8, 64, 64 );

        int j = 0;
        co::base::RNG rng;
        for( int y = 0; y < 64; ++y )
        {
            for( int x = 0; x < 64; ++x )
            {
                const GLbyte rnd = rng.get< uint8_t >() % 127;
                const GLbyte val = (x / 8) % 2 == (y / 8) % 2 ? rnd : 0;
                _tmpTexture[ j++ ] = val;
                _tmpTexture[ j++ ] = val;
                _tmpTexture[ j++ ] = val;
                _tmpTexture[ j++ ] = val;
            }
        }
        tx->upload( 64, 64, _tmpTexture );
        EQ_GL_CALL( glFinish( ));

        // add new texture to the pool
        _outQueue.push( TextureId( tx->getName( ), i ));

        // imitate hard work of loading something else
        co::base::sleep( rng.get< uint32_t >() % 5000u );

        // clean unused textures
        int keyToDelete = 0;
        while( _inQueue.tryPop( keyToDelete ))
        {
            if( keyToDelete )
            {
                EQWARN << "Deleting eq texture " << keyToDelete << std::endl;
                _objectManager->deleteEqTexture( keyToDelete );
            }
            else
                running = false;
        }
    }
    deleteSharedContextWindow( _wnd, &_sharedContextWindow, &_objectManager );
}
예제 #2
0
void CDeco::CreateLightStrip (float x, float z, float width, float depth, float height, GLrgba color)
{

  GLvertex   p;
  quad_strip qs1;
  float      u, v;
  
  qs1.index_list.push_back(0);
  qs1.index_list.push_back(1);
  qs1.index_list.push_back(3);
  qs1.index_list.push_back(2);
  _color = color;
  _use_alpha = true;
  _center = glVector (x + width / 2, height, z + depth / 2);
  if (width < depth) {
    u = 1.0f;
    v = (float)((int)(depth / width));
  } else {
    v = 1.0f;
    u = (float)((int)(width / depth));
  }
  _texture = TextureId (TEXTURE_LIGHT);
  p.position = glVector (x, height, z);  p.uv = glVector (0.0f, 0.0f);
  _mesh->VertexAdd (p);
  p.position = glVector (x, height, z + depth);  p.uv = glVector (0.0f, v);
  _mesh->VertexAdd (p);
  p.position = glVector (x + width, height, z + depth);  p.uv = glVector (u, v);
  _mesh->VertexAdd (p);
  p.position = glVector (x + width, height, z);  p.uv = glVector (u, 0.0f);
  _mesh->VertexAdd (p);
  _mesh->QuadStripAdd (qs1);
  _mesh->Compile ();

}
예제 #3
0
void LightRender ()
{

    CLight*     l;

    if (!EntityReady ())
        return;
    if (!angles_done) {
        for (int size = 0; size < MAX_SIZE; size++) {
            for (int i = 0 ; i < 360; i++) {
                angles[size][i].x = cosf ((float)i * DEGREES_TO_RADIANS) * ((float)size + 0.5f);
                angles[size][i].y = sinf ((float)i * DEGREES_TO_RADIANS) * ((float)size + 0.5f);
            }
        }
    }
    glDepthMask (false);
    glEnable (GL_BLEND);
    glDisable (GL_CULL_FACE);
    glBlendFunc (GL_ONE, GL_ONE);
    glBindTexture(GL_TEXTURE_2D, TextureId (TEXTURE_LIGHT));
    glDisable (GL_CULL_FACE);
    glBegin (GL_QUADS);
    for (l = head; l; l = l->_next)
        l->Render ();
    glEnd ();
    glDepthMask (true);

}
예제 #4
0
void CDeco::CreateRadioTower (GLvector pos, float height)
{

  CLight*   l;
  float     offset;
  GLvertex  v;
  fan       f;

  for(int i=0; i<6; i++)
    f.index_list.push_back(i);

  offset = height / 15.0f;
  _center = pos;
  _use_alpha = true;
  //Radio tower
  v.position = glVector (_center.x, _center.y + height, _center.z);  v.uv = glVector (0,1);
  _mesh->VertexAdd (v);
  v.position = glVector (_center.x - offset, _center.y, _center.z - offset);  v.uv = glVector (1,0);
  _mesh->VertexAdd (v);
  v.position = glVector (_center.x + offset, _center.y, _center.z - offset);  v.uv = glVector (0,0);
  _mesh->VertexAdd (v);
  v.position = glVector (_center.x + offset, _center.y, _center.z + offset);  v.uv = glVector (1,0);
  _mesh->VertexAdd (v);
  v.position = glVector (_center.x - offset, _center.y, _center.z + offset);  v.uv = glVector (0,0);
  _mesh->VertexAdd (v);
  v.position = glVector (_center.x - offset, _center.y, _center.z - offset);  v.uv = glVector (1,0);
  _mesh->VertexAdd (v);
  _mesh->FanAdd (f);
  l = new CLight (glVector (_center.x, _center.y + height + 1.0f, _center.z), glRgba (255,192,160), 1);
  l->Blink ();
  _texture = TextureId (TEXTURE_LATTICE);

}
예제 #5
0
파일: Texture.cpp 프로젝트: 96fps/pixelcity
unsigned TextureRandomBuilding (int index)
{

  index = abs (index) % BUILDING_COUNT;
  return TextureId (TEXTURE_BUILDING1 + index);

}
예제 #6
0
void CSky::Render ()
{

  GLvector    angle, position;

  if (!TextureReady ())
    return;
  glDepthMask (false);
  glPushAttrib (GL_POLYGON_BIT | GL_FOG_BIT);
  glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
  glDisable (GL_CULL_FACE);
  glDisable (GL_FOG);
  glPushMatrix ();
  glLoadIdentity();
  angle = CameraAngle ();
  position = CameraPosition ();
  glRotatef (angle.x, 1.0f, 0.0f, 0.0f);
  glRotatef (angle.y, 0.0f, 1.0f, 0.0f);
  glRotatef (angle.z, 0.0f, 0.0f, 1.0f);
  glTranslatef (0.0f, -position.y / 100.0f, 0.0f);
  glEnable (GL_TEXTURE_2D);
  glBindTexture(GL_TEXTURE_2D, TextureId (TEXTURE_SKY));
  glCallList (m_list);
  glPopMatrix ();
  glPopAttrib ();
  glDepthMask (true);
  glEnable (GL_COLOR_MATERIAL);


}
예제 #7
0
/**
 *  Function for creating and holding of shared context.
 *  Generation and uploading of new textures over some period with sleep time.
 */
void AsyncFetcher::run()
{
    LBASSERT( _sharedWindow );
    if( !_sharedWindow )
        return;

    _sharedWindow->makeCurrent();
    eq::util::ObjectManager objects( glewGetContext( ));
    lunchbox::Bufferb textureData( 64*64*4 );
    LBINFO << "async fetcher initialized" << std::endl;

    bool running = true;
    lunchbox::sleep( 1000 ); // imitate loading of the first texture
    for( uint8_t* i = 0; running; ++i )
    {
        // generate new texture
        eq::util::Texture* tx = objects.newEqTexture( i, GL_TEXTURE_2D );
        tx->init( GL_RGBA8, 64, 64 );

        int j = 0;
        lunchbox::RNG rng;
        for( int y = 0; y < 64; ++y )
        {
            for( int x = 0; x < 64; ++x )
            {
                const GLbyte rnd = rng.get< uint8_t >() % 127;
                const GLbyte val = (x / 8) % 2 == (y / 8) % 2 ? rnd : 0;
                textureData[ j++ ] = val;
                textureData[ j++ ] = val;
                textureData[ j++ ] = val;
                textureData[ j++ ] = val;
            }
        }
        tx->upload( 64, 64, textureData.getData( ));
        EQ_GL_CALL( glFinish( ));

        // add new texture to the pool
        _outQueue.push( TextureId( tx->getName(), i ));

        // imitate hard work of loading something else
        lunchbox::sleep( rng.get< uint32_t >() % 5000u );

        // clean unused textures
        const void* keyToDelete = 0;
        while( _inQueue.tryPop( keyToDelete ))
        {
            if( keyToDelete )
            {
                LBWARN << "Deleting eq texture " << keyToDelete << std::endl;
                objects.deleteEqTexture( keyToDelete );
            }
            else
                running = false;
        }
    }
    objects.deleteAll();
}
예제 #8
0
void CDeco::CreateLightTrim (GLvector* chain, int count, float height, int seed, GLrgba color)
{

    GLvertex   p;
    GLvector   to;
    GLvector   out;
    int        i;
    int        index;
    int        prev, next;
    float      u, v1, v2;
    float      row;
    quad_strip qs;

    _color = color;
    _center = glVector (0.0f, 0.0f, 0.0f);
    qs.index_list.reserve(count * 2 + 2);
    for (i = 0; i < count; i++)
        _center += chain[i];
    _center /= (float)count;
    row = (float)(seed % TRIM_ROWS);
    v1 = row * TRIM_SIZE;
    v2 = (row + 1.0f) * TRIM_SIZE;
    index = 0;
    u = 0.0f;
    for (i = 0; i < count + 1; i++) {
        if (i)
            u += glVectorLength (chain[i % count] - p.position) * 0.1f;
        //Add the bottom point
        prev = i - 1;
        if (prev < 0)
            prev = count + prev;
        next = (i + 1) % count;
        to = glVectorNormalize (chain[next] - chain[prev]);
        out = glVectorCrossProduct (glVector (0.0f, 1.0f, 0.0f), to) * LOGO_OFFSET;
        p.position = chain[i % count] + out;
        p.uv = glVector (u, v2);
        _mesh->VertexAdd (p);
        qs.index_list.push_back(index++);
        //Top point
        p.position.y += height;
        p.uv = glVector (u, v1);
        _mesh->VertexAdd (p);
        qs.index_list.push_back(index++);
    }
    _mesh->QuadStripAdd (qs);
    _texture = TextureId (TEXTURE_TRIM);
    _mesh->Compile ();

}
예제 #9
0
void CDeco::CreateLogo (GLvector2 start, GLvector2 end, float bottom, int seed, GLrgba color)
{

    GLvertex   p;
    quad_strip qs;
    float      u1, u2, v1, v2;
    float      top;
    float      height, length;
    GLvector2  center2d;
    GLvector   to;
    GLvector   out;
    int        logo_index;

    qs.index_list.push_back(0);
    qs.index_list.push_back(1);
    qs.index_list.push_back(3);
    qs.index_list.push_back(2);

    _use_alpha = true;
    _color = color;
    logo_index = seed % LOGO_ROWS;
    to = glVector (start.x, 0.0f, start.y) - glVector (end.x, 0.0f, end.y);
    to = glVectorNormalize (to);
    out = glVectorCrossProduct (glVector (0.0f, 1.0f, 0.0f), to) * LOGO_OFFSET;
    center2d = (start + end) / 2;
    _center = glVector (center2d.x, bottom, center2d.y);
    length = glVectorLength (start - end);
    height = (length / 8.0f) * 1.5f;
    top = bottom + height;
    u1 = 0.0f;
    u2 = 0.5f;//We actually only use the left half of the texture
    v1 = (float)logo_index / LOGO_ROWS;
    v2 = v1 + (1.0f / LOGO_ROWS);
    p.position = glVector (start.x, bottom, start.y) + out;
    p.uv = glVector (u1,v1);
    _mesh->VertexAdd (p);
    p.position = glVector (end.x, bottom, end.y) + out;
    p.uv = glVector (u2, v1);
    _mesh->VertexAdd (p);
    p.position = glVector (end.x, top, end.y) + out;
    p.uv = glVector (u2, v2);
    _mesh->VertexAdd (p);
    p.position = glVector (start.x, top, start.y) + out;
    p.uv = glVector (u1, v2);
    _mesh->VertexAdd (p);
    _mesh->QuadStripAdd (qs);
    _texture = TextureId (TEXTURE_LOGOS);

}
예제 #10
0
파일: Car.cpp 프로젝트: elcerdo/pixelcity
void CarRender ()
{

  CCar*       c;

  if (!angles_done) {
    for (int i = 0 ;i < 360; i++) {
      angles[i].x = cosf ((float)i * DEGREES_TO_RADIANS) * CAR_SIZE;
      angles[i].y = sinf ((float)i * DEGREES_TO_RADIANS) * CAR_SIZE;
    }
  }
  glDepthMask (false);
  glEnable (GL_BLEND);
  glDisable (GL_CULL_FACE);
  glBlendFunc (GL_ONE, GL_ONE);
  glBindTexture (GL_TEXTURE_2D, 0);
  glBindTexture(GL_TEXTURE_2D, TextureId (TEXTURE_HEADLIGHT));
  for (c = head; c; c = c->m_next)
    c->Render ();
  glDepthMask (true);

}
예제 #11
0
void CTexture::DrawSky()
{
	GLrgba color;
	float grey;
	float scale, inv_scale;
	int i, x, y;
	int width, height;
	int offset;
	int width_adjust;
	int height_adjust;

	color = WorldBloomColor();
	grey = (color.red + color.green + color.blue) / 3.0f;
	//desaturate, slightly dim
	color = (color + glRgba(grey) * 2.0f) / 15.0f;
	glDisable(GL_BLEND);
	glBegin(GL_QUAD_STRIP);
	glColor3f(0, 0, 0);
	glVertex2i(0, _half);
	glVertex2i(_size, _half);
	glColor3fv(&color.red);
	glVertex2i(0, _size - 2);
	glVertex2i(_size, _size - 2);
	glEnd();
	//Draw a bunch of little faux-buildings on the horizon.
	for (i = 0; i < _size; i += 5)
		drawrect(i, _size - RandomVal(8) - RandomVal(8) - RandomVal(8), i + RandomVal(9), _size, glRgba(0.0f));
	//Draw the clouds
	for (i = _size - 30; i > 5; i -= 2)
	{
		x = RandomVal(_size);
		y = i;

		scale = 1.0f - ((float)y / (float)_size);
		width = RandomVal(_half / 2) + (int)((float)_half * scale) / 2;
		scale = 1.0f - (float)y / (float)_size;
		height = (int)((float)(width) * scale);
		height = MAX(height, 4);

		glEnable(GL_BLEND);
		glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
		glDisable(GL_CULL_FACE);
		glEnable(GL_TEXTURE_2D);
		glBindTexture(GL_TEXTURE_2D, TextureId(TEXTURE_SOFT_CIRCLE));
		glDepthMask(false);
		glBegin(GL_QUADS);
		for (offset = -_size; offset <= _size; offset += _size)
		{
			for (scale = 1.0f; scale > 0.0f; scale -= 0.25f)
			{
				inv_scale = 1.0f - (scale);
				if (scale < 0.4f)
					color = WorldBloomColor() * 0.1f;
				else
					color = glRgba(0.0f);
				color.alpha = 0.2f;
				glColor4fv(&color.red);
				width_adjust = (int)((float)width / 2.0f + (int)(inv_scale * ((float)width / 2.0f)));
				height_adjust = height + (int)(scale * (float)height * 0.99f);
				glTexCoord2f(0, 0);
				glVertex2i(offset + x - width_adjust, y + height - height_adjust);
				glTexCoord2f(0, 1);
				glVertex2i(offset + x - width_adjust, y + height);
				glTexCoord2f(1, 1);
				glVertex2i(offset + x + width_adjust, y + height);
				glTexCoord2f(1, 0);
				glVertex2i(offset + x + width_adjust, y + height - height_adjust);
			}
		}
	}
	glEnd();
}
예제 #12
0
파일: Render.cpp 프로젝트: 96fps/pixelcity
static void do_effects (int type)
{

  float           hue1, hue2, hue3, hue4;
  GLrgba          color;
  float           fade;
  int             radius;
  int             x, y;
  int             i;
  int             bloom_radius;
  int             bloom_step;
  
  fade = WorldFade ();
  bloom_radius = 15;
  bloom_step = bloom_radius / 3;
  if (!TextureReady ())
    return;
  //Now change projection modes so we can render full-screen effects
  glMatrixMode (GL_PROJECTION);
  glPushMatrix ();
  glLoadIdentity ();
  glOrtho (0, render_width, render_height, 0, 0.1f, 2048);
	glMatrixMode (GL_MODELVIEW);
  glPushMatrix ();
  glLoadIdentity();
  glTranslatef(0, 0, -1.0f);				
  glDisable (GL_CULL_FACE);
  glDisable (GL_FOG);
  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
  //Render full-screen effects
  glBlendFunc (GL_ONE, GL_ONE);
  glEnable (GL_TEXTURE_2D);
  glDisable(GL_DEPTH_TEST);
  glDepthMask (false);
  glBindTexture(GL_TEXTURE_2D, TextureId (TEXTURE_BLOOM));
  switch (type) {
  case EFFECT_DEBUG:
    glBindTexture(GL_TEXTURE_2D, TextureId (TEXTURE_LOGOS));
    glDisable (GL_BLEND);
    glBegin (GL_QUADS);
    glColor3f (1, 1, 1);
    glTexCoord2f (0, 0);  glVertex2i (0, render_height / 4);
    glTexCoord2f (0, 1);  glVertex2i (0, 0);
    glTexCoord2f (1, 1);  glVertex2i (render_width / 4, 0);
    glTexCoord2f (1, 0);  glVertex2i (render_width / 4, render_height / 4);

    glTexCoord2f (0, 0);  glVertex2i (0, 512);
    glTexCoord2f (0, 1);  glVertex2i (0, 0);
    glTexCoord2f (1, 1);  glVertex2i (512, 0);
    glTexCoord2f (1, 0);  glVertex2i (512, 512);
    glEnd ();
    break;
  case EFFECT_BLOOM_RADIAL:
    //Psychedelic bloom
    glEnable (GL_BLEND);
    glBegin (GL_QUADS);
    color = WorldBloomColor () * BLOOM_SCALING * 2;
    glColor3fv (&color.red);
    for (i = 0; i <= 100; i+=10) {
      glTexCoord2f (0, 0);  glVertex2i (-i, i + render_height);
      glTexCoord2f (0, 1);  glVertex2i (-i, -i);
      glTexCoord2f (1, 1);  glVertex2i (i + render_width, -i);
      glTexCoord2f (1, 0);  glVertex2i (i + render_width, i + render_height);
    }
    glEnd ();
    break;
  case EFFECT_COLOR_CYCLE:
    //Oooh. Pretty colors.  Tint the scene according to screenspace.
    hue1 = (float)(GetTickCount () % COLOR_CYCLE_TIME) / COLOR_CYCLE_TIME;
    hue2 = (float)((GetTickCount () + COLOR_CYCLE) % COLOR_CYCLE_TIME) / COLOR_CYCLE_TIME;
    hue3 = (float)((GetTickCount () + COLOR_CYCLE * 2) % COLOR_CYCLE_TIME) / COLOR_CYCLE_TIME;
    hue4 = (float)((GetTickCount () + COLOR_CYCLE * 3) % COLOR_CYCLE_TIME) / COLOR_CYCLE_TIME;
    glBindTexture(GL_TEXTURE_2D, 0);
    glEnable (GL_BLEND);
    glBlendFunc (GL_ONE, GL_ONE);
    glBlendFunc (GL_DST_COLOR, GL_SRC_COLOR);
    glBegin (GL_QUADS);
    color = glRgbaFromHsl (hue1, 1.0f, 0.6f);
    glColor3fv (&color.red);
    glTexCoord2f (0, 0);  glVertex2i (0, render_height);
    color = glRgbaFromHsl (hue2, 1.0f, 0.6f);
    glColor3fv (&color.red);
    glTexCoord2f (0, 1);  glVertex2i (0, 0);
    color = glRgbaFromHsl (hue3, 1.0f, 0.6f);
    glColor3fv (&color.red);
    glTexCoord2f (1, 1);  glVertex2i (render_width, 0);
    color = glRgbaFromHsl (hue4, 1.0f, 0.6f);
    glColor3fv (&color.red);
    glTexCoord2f (1, 0);  glVertex2i (render_width, render_height);
    glEnd ();
    break;
  case EFFECT_BLOOM:
    //Simple bloom effect
    glBegin (GL_QUADS);
    color = WorldBloomColor () * BLOOM_SCALING;
    glColor3fv (&color.red);
    for (x = -bloom_radius; x <= bloom_radius; x += bloom_step) {
      for (y = -bloom_radius; y <= bloom_radius; y += bloom_step) {
        if (abs (x) == abs (y) && x)
          continue;
        glTexCoord2f (0, 0);  glVertex2i (x, y + render_height);
        glTexCoord2f (0, 1);  glVertex2i (x, y);
        glTexCoord2f (1, 1);  glVertex2i (x + render_width, y);
        glTexCoord2f (1, 0);  glVertex2i (x + render_width, y + render_height);
      }
    }
    glEnd ();
    break;
  case EFFECT_DEBUG_OVERBLOOM:
    //This will punish that uppity GPU. Good for testing low frame rate behavior.
    glBegin (GL_QUADS);
    color = WorldBloomColor () * 0.01f;
    glColor3fv (&color.red);
    for (x = -50; x <= 50; x+=5) {
      for (y = -50; y <= 50; y+=5) {
        glTexCoord2f (0, 0);  glVertex2i (x, y + render_height);
        glTexCoord2f (0, 1);  glVertex2i (x, y);
        glTexCoord2f (1, 1);  glVertex2i (x + render_width, y);
        glTexCoord2f (1, 0);  glVertex2i (x + render_width, y + render_height);
      }
    }
    glEnd ();
    break;
  }
  //Do the fade to / from darkness used to hide scene transitions
  if (LOADING_SCREEN) {
    if (fade > 0.0f) {
      glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
      glEnable (GL_BLEND);
      glDisable (GL_TEXTURE_2D);
      glColor4f (0, 0, 0, fade);
      glBegin (GL_QUADS);
      glVertex2i (0, 0);
      glVertex2i (0, render_height);
      glVertex2i (render_width, render_height);
      glVertex2i (render_width, 0);
      glEnd ();
    }
    if (TextureReady () && !EntityReady () && fade != 0.0f) {
      radius = render_width / 16;
      do_progress ((float)render_width / 2, (float)render_height / 2, (float)radius, fade, EntityProgress ());
      RenderPrint (render_width / 2 - LOGO_PIXELS, render_height / 2 + LOGO_PIXELS, 0, glRgba (0.5f), "%1.2f%%", EntityProgress () * 100.0f);
      RenderPrint (1, "%s v%d.%d.%03d", APP_TITLE, VERSION_MAJOR, VERSION_MINOR, VERSION_REVISION);
    }
  }
  glPopMatrix ();
  glMatrixMode (GL_PROJECTION);
  glPopMatrix ();
  glMatrixMode (GL_MODELVIEW);
  glEnable(GL_DEPTH_TEST);

}
예제 #13
0
PostShaderStage::RenderPassData::RenderPassData(const std::string& VertexProgram,
                                                const std::string& FragmentProgram,
                                                bool isLastPass,
                                                UInt32 Index,
                                                Int32 iPixelWidth,
                                                Int32 iPixelHeight,
                                                PostShaderStageData *StageData,
                                                const Vec2f& FBOSize,
                                                TextureObjChunk* const SceneColorTex,
                                                TextureObjChunk* const SceneDepthTex,
                                                const RenderPassVector& Passes,
                                                FrameBufferObject* const SceneFBO) : 
                                                    _IsLassPass(isLastPass),
                                                    _Index(Index),
                                                    _FBOSize(FBOSize)
{
    //If this pass is not the last
    if(!_IsLassPass)
    {
        _FBO = FrameBufferObject::createLocal();

        _OutputTexture                   = TextureObjChunk::createLocal();
        TextureEnvChunkUnrecPtr pTexEnv  = TextureEnvChunk::createLocal();
        ImageUnrecPtr           pImg     = Image          ::createLocal();
        
        pImg->set(Image::OSG_RGB_PF, 
                  static_cast<Real32>(iPixelWidth)  * _FBOSize.x() , 
                  static_cast<Real32>(iPixelHeight) * _FBOSize.y(),
                  1,
                  1,
                  1,
                  0.0,
                  0,
                  Image::OSG_UINT8_IMAGEDATA,
                  false);
        
        _OutputTexture   ->setImage         (pImg             ); 
        _OutputTexture   ->setMinFilter     (GL_LINEAR        );
        _OutputTexture   ->setMagFilter     (GL_LINEAR        );
        _OutputTexture   ->setWrapS         (GL_CLAMP_TO_EDGE );
        _OutputTexture   ->setWrapT         (GL_CLAMP_TO_EDGE );
        _OutputTexture   ->setInternalFormat(GL_RGB           );

        pTexEnv->setEnvMode       (GL_REPLACE       );
        
        TextureBufferUnrecPtr pTexBuffer   = TextureBuffer::createLocal();
        
        pTexBuffer->setTexture(_OutputTexture);
        
        _FBO->setSize(static_cast<Real32>(iPixelWidth)  * _FBOSize.x(),
                      static_cast<Real32>(iPixelHeight) * _FBOSize.y());
        _FBO->setColorAttachment(pTexBuffer, 0);
        _FBO->editMFDrawBuffers()->push_back(GL_COLOR_ATTACHMENT0_EXT);

        StageData->pushToRenderTargets(_FBO);
        OSG_ASSERT(StageData->getMFRenderTargets()->size() == _Index+1);
    }
    else
    {
        _FBO = SceneFBO;
    }
    //Update the flags on what uniforms are present
    _ShaderHasSceneColorTex = ((FragmentProgram.find(PostShaderStage::ShaderSceneColorTexName) != std::string::npos) ||
                               (VertexProgram.find(PostShaderStage::ShaderSceneColorTexName) != std::string::npos));

    _ShaderHasSceneDepthTex = ((FragmentProgram.find(PostShaderStage::ShaderSceneDepthTexName) != std::string::npos) ||
                               (VertexProgram.find(PostShaderStage::ShaderSceneDepthTexName) != std::string::npos));

    _ShaderHasFBOWidth = ((FragmentProgram.find(PostShaderStage::ShaderFBOWidthName) != std::string::npos) ||
                          (VertexProgram.find(PostShaderStage::ShaderFBOWidthName) != std::string::npos));

    _ShaderHasFBOHeight = ((FragmentProgram.find(PostShaderStage::ShaderFBOHeightName) != std::string::npos) ||
                          (VertexProgram.find(PostShaderStage::ShaderFBOHeightName) != std::string::npos));

    _ShaderHasCameraNear = ((FragmentProgram.find(PostShaderStage::ShaderCameraNearName) != std::string::npos) ||
                          (VertexProgram.find(PostShaderStage::ShaderCameraNearName) != std::string::npos));

    _ShaderHasCameraFar = ((FragmentProgram.find(PostShaderStage::ShaderCameraFarName) != std::string::npos) ||
                          (VertexProgram.find(PostShaderStage::ShaderCameraFarName) != std::string::npos));

    //Create the material used by this pass
    ChunkMaterialUnrecPtr    pPostShaderMat  = ChunkMaterial  ::createLocal();

    UInt16 TextureId(0);

    _Shader = SimpleSHLChunk::createLocal();

    TextureEnvChunkUnrecPtr pGenericTexEnv  = TextureEnvChunk::createLocal();
    pGenericTexEnv->setEnvMode(GL_REPLACE);

    //Scene Color Texture
    if(_ShaderHasSceneColorTex)
    {
        pPostShaderMat->addChunk(SceneColorTex,       TextureId);
        pPostShaderMat->addChunk(pGenericTexEnv,  TextureId);
        _Shader->addUniformVariable(PostShaderStage::ShaderSceneColorTexName.c_str(), TextureId);
        ++TextureId;
    }
    //Scene Depth Texture
    if(_ShaderHasSceneDepthTex)
    {
        pPostShaderMat->addChunk(SceneDepthTex, TextureId);
        pPostShaderMat->addChunk(pGenericTexEnv, TextureId);
        _Shader->addUniformVariable(PostShaderStage::ShaderSceneDepthTexName.c_str(), TextureId);
        ++TextureId;
    }
    _HeightRefs.clear();
    _WidthRefs.clear();
    //Preceding passes variables
    std::string VariableName;
    for(RenderPassVector::const_iterator PassItor(Passes.begin()) ;
        PassItor != Passes.end() ;
        ++PassItor)
    {
        VariableName = (*PassItor)->getOutputTextureName();
        if((FragmentProgram.find(VariableName) != std::string::npos) ||
           (VertexProgram.find(VariableName) != std::string::npos))
        {
            pPostShaderMat->addChunk((*PassItor)->getOutputTexture(), TextureId);
            pPostShaderMat->addChunk(pGenericTexEnv, TextureId);
            _Shader->addUniformVariable(VariableName.c_str(), TextureId);
            ++TextureId;
        }

        VariableName = (*PassItor)->getWidthName();
        if((FragmentProgram.find(VariableName) != std::string::npos) ||
           (VertexProgram.find(VariableName) != std::string::npos))
        {
            _Shader->addUniformVariable<Real32>(VariableName.c_str(),
                                        (*PassItor)->getOutputTexture()->getImage()->getWidth());
            _WidthRefs.push_back((*PassItor)->getIndex());
        }

        VariableName = (*PassItor)->getHeightName();
        if((FragmentProgram.find(VariableName) != std::string::npos) ||
           (VertexProgram.find(VariableName) != std::string::npos))
        {
            _Shader->addUniformVariable<Real32>(VariableName.c_str(),
                                        (*PassItor)->getOutputTexture()->getImage()->getHeight());
            _HeightRefs.push_back((*PassItor)->getIndex());
        }
    }

    MaterialChunkUnrecPtr pMatChunk = MaterialChunk::createLocal();
    pMatChunk->setLit(false);
    pPostShaderMat->addChunk(pMatChunk);

    _Shader->setVertexProgram(VertexProgram);
    _Shader->setFragmentProgram(FragmentProgram);
    
    //Add the uniform parameters
    _Shader->addUniformVariable(ShaderFBOWidthName.c_str(),   0.0f);
    _Shader->addUniformVariable(ShaderFBOHeightName.c_str(),  0.0f);
    _Shader->addUniformVariable(ShaderCameraNearName.c_str(), 0.0f);
    _Shader->addUniformVariable(ShaderCameraFarName.c_str(),  1.0f);
    
    pPostShaderMat->addChunk(_Shader, 0);
    
    StageData->pushToShaderMaterials(pPostShaderMat);
    OSG_ASSERT(StageData->getMFShaderMaterials()->size() == _Index+1);
}