void Window_Base::DrawGauge(Game_Battler* actor, int cx, int cy) {
	FileRequestAsync* request = AsyncHandler::RequestFile("System2", Data::system.system2_name);
	if (!request->IsReady()) {
		// Gauge refreshed each frame, so we can wait via polling
		request->Start();
		return;
	}

	BitmapRef system2 = Cache::System2(Data::system.system2_name);

	bool full = actor->IsGaugeFull();
	int gauge_w = actor->GetGauge() / 4;

	// Which gauge (0 - 2)
	int gauge_y = 32 + 2 * 16;

	// Three components of the gauge
	Rect gauge_left(0, gauge_y, 16, 16);
	Rect gauge_center(16, gauge_y, 16, 16);
	Rect gauge_right(32, gauge_y, 16, 16);

	// Full or not full bar
	Rect gauge_bar(full ? 64 : 48, gauge_y, 16, 16);

	Rect dst_rect(cx + 16, cy, 25, 16);
	Rect bar_rect(cx + 16, cy, gauge_w, 16);

	contents->Blit(cx + 0, cy, *system2, gauge_left, 255);
	contents->Blit(cx + 16 + 25, cy, *system2, gauge_right, 255);

	contents->StretchBlit(dst_rect, *system2, gauge_center, 255);
	contents->StretchBlit(bar_rect, *system2, gauge_bar, 255);
}
Exemplo n.º 2
0
/* ================================================================
   コピー。
   ソース画像が透明色を持っていない場合はmemory-to-memoryコピー
   そうでない場合は1pixelづつコピー
================================================================ */
void VnImage::Copy(const VnImage& img, const VnRect& srcRect, int dx, int dy)
{
  // 範囲内のチェック
  VnRect src_rect(0, 0, img.Width(), img.Height());
  src_rect &= srcRect;
  
  VnRect dst_rect(0, 0, Width(), Height());
  dst_rect &= VnRect(dx, dy, src_rect.width, src_rect.height);

  if (GetAlpha(img.mTransColor) == 0xff) {
    // 不透明画像をコピー
    for(int y = 0; y < dst_rect.height; ++y) {
      memcpy(GetPixelBuf(dst_rect.x, dst_rect.y + y), img.GetPixelBuf(src_rect.x, src_rect.y + y), dst_rect.width * 4);
    }
  } else {
    const u_int32_t trans_color = ToMachineColor(img.mTransColor & 0xffffff00);

    // 透明色を考慮したコピー
    for(int y = 0; y < dst_rect.height; ++y) {
      const u_int32_t* src = img.GetPixelBuf(src_rect.x, src_rect.y + y);
      u_int32_t* dst       = GetPixelBuf(dst_rect.x, dst_rect.y + y);
      for(int x = 0; x < dst_rect.width; ++x, ++dst, ++src) {
        // ソースが透明色でない場合に書き込む
        // リトルエンディアン限定(:TODO:)
        if (trans_color != (*src & 0x00ffffff)) {
          *dst = *src;
        }
      }
    }
  } // end of if (GetAlpha ...)

//   cerr << "VnImage::Copy " << t.GetPassed() << "(s)" << endl;

}
Exemplo n.º 3
0
void Plane::Draw(int /* z_order */) {
    if (!visible || !bitmap) return;

    Rect dst_rect(0, 0, DisplayUi->GetWidth(), DisplayUi->GetHeight());

    bitmap_screen->BlitScreenTiled(bitmap->GetRect(), dst_rect, ox, oy);
}
Exemplo n.º 4
0
void ViewportSprite::_notification(int p_what) {

	switch(p_what) {

		case NOTIFICATION_ENTER_TREE: {

			if (!viewport_path.is_empty()) {

				Node *n = get_node(viewport_path);
				ERR_FAIL_COND(!n);
				Viewport *vp=n->cast_to<Viewport>();
				ERR_FAIL_COND(!vp);

				Ref<RenderTargetTexture> rtt = vp->get_render_target_texture();
				texture=rtt;
				texture->connect("changed",this,"update");
				item_rect_changed();
			}
		} break;
		case NOTIFICATION_EXIT_TREE: {

			if (texture.is_valid()) {

				texture->disconnect("changed",this,"update");
				texture=Ref<Texture>();
			}
		} break;
		case NOTIFICATION_DRAW: {

			if (texture.is_null())
				return;

			RID ci = get_canvas_item();

			/*
			texture->draw(ci,Point2());
			break;
			*/

			Size2i s;
			Rect2i src_rect;

			s = texture->get_size();

			src_rect.size=s;

			Point2 ofs=offset;
			if (centered)
				ofs-=s/2;

			if (OS::get_singleton()->get_use_pixel_snap()) {
				ofs=ofs.floor();
			}
			Rect2 dst_rect(ofs,s);
			texture->draw_rect_region(ci,dst_rect,src_rect,modulate);

		} break;
	}
}
Exemplo n.º 5
0
Arquivo: sprite.cpp Projeto: 93i/godot
void Sprite::_notification(int p_what) {

    switch(p_what) {

    case NOTIFICATION_DRAW: {

        if (texture.is_null())
            return;




        RID ci = get_canvas_item();

        /*
        texture->draw(ci,Point2());
        break;
        */

        Size2 s;
        Rect2 src_rect;

        if (region) {

            s=region_rect.size;
            src_rect=region_rect;
        } else {
            s = Size2(texture->get_size());
            s=s/Size2(hframes,vframes);

            src_rect.size=s;
            src_rect.pos.x+=float(frame%hframes)*s.x;
            src_rect.pos.y+=float(frame/hframes)*s.y;

        }

        Point2 ofs=offset;
        if (centered)
            ofs-=s/2;
        if (OS::get_singleton()->get_use_pixel_snap()) {
            ofs=ofs.floor();
        }

        Rect2 dst_rect(ofs,s);

        if (hflip)
            dst_rect.size.x=-dst_rect.size.x;
        if (vflip)
            dst_rect.size.y=-dst_rect.size.y;

        texture->draw_rect_region(ci,dst_rect,src_rect,modulate);

    }
    break;
    }
}
Exemplo n.º 6
0
Common::Rect Surface::render(Graphics::Surface *surface, int dx, int dy, bool mirror, Common::Rect src_rect, uint zoom) const {
	if (src_rect.isEmpty()) {
		src_rect = Common::Rect(0, 0, w, h);
	}
	Common::Rect dst_rect(x + dx, y + dy, x + dx + zoom * src_rect.width() / 256, y + dy + zoom * src_rect.height() / 256);
	if (dst_rect.left < 0) {
		src_rect.left = -dst_rect.left;
		dst_rect.left = 0;
	}
	if (dst_rect.right > surface->w) {
		src_rect.right -= dst_rect.right - surface->w;
		dst_rect.right = surface->w;
	}
	if (dst_rect.top < 0) {
		src_rect.top -= dst_rect.top;
		dst_rect.top = 0;
	}
	if (dst_rect.bottom > surface->h) {
		src_rect.bottom -= dst_rect.bottom - surface->h;
		dst_rect.bottom = surface->h;
	}
	if (src_rect.isEmpty() || dst_rect.isEmpty())
		return Common::Rect();

	if (zoom == 256) {
		const byte *src = (const byte *)getBasePtr(0, src_rect.top);
		byte *dst_base = (byte *)surface->getBasePtr(dst_rect.left, dst_rect.top);

		for (int i = src_rect.top; i < src_rect.bottom; ++i) {
			byte *dst = dst_base;
			for (int j = src_rect.left; j < src_rect.right; ++j) {
				byte p = src[(mirror? w - j - 1: j)];
				if (p != 0xff)
					*dst++ = p;
				else
					++dst;
			}
			dst_base += surface->pitch;
			src += pitch;
		}
	} else {
		byte *dst = (byte *)surface->getBasePtr(dst_rect.left, dst_rect.top);
		for(int i = 0; i < dst_rect.height(); ++i) {
			for (int j = 0; j < dst_rect.width(); ++j) {
				int px = j * 256 / zoom;
				const byte *src = (const byte *)getBasePtr(src_rect.left + (mirror? w - px - 1: px), src_rect.top + i * 256 / zoom);
				byte p = *src;
				if (p != 0xff)
					dst[j] = p;
			}
			dst += surface->pitch;
		}
	}
	return dst_rect;
}
Exemplo n.º 7
0
    void shiftMat(InputArray _src, OutputArray _dst, const Point shift)
    {
        Mat src = _src.getMat();
        _dst.create(src.size(), src.type());
        Mat dst = _dst.getMat();

        Mat res = Mat::zeros(src.size(), src.type());
        int width = src.cols - abs(shift.x);
        int height = src.rows - abs(shift.y);
        Rect dst_rect(max(shift.x, 0), max(shift.y, 0), width, height);
        Rect src_rect(max(-shift.x, 0), max(-shift.y, 0), width, height);
        src(src_rect).copyTo(res(dst_rect));
        res.copyTo(dst);
    }
