示例#1
0
文件: Texture.cpp 项目: neo333/XGame
	void Texture::LoadTexture_fromSurface(const Surface& input_surface, const ScreenVideo& makerVideo, Rect& area_cut) throw(Error){
		this->Clean();
		if (makerVideo.m_renderer == nullptr)
			throw Error("Texture", "LoadTexture_fromMemoryPage", "Impossibile caricare una texture con uno specifico renderer nullo!");
		if (makerVideo.m_renderer != m_render) m_render = makerVideo.m_renderer;
		if (input_surface.Is_Void()) return;
		if (area_cut.Get_Xcomponent() < 0) area_cut.Set_Xcomponent(0);
		if (area_cut.Get_Ycomponent() < 0) area_cut.Set_Ycomponent(0);
		if (area_cut.Get_Wcomponent() < 0) area_cut.Set_Wcomponent(input_surface.Get_W() - area_cut.Get_Xcomponent());
		if (area_cut.Get_Hcomponent() < 0) area_cut.Set_Hcomponent(input_surface.Get_H() - area_cut.Get_Ycomponent());
		if (area_cut.Get_Wcomponent() + (size_t)area_cut.Get_Xcomponent() > input_surface.Get_W())
			area_cut.Set_Wcomponent(input_surface.Get_W() - area_cut.Get_Xcomponent());
		if (area_cut.Get_Hcomponent() + (size_t)area_cut.Get_Ycomponent() > input_surface.Get_H())
			area_cut.Set_Hcomponent(input_surface.Get_H() - area_cut.Get_Ycomponent());

		this->m_texture = SDL_CreateTexture(m_render, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STREAMING, 
			area_cut.Get_Wcomponent(), area_cut.Get_Hcomponent());
		if (this->m_texture == nullptr)
			throw Error("Texture", "LoadTexture_fromSurface", "Impossibile creare una texture grafica!\n%s", SDL_GetError());

		void* data_texture;
		int pitch_texture;

		if (SDL_LockTexture(m_texture, NULL, &data_texture, &pitch_texture) != 0)
			throw Error("Texture", "LoadTexture_fromSurface", "Impossibile scrivere la texture grafica!\n%s", SDL_GetError());
		if (SDL_LockSurface(input_surface.m_surface) != 0){
			SDL_UnlockTexture(m_texture);
			throw Error("Texture", "LoadTexture_fromSurface", "Impossibile leggere la surface grafica!\n%s", SDL_GetError());
		}
			

		try{
			Uint8* texture_pixelb = static_cast<Uint8*>(data_texture);
			const Uint8* surface_pixelb = static_cast<Uint8*>(input_surface.m_surface->pixels) +
				area_cut.Get_Ycomponent() * input_surface.m_surface->pitch +
				area_cut.Get_Xcomponent() * input_surface.m_surface->format->BytesPerPixel;

			const int row_size = area_cut.Get_Wcomponent() * input_surface.m_surface->format->BytesPerPixel;

			for (register int row = 0; row < area_cut.Get_Hcomponent(); ++row){
				memcpy(texture_pixelb, surface_pixelb, row_size);
				texture_pixelb += pitch_texture;
				surface_pixelb += input_surface.m_surface->pitch;
			}
		}
		catch (const std::exception& err){
			SDL_UnlockTexture(m_texture);
			SDL_UnlockSurface(input_surface.m_surface);
			throw Error("Texture", "LoadTexture_fromSurface", "Impossibile copiare i dati nella destinazione!\n%s", err.what());
		}

		SDL_UnlockSurface(input_surface.m_surface);
		SDL_UnlockTexture(m_texture);
		data_texture = nullptr;

		m_w_size = area_cut.Get_Wcomponent();
		m_h_size = area_cut.Get_Hcomponent();
		m_w_size_scaled = m_w_size;
		m_h_size_scaled = m_h_size;
		m_drawnable_area.Set_AllComponent(0, 0, m_w_size, m_h_size);
		m_alpha_mod = SDL_ALPHA_OPAQUE;

		SDL_SetTextureBlendMode(m_texture, SDL_BLENDMODE_BLEND);
	}