ExpandCelCanvas::ExpandCelCanvas(DocumentLocation location,
  TiledMode tiledMode, Transaction& transaction, Flags flags)
  : m_document(location.document())
  , m_sprite(location.sprite())
  , m_layer(location.layer())
  , m_cel(NULL)
  , m_celImage(NULL)
  , m_celCreated(false)
  , m_flags(flags)
  , m_srcImage(NULL)
  , m_dstImage(NULL)
  , m_closed(false)
  , m_committed(false)
  , m_transaction(transaction)
{
  create_buffers();

  if (m_layer->isImage()) {
    m_cel = m_layer->cel(location.frame());
    if (m_cel)
      m_celImage = m_cel->imageRef();
  }

  // Create a new cel
  if (m_cel == NULL) {
    m_celCreated = true;
    m_cel = new Cel(location.frame(), ImageRef(NULL));
  }

  m_origCelPos = m_cel->position();

  // Region to draw
  gfx::Rect celBounds(
    m_cel->x(),
    m_cel->y(),
    m_celImage ? m_celImage->width(): m_sprite->width(),
    m_celImage ? m_celImage->height(): m_sprite->height());

  gfx::Rect spriteBounds(0, 0,
    m_sprite->width(),
    m_sprite->height());

  if (tiledMode == TiledMode::NONE) { // Non-tiled
    m_bounds = celBounds.createUnion(spriteBounds);
  }
  else {                         // Tiled
    m_bounds = spriteBounds;
  }

  // We have to adjust the cel position to match the m_dstImage
  // position (the new m_dstImage will be used in RenderEngine to
  // draw this cel).
  m_cel->setPosition(m_bounds.x, m_bounds.y);

  if (m_celCreated) {
    getDestCanvas();
    m_cel->data()->setImage(m_dstImage);
    static_cast<LayerImage*>(m_layer)->addCel(m_cel);
  }
}
ExpandCelCanvas::ExpandCelCanvas(Context* context, TiledMode tiledMode, UndoTransaction& undo, Flags flags)
  : m_cel(NULL)
  , m_celImage(NULL)
  , m_celCreated(false)
  , m_flags(flags)
  , m_srcImage(NULL)
  , m_dstImage(NULL)
  , m_closed(false)
  , m_committed(false)
  , m_undo(undo)
{
  create_buffers();

  DocumentLocation location = context->activeLocation();
  m_document = location.document();
  m_sprite = location.sprite();
  m_layer = location.layer();

  if (m_layer->isImage()) {
    m_cel = static_cast<LayerImage*>(m_layer)->getCel(location.frame());
    if (m_cel)
      m_celImage = m_cel->image();
  }

  // If there is no Cel
  if (m_cel == NULL) {
    // Create the cel
    m_celCreated = true;
    m_cel = new Cel(location.frame(), 0);
    static_cast<LayerImage*>(m_layer)->addCel(m_cel);
  }

  m_origCelPos = m_cel->position();

  // Region to draw
  gfx::Rect celBounds(
    m_cel->x(),
    m_cel->y(),
    m_celImage ? m_celImage->width(): m_sprite->width(),
    m_celImage ? m_celImage->height(): m_sprite->height());

  gfx::Rect spriteBounds(0, 0,
    m_sprite->width(),
    m_sprite->height());

  if (tiledMode == TILED_NONE) { // Non-tiled
    m_bounds = celBounds.createUnion(spriteBounds);
  }
  else {                         // Tiled
    m_bounds = spriteBounds;
  }

  // We have to adjust the cel position to match the m_dstImage
  // position (the new m_dstImage will be used in RenderEngine to
  // draw this cel).
  m_cel->setPosition(m_bounds.x, m_bounds.y);
}
void SpriteRenderNode::render() {
	if(!hidden && (!scene->isPaused() || renderWhenPaused)) {
		bool renderSprites = scene->getAttribute(RENDER_SPRITES)->getBooleanValue();
		if(renderSprites) {
			pantheios::log(pantheios::debug, "Rendering Sprite ", HashedStringInserter(texture), " for ", GameObjectInserter(*(getOwner())));
			
			Texture* tex = CalicoAPI::getResourceManager()->getTexture(texture);
			assert(tex != NULL);
			
			if(tex != NULL) {
				if(needToRegenerateVBO) {
					generateVBO();
				}
				
				Rect2D boundsRect = getWorldRect();
				
				Transform* ownerTransform = owner->getTransform();
				Vector3 ownerPosition = *(ownerTransform->getPosition());
				Rect2D spriteBounds(Vector2(ownerPosition.X() + boundsRect.min.X(), ownerPosition.Y() + boundsRect.min.Y()), 
									Vector2(ownerPosition.X() + boundsRect.max.X(), ownerPosition.Y() + boundsRect.max.Y()));
				Rect2D cameraBounds = layer->getCamera()->getWorldBounds();
				
				// only draw if the sprite is actually on-screen
				
				// TODO - this is buggy!
//				if(spriteBounds.intersects(cameraBounds)) {
					glPushMatrix();
					glMultMatrixf(ownerTransform->ToGlWorldMatrix(flip));
					
					tex->bind();
					
					glEnableClientState(GL_TEXTURE_COORD_ARRAY);
					glEnableClientState(GL_COLOR_ARRAY);
					
					glBindBuffer(GL_ARRAY_BUFFER, vbo);
					glVertexPointer(2, GL_FLOAT, sizeof(VertexPt), 0);
					glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(VertexPt), (unsigned char*) (sizeof(GLfloat) * 2));
					glTexCoordPointer(2, GL_FLOAT, sizeof(VertexPt), (unsigned char*) (sizeof(GLfloat) * 2 + sizeof(GLubyte) * 4));
					
					glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
					
					glBindBuffer(GL_ARRAY_BUFFER, 0);
					
					glPopMatrix();
//				}
			}
		}
	}
}
ExpandCelCanvas::ExpandCelCanvas(
  Site site, Layer* layer,
  TiledMode tiledMode, Transaction& transaction, Flags flags)
  : m_document(static_cast<app::Document*>(site.document()))
  , m_sprite(site.sprite())
  , m_layer(layer)
  , m_frame(site.frame())
  , m_cel(NULL)
  , m_celImage(NULL)
  , m_celCreated(false)
  , m_flags(flags)
  , m_srcImage(NULL)
  , m_dstImage(NULL)
  , m_closed(false)
  , m_committed(false)
  , m_transaction(transaction)
  , m_canCompareSrcVsDst((m_flags & NeedsSource) == NeedsSource)
{
  ASSERT(!singleton);
  singleton = this;

  create_buffers();

  if (m_layer && m_layer->isImage()) {
    m_cel = m_layer->cel(site.frame());
    if (m_cel)
      m_celImage = m_cel->imageRef();
  }

  // Create a new cel
  if (!m_cel) {
    m_celCreated = true;
    m_cel = new Cel(site.frame(), ImageRef(NULL));
  }

  m_origCelPos = m_cel->position();

  // Region to draw
  gfx::Rect celBounds(
    m_cel->x(),
    m_cel->y(),
    m_celImage ? m_celImage->width(): m_sprite->width(),
    m_celImage ? m_celImage->height(): m_sprite->height());

  gfx::Rect spriteBounds(0, 0,
    m_sprite->width(),
    m_sprite->height());

  if (tiledMode == TiledMode::NONE) { // Non-tiled
    m_bounds = celBounds.createUnion(spriteBounds);
  }
  else {                         // Tiled
    m_bounds = spriteBounds;
  }

  // We have to adjust the cel position to match the m_dstImage
  // position (the new m_dstImage will be used in RenderEngine to
  // draw this cel).
  m_cel->setPosition(m_bounds.x, m_bounds.y);

  if (m_celCreated) {
    getDestCanvas();
    m_cel->data()->setImage(m_dstImage);

    if (m_layer && m_layer->isImage())
      static_cast<LayerImage*>(m_layer)->addCel(m_cel);
  }
}