Exemplo n.º 8
0
/* ================================================================
   画像のαブレンド

   ※リトルエンディアン環境を仮定
================================================================ */
void VnImage::Blend(const VnImage& img, u_int8_t srcAlpha, const VnRect& srcRect, int dx, int dy)
{
  // 範囲内のチェック(これは共通ルーチンにした方が良い:TODO:)
  VnRect src_rect(0, 0, img.Width(), img.Height());
  src_rect &= srcRect;
  
  VnRect dst_rect(0, 0, Width(), Height());
  dst_rect &= VnRect(dx, dy, src_rect.width, src_rect.height);

  VnTime t(true);

  int alpha_table[256 * 2 - 1];
  for(int a = -255; a < 256; ++a) {
    if (a < 0) {
      alpha_table[a + 255] = -((-a * srcAlpha) >> 8);
    } else {
Exemplo n.º 9
0
void AnimatedSprite::_notification(int p_what) {

	switch(p_what) {

		case NOTIFICATION_DRAW: {

			if (frames.is_null())
				return;

			if (frame<0 || frame>=frames->get_frame_count())
				return;

			Ref<Texture> texture = frames->get_frame(frame);
			if (texture.is_null())
				return;

			//print_line("DECIDED TO DRAW");

			RID ci = get_canvas_item();

			/*
			texture->draw(ci,Point2());
			break;
			*/

			Size2i s;
			s = texture->get_size();
			Point2 ofs=offset;
			if (centered)
				ofs-=s/2;

			Rect2 dst_rect(ofs,s);

			if (hflip)
				dst_rect.size.x=-dst_rect.size.x;
			if (vflip)
				dst_rect.size.y=-dst_rect.size.y;

			texture->draw_rect(ci,dst_rect,false,modulate);
//			VisualServer::get_singleton()->canvas_item_add_texture_rect_region(ci,dst_rect,texture->get_rid(),src_rect,modulate);

		} break;
	}

}
Exemplo n.º 10
0
void Window_BattleStatus::DrawGauge(Game_Actor* /* actor */, int index, int cx, int cy) {
	BitmapRef system2 = Cache::System2(Data::system.system2_name);

	Battle::Ally& ally = Game_Battle::GetAlly(index);
	bool full = ally.IsReady();
	int gauge_w = ally.gauge * 25 / Game_Battle::gauge_full;
	int speed = 2; // FIXME: how to determine?
	int gauge_y = 32 + speed * 16;
	Rect gauge_left(0, gauge_y, 16, 16);
	Rect gauge_center(16, gauge_y, 16, 16);
	Rect gauge_right(32, gauge_y, 16, 16);
	Rect gauge_bar(full ? 64 : 48, gauge_y, 16, 16);
	Rect dst_rect(cx+16, cy, 25, 16);
	Rect bar_rect(cx+16, cy, gauge_w, 16);

	contents->Blit(cx+0, cy, *system2, gauge_left, 255);
	contents->StretchBlit(dst_rect, *system2, gauge_center, 255);
	contents->Blit(cx+16+25, cy, *system2, gauge_right, 255);
	contents->StretchBlit(bar_rect, *system2, gauge_bar, 255);
}
Exemplo n.º 11
0
/* ================================================================
   指定した矩形内の各画素(RGB各成分)に対し,各成分ごとに指定した値を
   加/減する。引数の範囲は一般的には -256 〜 +256だろうが、その範囲外でも
   動作する。
   
   (※リトルエンディアン環境を仮定)

   計算結果の各成分が……
    0以下   : 0でクランプ
    256以上 : 255でクランプ
================================================================ */
void VnImage::Add(int r, int g, int b, const VnRect& rect)
{

  VnRect dst_rect(0, 0, Width(), Height());
  dst_rect &= rect;

  for(int y = 0; y < dst_rect.height; ++y) {
    u_int32_t* dst = GetPixelBuf(dst_rect.x, dst_rect.y + y);
    for(int x = 0; x < dst_rect.width; ++x, ++dst) {
      int dr = ( *dst        & 0xff) + r;
      int dg = ((*dst >>  8) & 0xff) + g;
      int db = ((*dst >> 16) & 0xff) + b;
      dr = (dr < 0) ? 0 : (dr > 256) ? 255 : dr;
      dg = (dg < 0) ? 0 : (dg > 256) ? 255 : dg;
      db = (db < 0) ? 0 : (db > 256) ? 255 : db;
      *dst = (dr | (dg << 8) | (db << 16));
    }
  }

}
Exemplo n.º 12
0
void Direct3D11::renderText()
{
	if ( ! font_ )
	{
		return;
	}

	getSprite()->begin();

	EffectTechnique* technique = effect_->get_technique( "|sprite" );

	for ( const auto& pass : technique->get_pass_list() )
	{
		pass->apply();

		Sprite::Rect dst_rect( 0, 0, get_width(), get_height() );
		getSprite()->draw( dst_rect, text_view_.get() );
	}

	getSprite()->end();
}
Exemplo n.º 13
0
/** 
 * 指定したイメージ(img)の特定の成分(RGBAのどれか)をαとみなし, それをコピー
 * 
 * @param img       転送元
 * @param mask      pixelに対するマスク
 * @param shift     右シフト値。α = (ToInterfaceColor(pixel) & mask) >> shift;
 * @param srcRect   転送元
 * @param dx        転送先
 * @param dy        転送先
 */
void VnImage::CopyAlpha(const VnImage& img, const u_int32_t mask, const u_int32_t shift, const VnRect& srcRect, int dx, int dy)
{
  // 範囲内のチェック
  VnRect src_rect(0, 0, img.Width(), img.Height());
  src_rect &= srcRect;
  
  VnRect dst_rect(0, 0, Width(), Height());
  dst_rect &= VnRect(dx, dy, src_rect.width, src_rect.height);

  for(int y = 0; y < dst_rect.height; ++y) {
    const u_int32_t* src = img.GetPixelBuf(src_rect.x, src_rect.y + y);
    u_int32_t* dst       = GetPixelBuf(dst_rect.x, dst_rect.y + y);

    for(int x = 0; x < dst_rect.width; ++x, ++dst, ++src) {
      int a = (ToInterfaceColor(*src) & mask) >> shift;
      int r = ( *dst        & 0xff);
      int g = ((*dst >>  8) & 0xff);
      int b = ((*dst >> 16) & 0xff);
      *dst = r | (g << 8) | (b << 16) | (a << 24);
    }
  }

}
Exemplo n.º 14
0
void TBFontFace::DrawString(int x, int y, const TBColor &color, const char *str, int len)
{
	if (m_bgFont)
		m_bgFont->DrawString(x+m_bgX, y+m_bgY, m_bgColor, str, len);

	if (m_font_renderer)
		g_renderer->BeginBatchHint(TBRenderer::BATCH_HINT_DRAW_BITMAP_FRAGMENT);

	int i = 0;
	while (str[i] && i < len)
	{
		UCS4 cp = utf8::decode_next(str, &i, len);
		if (cp == 0xFFFF)
			continue;
		if (TBFontGlyph *glyph = GetGlyph(cp, true))
		{
			if (glyph->frag)
			{
				TBRect dst_rect(x + glyph->metrics.x, y + glyph->metrics.y + GetAscent(), glyph->frag->Width(), glyph->frag->Height());
				TBRect src_rect(0, 0, glyph->frag->Width(), glyph->frag->Height());
				if (glyph->has_rgb)
					g_renderer->DrawBitmap(dst_rect, src_rect, glyph->frag);
				else
					g_renderer->DrawBitmapColored(dst_rect, src_rect, color, glyph->frag);
			}
			x += glyph->metrics.advance;
		}
		else if (!m_font_renderer) // This is the test font. Use same glyph width as height and draw square.
		{
			g_renderer->DrawRect(TBRect(x, y, m_metrics.height / 3, m_metrics.height), color);
			x += m_metrics.height / 3 + 1;
		}
	}

	if (m_font_renderer)
		g_renderer->EndBatchHint();
}
Exemplo n.º 15
0
/* ================================================================
   塗りつぶし。

   αが0xff以外の時は, 
   各RGBに対して目標値と現在のピクセルとでαブレンディングする

   (※リトルエンディアンを仮定)
================================================================ */
void VnImage::Fill(u_int32_t color, const VnRect& rect)
{
  const u_int8_t r = GetRed(color);
  const u_int8_t g = GetGreen(color);
  const u_int8_t b = GetBlue(color);
  const u_int8_t a = GetAlpha(color);

  VnRect dst_rect(0, 0, Width(), Height());
  dst_rect &= rect;

  if (a == 0xff) {
    const u_int32_t fill_color = ToMachineColor(color);
//     cerr << "Fill: " << hex << fill_color << dec << endl;

    // 不透明塗りつぶし
    for(int y = 0; y < dst_rect.height; ++y) {
      u_int32_t* dst = GetPixelBuf(dst_rect.x, dst_rect.y + y);
      for(int x = 0; x < dst_rect.width; ++x, ++dst) {
        *dst = fill_color;
      }
    }
  } else {
    // αブレンディング

    for(int y = 0; y < dst_rect.height; ++y) {
      u_int32_t* dst = GetPixelBuf(dst_rect.x, dst_rect.y + y);
      for(int x = 0; x < dst_rect.width; ++x, ++dst) {
        // よりよい最適化は後回し
        // リトルエンディアンの場合, 0xAABBGGRRとなる
        const int dr = ((r - ( *dst        & 0xff)) * a) >> 8;
        const int dg = ((g - ((*dst >>  8) & 0xff)) * a) >> 8;
        const int db = ((b - ((*dst >> 16) & 0xff)) * a) >> 8;
        *dst += (dr | (dg << 8) | (db << 16));
      }
    }
  }
}
Exemplo n.º 16
0
/**
 * \brief Draws a subrectangle of this surface on another surface.
 * \param region The subrectangle to draw in this object.
 * \param dst_surface The destination surface.
 * \param dst_position Coordinates on the destination surface.
 * The width and height of this rectangle are ignored.
 */
void Surface::raw_draw_region(
    const Rectangle& region,
    Surface& dst_surface,
    const Rectangle& dst_position) {

  if (dst_surface.software_destination  // The destination surface is in RAM.
      || !Video::is_acceleration_enabled()  // The rendering is in RAM.
  ) {

    if (dst_surface.internal_surface == NULL) {
      dst_surface.create_software_surface();
    }

    // First, draw subsurfaces if any.
    // They can exist if the video mode recently switched from an accelerated
    // one to a software one.
    if (!subsurfaces.empty()) {

      if (this->internal_surface == NULL) {
        create_software_surface();
      }

      std::vector<SubSurfaceNode*> subsurfaces = this->subsurfaces;
      this->subsurfaces.clear();  // Avoid infinite recursive calls if there are cycles.

      std::vector<SubSurfaceNode*>::const_iterator it;
      const std::vector<SubSurfaceNode*>::const_iterator end = subsurfaces.end();
      for (it = subsurfaces.begin(); it != end; ++it) {
        SubSurfaceNode* subsurface = *it;

        // TODO draw the subsurfaces of the whole tree recursively instead.
        // The current version is not correct because it handles only one level
        // (it ignores subsurface->subsurfaces).
        // Plus it needs the workaround above to avoid a stack overflow.
        subsurface->src_surface->raw_draw_region(
            subsurface->src_rect,
            *this,
            subsurface->dst_rect
        );
        RefCountable::unref(subsurface);
      }
      clear_subsurfaces();
    }

    if (this->internal_surface != NULL) {
      // The source surface is not empty: draw it onto the destination.

      SDL_BlitSurface(
          this->internal_surface,
          region.get_internal_rect(),
          dst_surface.internal_surface,
          Rectangle(dst_position).get_internal_rect()
      );
    }
    else if (internal_color != NULL) { // No internal surface to draw: this may be a color.

      if (internal_color->get_internal_color()->a == 255) {
        // Fill with opaque color: we can directly modify the destination pixels.
        Rectangle dst_rect(
            dst_position.get_x(), dst_position.get_y(),
            region.get_width(), region.get_height()
        );
        SDL_FillRect(
            dst_surface.internal_surface,
            dst_rect.get_internal_rect(),
            this->internal_color->get_internal_value()
        );
      }
      else {
        // Fill with semi-transparent pixels: perform alpha-blending.
        create_software_surface();
        SDL_FillRect(
            this->internal_surface,
            NULL,
            this->internal_color->get_internal_value()
        );
        SDL_BlitSurface(
            this->internal_surface,
            region.get_internal_rect(),
            dst_surface.internal_surface,
            Rectangle(dst_position).get_internal_rect()
        );
      }
    }
  }
  else {
    // The destination is a GPU surface (a texture).
    // Do not draw anything, just store the operation in the tree instead.
    // The actual drawing will be done at rendering time in GPU.
    dst_surface.add_subsurface(*this, region, dst_position);
  }

  dst_surface.is_rendered = false;
}
Exemplo n.º 17
0
void AnimatedSprite3D::_draw() {

	RID immediate = get_immediate();
	VS::get_singleton()->immediate_clear(immediate);

	if (!frames.is_valid() || !frames->get_frame_count(animation) || frame<0 || frame>=frames->get_frame_count(animation)) {
		return;
	}

	Ref<Texture> texture = frames->get_frame(animation,frame);
	if (!texture.is_valid())
		return; //no texuture no life
	Vector2 tsize = texture->get_size();
	if (tsize.x==0 || tsize.y==0)
		return;

	Size2i s=tsize;
	Rect2i src_rect;

	src_rect.size=s;

	Point2i ofs=get_offset();
	if (is_centered())
		ofs-=s/2;

	Rect2i dst_rect(ofs,s);


	Rect2 final_rect;
	Rect2 final_src_rect;
	if (!texture->get_rect_region(dst_rect,src_rect,final_rect,final_src_rect))
		return;


	if (final_rect.size.x==0 || final_rect.size.y==0)
		return;

	Color color=_get_color_accum();
	color.a*=get_opacity();

	float pixel_size=get_pixel_size();

	Vector2 vertices[4]={

		(final_rect.pos+Vector2(0,final_rect.size.y)) * pixel_size,
		(final_rect.pos+final_rect.size) * pixel_size,
		(final_rect.pos+Vector2(final_rect.size.x,0)) * pixel_size,
		final_rect.pos * pixel_size,


	};
	Vector2 uvs[4]={
		final_src_rect.pos / tsize,
		(final_src_rect.pos+Vector2(final_src_rect.size.x,0)) / tsize,
		(final_src_rect.pos+final_src_rect.size) / tsize,
		(final_src_rect.pos+Vector2(0,final_src_rect.size.y)) / tsize,
	};

	if (is_flipped_h()) {
		SWAP(uvs[0],uvs[1]);
		SWAP(uvs[2],uvs[3]);
	}
	if (is_flipped_v()) {

		SWAP(uvs[0],uvs[3]);
		SWAP(uvs[1],uvs[2]);
	}


	Vector3 normal;
	int axis = get_axis();
	normal[axis]=1.0;

	RID mat = VS::get_singleton()->material_2d_get(get_draw_flag(FLAG_SHADED),get_draw_flag(FLAG_TRANSPARENT),get_alpha_cut_mode()==ALPHA_CUT_DISCARD,get_alpha_cut_mode()==ALPHA_CUT_OPAQUE_PREPASS);
	VS::get_singleton()->immediate_set_material(immediate,mat);

	VS::get_singleton()->immediate_begin(immediate,VS::PRIMITIVE_TRIANGLE_FAN,texture->get_rid());

	int x_axis = ((axis + 1) % 3);
	int y_axis = ((axis + 2) % 3);

	if (axis!=Vector3::AXIS_Z) {
		SWAP(x_axis,y_axis);

		for(int i=0;i<4;i++) {
			//uvs[i] = Vector2(1.0,1.0)-uvs[i];
			//SWAP(vertices[i].x,vertices[i].y);
			if (axis==Vector3::AXIS_Y) {
				vertices[i].y = - vertices[i].y;
			} else if (axis==Vector3::AXIS_X) {
				vertices[i].x = - vertices[i].x;
			}
		}
	}

	AABB aabb;

	for(int i=0;i<4;i++) {
		VS::get_singleton()->immediate_normal(immediate,normal);
		VS::get_singleton()->immediate_color(immediate,color);
		VS::get_singleton()->immediate_uv(immediate,uvs[i]);

		Vector3 vtx;
		vtx[x_axis]=vertices[i][0];
		vtx[y_axis]=vertices[i][1];
		VS::get_singleton()->immediate_vertex(immediate,vtx);
		if (i==0) {
			aabb.pos=vtx;
			aabb.size=Vector3();
		} else {
			aabb.expand_to(vtx);
		}
	}
	set_aabb(aabb);
	VS::get_singleton()->immediate_end(immediate);

}
Exemplo n.º 18
0
void AnimatedSprite::_notification(int p_what) {

	switch (p_what) {
		case NOTIFICATION_INTERNAL_PROCESS: {

			if (frames.is_null())
				return;
			if (!frames->has_animation(animation))
				return;
			if (frame < 0)
				return;

			float speed = frames->get_animation_speed(animation);
			if (speed == 0)
				return; //do nothing

			float remaining = get_process_delta_time();

			while (remaining) {

				if (timeout <= 0) {

					timeout = 1.0 / speed;

					int fc = frames->get_frame_count(animation);
					if (frame >= fc - 1) {
						if (frames->get_animation_loop(animation)) {
							frame = 0;
						} else {
							frame = fc - 1;
						}
					} else {
						frame++;
						if (frame == fc - 1) {
							emit_signal(SceneStringNames::get_singleton()->animation_finished);
						}
					}

					update();
					_change_notify("frame");
					emit_signal(SceneStringNames::get_singleton()->frame_changed);
				}

				float to_process = MIN(timeout, remaining);
				remaining -= to_process;
				timeout -= to_process;
			}
		} break;

		case NOTIFICATION_DRAW: {

			if (frames.is_null()) {
				print_line("no draw no faemos");
				return;
			}

			if (frame < 0) {
				print_line("no draw frame <0");
				return;
			}

			if (!frames->has_animation(animation)) {
				print_line("no draw no anim: " + String(animation));
				return;
			}

			Ref<Texture> texture = frames->get_frame(animation, frame);
			if (texture.is_null()) {
				print_line("no draw texture is null");
				return;
			}

			Ref<Texture> normal = frames->get_normal_frame(animation, frame);

			//print_line("DECIDED TO DRAW");

			RID ci = get_canvas_item();

			/*
			texture->draw(ci,Point2());
			break;
			*/

			Size2i s;
			s = texture->get_size();
			Point2 ofs = offset;
			if (centered)
				ofs -= s / 2;

			if (Engine::get_singleton()->get_use_pixel_snap()) {
				ofs = ofs.floor();
			}
			Rect2 dst_rect(ofs, s);

			if (hflip)
				dst_rect.size.x = -dst_rect.size.x;
			if (vflip)
				dst_rect.size.y = -dst_rect.size.y;

			//texture->draw_rect(ci,dst_rect,false,modulate);
			texture->draw_rect_region(ci, dst_rect, Rect2(Vector2(), texture->get_size()), Color(1, 1, 1), false, normal);
			//VisualServer::get_singleton()->canvas_item_add_texture_rect_region(ci,dst_rect,texture->get_rid(),src_rect,modulate);

		} break;
	}
}
Exemplo n.º 19
0
/**
 * \brief Draws a subrectangle of this surface on another surface.
 * \param region The subrectangle to draw in this object.
 * \param dst_surface The destination surface.
 * \param dst_position Coordinates on the destination surface.
 */
void Surface::raw_draw_region(
    const Rectangle& region,
    Surface& dst_surface,
    const Point& dst_position) {

  if (dst_surface.software_destination  // The destination surface is in RAM.
      || !Video::is_acceleration_enabled()  // The rendering is in RAM.
  ) {

    if (dst_surface.internal_surface == nullptr) {
      dst_surface.create_software_surface();
    }

    // First, draw subsurfaces if any.
    // They can exist if the video mode recently switched from an accelerated
    // one to a software one.
    if (!subsurfaces.empty()) {

      if (this->internal_surface == nullptr) {
        create_software_surface();
      }

      std::vector<SubSurfaceNodePtr> subsurfaces = this->subsurfaces;
      this->subsurfaces.clear();  // Avoid infinite recursive calls if there are cycles.

      for (SubSurfaceNodePtr& subsurface: subsurfaces) {

        // TODO draw the subsurfaces of the whole tree recursively instead.
        // The current version is not correct because it handles only one level
        // (it ignores subsurface->subsurfaces).
        // Plus it needs the workaround above to avoid a stack overflow.
        subsurface->src_surface->raw_draw_region(
            subsurface->src_rect,
            *this,
            subsurface->dst_rect.get_xy()
        );
        subsurface = nullptr;
      }
      clear_subsurfaces();
    }

    if (this->internal_surface != nullptr) {
      // The source surface is not empty: draw it onto the destination.

      SDL_SetSurfaceBlendMode(
            this->internal_surface.get(),
            get_sdl_blend_mode()
      );
      SDL_BlitSurface(
          this->internal_surface.get(),
          region.get_internal_rect(),
          dst_surface.internal_surface.get(),
          Rectangle(dst_position).get_internal_rect()
      );
    }
    else if (internal_color != nullptr) { // No internal surface to draw: this may be a color.

      if (get_blend_mode() == BlendMode::BLEND && internal_color->get_alpha() == 255) {
        // Fill with opaque color: we can directly modify the destination pixels.
        Rectangle dst_rect(
            dst_position,
            region.get_size()
        );
        SDL_FillRect(
            dst_surface.internal_surface.get(),
            dst_rect.get_internal_rect(),
            get_color_value(*internal_color)
        );
      }
      else {
        // Fill with semi-transparent pixels: perform alpha-blending.
        create_software_surface();
        SDL_FillRect(
            this->internal_surface.get(),
            nullptr,
            get_color_value(*internal_color)
        );
        SDL_BlitSurface(
            this->internal_surface.get(),
            region.get_internal_rect(),
            dst_surface.internal_surface.get(),
            Rectangle(dst_position).get_internal_rect()
        );
      }
    }
  }
  else {
    // The destination is a GPU surface (a texture).
    // Do not draw anything, just store the operation in the tree instead.
    // The actual drawing will be done at rendering time in GPU.

    SurfacePtr src_surface = std::static_pointer_cast<Surface>(shared_from_this());
    dst_surface.add_subsurface(src_surface, region, dst_position);
  }

  dst_surface.is_rendered = false;
}
Exemplo n.º 20
0
void AnimatedSprite::_notification(int p_what) {

	switch (p_what) {
		case NOTIFICATION_INTERNAL_PROCESS: {

			if (frames.is_null())
				return;
			if (!frames->has_animation(animation))
				return;
			if (frame < 0)
				return;

			float speed = frames->get_animation_speed(animation) * speed_scale;
			if (speed == 0)
				return; //do nothing

			float remaining = get_process_delta_time();

			while (remaining) {

				if (timeout <= 0) {

					timeout = _get_frame_duration();

					int fc = frames->get_frame_count(animation);
					if (frame >= fc - 1) {
						if (frames->get_animation_loop(animation)) {
							frame = 0;
							emit_signal(SceneStringNames::get_singleton()->animation_finished);
						} else {
							frame = fc - 1;
							if (!is_over) {
								is_over = true;
								emit_signal(SceneStringNames::get_singleton()->animation_finished);
							}
						}
					} else {
						frame++;
					}

					update();
					_change_notify("frame");
					emit_signal(SceneStringNames::get_singleton()->frame_changed);
				}

				float to_process = MIN(timeout, remaining);
				remaining -= to_process;
				timeout -= to_process;
			}
		} break;

		case NOTIFICATION_DRAW: {

			if (frames.is_null())
				return;
			if (frame < 0)
				return;
			if (!frames->has_animation(animation))
				return;

			Ref<Texture> texture = frames->get_frame(animation, frame);
			if (texture.is_null())
				return;

			Ref<Texture> normal = frames->get_normal_frame(animation, frame);

			RID ci = get_canvas_item();

			Size2i s;
			s = texture->get_size();
			Point2 ofs = offset;
			if (centered)
				ofs -= s / 2;

			if (Engine::get_singleton()->get_use_pixel_snap()) {
				ofs = ofs.floor();
			}
			Rect2 dst_rect(ofs, s);

			if (hflip)
				dst_rect.size.x = -dst_rect.size.x;
			if (vflip)
				dst_rect.size.y = -dst_rect.size.y;

			texture->draw_rect_region(ci, dst_rect, Rect2(Vector2(), texture->get_size()), Color(1, 1, 1), false, normal);

		} break;
	}
}
Exemplo n.º 21
0
void Sprite3D::_draw() {

	RID immediate = get_immediate();

	VS::get_singleton()->immediate_clear(immediate);
	if (!texture.is_valid())
		return; //no texuture no life
	Vector2 tsize = texture->get_size();
	if (tsize.x == 0 || tsize.y == 0)
		return;

	Size2i s;
	Rect2i src_rect;

	if (region) {

		s = region_rect.size;
		src_rect = region_rect;
	} else {
		s = texture->get_size();
		s = s / Size2i(hframes, vframes);

		src_rect.size = s;
		src_rect.position.x += (frame % hframes) * s.x;
		src_rect.position.y += (frame / hframes) * s.y;
	}

	Point2i ofs = get_offset();
	if (is_centered())
		ofs -= s / 2;

	Rect2i dst_rect(ofs, s);

	Rect2 final_rect;
	Rect2 final_src_rect;
	if (!texture->get_rect_region(dst_rect, src_rect, final_rect, final_src_rect))
		return;

	if (final_rect.size.x == 0 || final_rect.size.y == 0)
		return;

	Color color = _get_color_accum();
	color.a *= get_opacity();

	float pixel_size = get_pixel_size();

	Vector2 vertices[4] = {

		(final_rect.position + Vector2(0, final_rect.size.y)) * pixel_size,
		(final_rect.position + final_rect.size) * pixel_size,
		(final_rect.position + Vector2(final_rect.size.x, 0)) * pixel_size,
		final_rect.position * pixel_size,

	};

	Vector2 src_tsize = tsize;

	// Properly setup UVs for impostor textures (AtlasTexture).
	Ref<AtlasTexture> atlas_tex = texture;
	if (atlas_tex != NULL) {
		src_tsize[0] = atlas_tex->get_atlas()->get_width();
		src_tsize[1] = atlas_tex->get_atlas()->get_height();
	}

	Vector2 uvs[4] = {
		final_src_rect.position / src_tsize,
		(final_src_rect.position + Vector2(final_src_rect.size.x, 0)) / src_tsize,
		(final_src_rect.position + final_src_rect.size) / src_tsize,
		(final_src_rect.position + Vector2(0, final_src_rect.size.y)) / src_tsize,
	};

	if (is_flipped_h()) {
		SWAP(uvs[0], uvs[1]);
		SWAP(uvs[2], uvs[3]);
	}
	if (is_flipped_v()) {

		SWAP(uvs[0], uvs[3]);
		SWAP(uvs[1], uvs[2]);
	}

	Vector3 normal;
	int axis = get_axis();
	normal[axis] = 1.0;

	RID mat = SpatialMaterial::get_material_rid_for_2d(get_draw_flag(FLAG_SHADED), get_draw_flag(FLAG_TRANSPARENT), get_draw_flag(FLAG_DOUBLE_SIDED), get_alpha_cut_mode() == ALPHA_CUT_DISCARD, get_alpha_cut_mode() == ALPHA_CUT_OPAQUE_PREPASS);
	VS::get_singleton()->immediate_set_material(immediate, mat);

	VS::get_singleton()->immediate_begin(immediate, VS::PRIMITIVE_TRIANGLE_FAN, texture->get_rid());

	int x_axis = ((axis + 1) % 3);
	int y_axis = ((axis + 2) % 3);

	if (axis != Vector3::AXIS_Z) {
		SWAP(x_axis, y_axis);

		for (int i = 0; i < 4; i++) {
			//uvs[i] = Vector2(1.0,1.0)-uvs[i];
			//SWAP(vertices[i].x,vertices[i].y);
			if (axis == Vector3::AXIS_Y) {
				vertices[i].y = -vertices[i].y;
			} else if (axis == Vector3::AXIS_X) {
				vertices[i].x = -vertices[i].x;
			}
		}
	}

	AABB aabb;

	for (int i = 0; i < 4; i++) {
		VS::get_singleton()->immediate_normal(immediate, normal);
		VS::get_singleton()->immediate_color(immediate, color);
		VS::get_singleton()->immediate_uv(immediate, uvs[i]);

		Vector3 vtx;
		vtx[x_axis] = vertices[i][0];
		vtx[y_axis] = vertices[i][1];
		VS::get_singleton()->immediate_vertex(immediate, vtx);
		if (i == 0) {
			aabb.position = vtx;
			aabb.size = Vector3();
		} else {
			aabb.expand_to(vtx);
		}
	}
	set_aabb(aabb);
	VS::get_singleton()->immediate_end(immediate);
}
Exemplo n.º 22
0
void Sprite3D::_draw() {

	RID immediate = get_immediate();

	VS::get_singleton()->immediate_clear(immediate);
	if (!texture.is_valid())
		return; //no texuture no life
	Vector2 tsize = texture->get_size();
	if (tsize.x==0 || tsize.y==0)
		return;

	Size2i s;
	Rect2i src_rect;

	if (region) {

		s=region_rect.size;
		src_rect=region_rect;
	} else {
		s = texture->get_size();
		s=s/Size2i(hframes,vframes);

		src_rect.size=s;
		src_rect.pos.x+=(frame%hframes)*s.x;
		src_rect.pos.y+=(frame/hframes)*s.y;

	}

	Point2i ofs=get_offset();
	if (is_centered())
		ofs-=s/2;

	Rect2i dst_rect(ofs,s);


	Rect2 final_rect;
	Rect2 final_src_rect;
	if (!texture->get_rect_region(dst_rect,src_rect,final_rect,final_src_rect))
		return;


	if (final_rect.size.x==0 || final_rect.size.y==0)
		return;

	Color color=_get_color_accum();
	color.a*=get_opacity();

	float pixel_size=get_pixel_size();

	Vector2 vertices[4]={

		(final_rect.pos+Vector2(0,final_rect.size.y)) * pixel_size,
		(final_rect.pos+final_rect.size) * pixel_size,
		(final_rect.pos+Vector2(final_rect.size.x,0)) * pixel_size,
		final_rect.pos * pixel_size,


	};
	Vector2 uvs[4]={
		final_src_rect.pos / tsize,
		(final_src_rect.pos+Vector2(final_src_rect.size.x,0)) / tsize,
		(final_src_rect.pos+final_src_rect.size) / tsize,
		(final_src_rect.pos+Vector2(0,final_src_rect.size.y)) / tsize,
	};

	if (is_flipped_h()) {
		SWAP(uvs[0],uvs[1]);
		SWAP(uvs[2],uvs[3]);
	}
	if (is_flipped_v()) {

		SWAP(uvs[0],uvs[3]);
		SWAP(uvs[1],uvs[2]);
	}


	Vector3 normal;
	int axis = get_axis();
	normal[axis]=1.0;

	RID mat = VS::get_singleton()->material_2d_get(get_draw_flag(FLAG_SHADED),get_draw_flag(FLAG_TRANSPARENT),get_alpha_cut_mode()==ALPHA_CUT_DISCARD,get_alpha_cut_mode()==ALPHA_CUT_OPAQUE_PREPASS);
	VS::get_singleton()->immediate_set_material(immediate,mat);

	VS::get_singleton()->immediate_begin(immediate,VS::PRIMITIVE_TRIANGLE_FAN,texture->get_rid());

	int x_axis = ((axis + 1) % 3);
	int y_axis = ((axis + 2) % 3);

	AABB aabb;

	for(int i=0;i<4;i++) {
		VS::get_singleton()->immediate_normal(immediate,normal);
		VS::get_singleton()->immediate_color(immediate,color);
		VS::get_singleton()->immediate_uv(immediate,uvs[i]);

		Vector3 vtx;
		vtx[x_axis]=vertices[i][x_axis];
		vtx[y_axis]=vertices[i][y_axis];
		VS::get_singleton()->immediate_vertex(immediate,vtx);
		if (i==0) {
			aabb.pos=vtx;
			aabb.size=Vector3();
		} else {
			aabb.expand_to(vtx);
		}
	}
	set_aabb(aabb);
	VS::get_singleton()->immediate_end(immediate);


}
Exemplo n.º 23
0
void AnimatedSprite::_notification(int p_what) {

	switch(p_what) {
		case NOTIFICATION_PROCESS: {

			if (frames.is_null())
				return;
			if (!frames->has_animation(animation))
				return;
			if (frame<0)
				return;

			float speed = frames->get_animation_speed(animation) * play_rate;
			if (speed==0)
				return; //do nothing

			float remaining = get_process_delta_time();

			while(remaining) {

				if (timeout<=0) {

					int fc = frames->get_frame_count(animation);
					if (frame>=fc-1) {
						if (frames->get_animation_loop(animation)) {
							frame=0;
						} else {
							frame=fc-1;
							// early exit so we don't do anything for non-looping ended animations, may want to
							// broadcast once more "frame" notify, pending
							break;
						}
					} else {
						frame++;
					}
					// to avoid timeout being reset for non-looping animations so queries can be use timeout value
					timeout = 1.0 / speed;
					update();
					_change_notify("frame");
				}

				float to_process = MIN(timeout,remaining);
				remaining-=to_process;
				timeout-=to_process;
			}
		} break;

		case NOTIFICATION_DRAW: {

			if (frames.is_null()) {
				print_line("no draw no faemos");
				return;
			}

			if (frame<0) {
				print_line("no draw frame <0");
				return;
			}

			if (!frames->has_animation(animation)) {
				print_line("no draw no anim: "+String(animation));
				return;
			}



			Ref<Texture> texture = frames->get_frame(animation,frame);
			if (texture.is_null()) {
				print_line("no draw texture is null");
				return;
			}

			//print_line("DECIDED TO DRAW");

			RID ci = get_canvas_item();

			/*
			texture->draw(ci,Point2());
			break;
			*/

			Size2i s;
			s = texture->get_size();
			Point2 ofs=offset;

			adjust_offset(ofs, s);

			if (OS::get_singleton()->get_use_pixel_snap()) {
				ofs=ofs.floor();
			}
			Rect2 dst_rect(ofs,s);

			if (hflip)
				dst_rect.size.x=-dst_rect.size.x;
			if (vflip)
				dst_rect.size.y=-dst_rect.size.y;

			//texture->draw_rect(ci,dst_rect,false,modulate);
			texture->draw_rect_region(ci,dst_rect,Rect2(Vector2(),texture->get_size()),modulate);
//			VisualServer::get_singleton()->canvas_item_add_texture_rect_region(ci,dst_rect,texture->get_rid(),src_rect,modulate);

		} break;
	}

}