void VulkanImage::map(UINT32 face, UINT32 mipLevel, PixelData& output) const
	{
		VulkanDevice& device = mOwner->getDevice();

		VkImageSubresource range;
		range.mipLevel = mipLevel;
		range.arrayLayer = face;

		if (mImageViewCI.subresourceRange.aspectMask == VK_IMAGE_ASPECT_COLOR_BIT)
			range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
		else // Depth stencil, but we only map depth
			range.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;

		VkSubresourceLayout layout;
		vkGetImageSubresourceLayout(device.getLogical(), mImage, &range, &layout);

		const UINT32 pixelSize = PixelUtil::getNumElemBytes(output.getFormat());
		assert((UINT32)layout.rowPitch % pixelSize == 0);
		assert((UINT32)layout.depthPitch % pixelSize == 0);

		output.setRowPitch((UINT32)layout.rowPitch / pixelSize);
		output.setSlicePitch((UINT32)layout.depthPitch / pixelSize);

		VkDeviceMemory memory;
		VkDeviceSize memoryOffset;
		device.getAllocationInfo(mAllocation, memory, memoryOffset);

		UINT8* data;
		VkResult result = vkMapMemory(device.getLogical(), memory, memoryOffset + layout.offset, layout.size, 0, (void**)&data);
		assert(result == VK_SUCCESS);

		output.setExternalBuffer(data);
	}
Texture CubeTransitionApp::LoadStageFillingTexture( const char* filepath )
{
  ImageDimensions dimensions( Stage::GetCurrent().GetSize().x, Stage::GetCurrent().GetSize().y );
  BitmapLoader loader = BitmapLoader::New( filepath, dimensions, FittingMode::SCALE_TO_FILL );
  loader.Load();
  PixelData pixelData = loader.GetPixelData();
  Texture texture = Texture::New( TextureType::TEXTURE_2D, pixelData.GetPixelFormat(), pixelData.GetWidth(), pixelData.GetHeight() );
  texture.Upload( pixelData );
  return texture;
}
Exemple #3
0
PixelData* MagickInputFormat::CreatePixelData(const char* filePath)
{
	PixelData* pData = NULL;

	
	MagickWandGenesis();

	MagickWand* wand = NewMagickWand();
	MagickBooleanType status = MagickReadImage(wand, filePath);

	if (status != MagickTrue)
	{
		DumpWandError(wand);
		DestroyMagickWand(wand);
		MagickWandTerminus();
		return NULL;
	}

	int w = MagickGetImageWidth(wand);
	int h = MagickGetImageHeight(wand);

	Format format = MagickGetImageAlphaChannel(wand) == MagickFalse ? FORMAT_RGB : FORMAT_RGBA;
	const char* strFormat = NULL;

	switch (format)
	{
	case FORMAT_RGB:  strFormat = "RGB"; break;
	case FORMAT_RGBA: strFormat = "RGBA"; break;
	};

	assert(strFormat != NULL);


	//Now create the pixel data
	pData = new PixelData(w, h, format);

	status = MagickExportImagePixels(wand, 0, 0, w, h, strFormat,  FloatPixel, pData->GetData());

	if (status != MagickTrue)
	{
		delete pData;

		DumpWandError(wand);
		DestroyMagickWand(wand);
		MagickWandTerminus();
		return NULL;
	}

	DestroyMagickWand(wand);
	MagickWandTerminus();


	return pData;
}
int UtcDaliPixelData01(void)
{
  TestApplication application;

  unsigned int width = 10u;
  unsigned int height = 10u;
  unsigned int bufferSize = width*height*Pixel::GetBytesPerPixel( Pixel::RGB888 );

  unsigned char* buffer= reinterpret_cast<unsigned char*>( malloc( bufferSize ) );
  PixelData pixelData = PixelData::New( buffer, bufferSize, width, height, Pixel::RGB888, PixelData::FREE );

  DALI_TEST_CHECK( pixelData );
  DALI_TEST_CHECK( pixelData.GetWidth() == width );
  DALI_TEST_CHECK( pixelData.GetHeight() == height );
  DALI_TEST_CHECK( pixelData.GetPixelFormat() == Pixel::RGB888 );

  END_TEST;
}
int UtcDaliPixelData02(void)
{
  TestApplication application;

  unsigned int width = 10u;
  unsigned int height = 10u;
  unsigned int bufferSize = width*height*Pixel::GetBytesPerPixel( Pixel::L8 );
  unsigned char* buffer = new unsigned char [ bufferSize ];
  buffer[0] = 'a';

  PixelData pixelData = PixelData::New( buffer, bufferSize, width, height, Pixel::L8, PixelData::DELETE_ARRAY );

  DALI_TEST_CHECK( pixelData);
  DALI_TEST_CHECK( pixelData.GetWidth() == width );
  DALI_TEST_CHECK( pixelData.GetHeight() == height );
  DALI_TEST_CHECK( pixelData.GetPixelFormat() == Pixel::L8 );

  END_TEST;
}
	void D3D11TextureCore::writeData(const PixelData& src, UINT32 mipLevel, UINT32 face, bool discardWholeBuffer)
	{
		PixelFormat format = mProperties.getFormat();

		if (mProperties.getMultisampleCount() > 1)
			BS_EXCEPT(InvalidStateException, "Multisampled textures cannot be accessed from the CPU directly.");

		mipLevel = Math::clamp(mipLevel, (UINT32)mipLevel, mProperties.getNumMipmaps());
		face = Math::clamp(face, (UINT32)0, mProperties.getNumFaces() - 1);

		if (face > 0 && mProperties.getTextureType() == TEX_TYPE_3D)
			BS_EXCEPT(InvalidStateException, "3D texture arrays are not supported.");

		if ((mProperties.getUsage() & TU_DYNAMIC) != 0)
		{
			PixelData myData = lock(discardWholeBuffer ? GBL_WRITE_ONLY_DISCARD : GBL_WRITE_ONLY, mipLevel, face);
			PixelUtil::bulkPixelConversion(src, myData);
			unlock();
		}
		else if ((mProperties.getUsage() & TU_DEPTHSTENCIL) == 0)
		{
			D3D11RenderAPI* rs = static_cast<D3D11RenderAPI*>(RenderAPICore::instancePtr());
			D3D11Device& device = rs->getPrimaryDevice();

			UINT subresourceIdx = D3D11CalcSubresource(mipLevel, face, mProperties.getNumMipmaps() + 1);
			UINT32 rowWidth = D3D11Mappings::getSizeInBytes(format, src.getWidth());
			UINT32 sliceWidth = D3D11Mappings::getSizeInBytes(format, src.getWidth(), src.getHeight());

			device.getImmediateContext()->UpdateSubresource(mTex, subresourceIdx, nullptr, src.getData(), rowWidth, sliceWidth);

			if (device.hasError())
			{
				String errorDescription = device.getErrorDescription();
				BS_EXCEPT(RenderingAPIException, "D3D11 device cannot map texture\nError Description:" + errorDescription);
			}

			BS_INC_RENDER_STAT_CAT(ResWrite, RenderStatObject_Texture);
		}
		else
		{
			BS_EXCEPT(RenderingAPIException, "Trying to write into a buffer with unsupported usage: " + toString(mProperties.getUsage()));
		}
	}
	void D3D11TextureCore::readData(PixelData& dest, UINT32 mipLevel, UINT32 face)
	{
		if (mProperties.getMultisampleCount() > 1)
			BS_EXCEPT(InvalidStateException, "Multisampled textures cannot be accessed from the CPU directly.");

		PixelData myData = lock(GBL_READ_ONLY, mipLevel, face);

#if BS_DEBUG_MODE
		if(dest.getConsecutiveSize() != myData.getConsecutiveSize())
		{
			unlock();
			BS_EXCEPT(InternalErrorException, "Buffer sizes don't match");
		}
#endif

		PixelUtil::bulkPixelConversion(myData, dest);

		unlock();
	}
	void GLTextureBuffer::download(const PixelData &data)
	{
		if(data.getWidth() != getWidth() || data.getHeight() != getHeight() || data.getDepth() != getDepth())
			BS_EXCEPT(InvalidParametersException, "only download of entire buffer is supported by GL");

		glBindTexture( mTarget, mTextureID );
		if(PixelUtil::isCompressed(data.getFormat()))
		{
			if(data.getFormat() != mFormat || !data.isConsecutive())
				BS_EXCEPT(InvalidParametersException, 
				"Compressed images must be consecutive, in the source format");

			// Data must be consecutive and at beginning of buffer as PixelStorei not allowed
			// for compressed formate
			glGetCompressedTexImage(mFaceTarget, mLevel, data.getData());
		} 
		else
		{
			if(data.getWidth() != data.getRowPitch())
				glPixelStorei(GL_PACK_ROW_LENGTH, data.getRowPitch());

			if(data.getHeight()*data.getWidth() != data.getSlicePitch())
				glPixelStorei(GL_PACK_IMAGE_HEIGHT, (data.getSlicePitch()/data.getWidth()));

			if(data.getLeft() > 0 || data.getTop() > 0 || data.getFront() > 0)
				glPixelStorei(GL_PACK_SKIP_PIXELS, data.getLeft() + data.getRowPitch() * data.getTop() + data.getSlicePitch() * data.getFront());

			if((data.getWidth()*PixelUtil::getNumElemBytes(data.getFormat())) & 3)
				glPixelStorei(GL_PACK_ALIGNMENT, 1);

			// We can only get the entire texture
			glGetTexImage(mFaceTarget, mLevel, GLPixelUtil::getGLOriginFormat(data.getFormat()), 
				GLPixelUtil::getGLOriginDataType(data.getFormat()), data.getData());

			// Restore defaults
			glPixelStorei(GL_PACK_ROW_LENGTH, 0);
			glPixelStorei(GL_PACK_IMAGE_HEIGHT, 0);
			glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
			glPixelStorei(GL_PACK_ALIGNMENT, 4);
		}

		BS_INC_RENDER_STAT_CAT(ResRead, RenderStatObject_Texture);
	}
	void GLTextureBuffer::upload(const PixelData &data, const PixelVolume &dest)
	{
		if((mUsage & TU_RENDERTARGET) != 0)
			BS_EXCEPT(NotImplementedException, "Writing to render texture from CPU not supported.");

		if ((mUsage & TU_DEPTHSTENCIL) != 0)
			BS_EXCEPT(NotImplementedException, "Writing to depth stencil texture from CPU not supported.");

		glBindTexture( mTarget, mTextureID );
		if(PixelUtil::isCompressed(data.getFormat()))
		{
			if(data.getFormat() != mFormat || !data.isConsecutive())
				BS_EXCEPT(InvalidParametersException, 
				"Compressed images must be consecutive, in the source format");

			GLenum format = GLPixelUtil::getClosestGLInternalFormat(mFormat);
			switch(mTarget) {
				case GL_TEXTURE_1D:
					if (dest.left == 0)
					{
						glCompressedTexImage1D(GL_TEXTURE_1D, mLevel,
							format,
							dest.getWidth(),
							0,
							data.getConsecutiveSize(),
							data.getData());
					}
					else
					{
						glCompressedTexSubImage1D(GL_TEXTURE_1D, mLevel, 
							dest.left,
							dest.getWidth(),
							format, data.getConsecutiveSize(),
							data.getData());
					}
					break;
				case GL_TEXTURE_2D:
				case GL_TEXTURE_CUBE_MAP:
					if (dest.left == 0 && dest.top == 0)
					{
						glCompressedTexImage2D(mFaceTarget, mLevel,
							format,
							dest.getWidth(),
							dest.getHeight(),
							0,
							data.getConsecutiveSize(),
							data.getData());
					}
					else
					{
						glCompressedTexSubImage2D(mFaceTarget, mLevel, 
							dest.left, dest.top, 
							dest.getWidth(), dest.getHeight(),
							format, data.getConsecutiveSize(),
							data.getData());
					}
					break;
				case GL_TEXTURE_3D:
					if (dest.left == 0 && dest.top == 0 && dest.front == 0)
					{
						glCompressedTexImage3D(GL_TEXTURE_3D, mLevel,
							format,
							dest.getWidth(),
							dest.getHeight(),
							dest.getDepth(),
							0,
							data.getConsecutiveSize(),
							data.getData());
					}
					else
					{			
						glCompressedTexSubImage3D(GL_TEXTURE_3D, mLevel, 
							dest.left, dest.top, dest.front,
							dest.getWidth(), dest.getHeight(), dest.getDepth(),
							format, data.getConsecutiveSize(),
							data.getData());
					}
					break;
			}
		
		} 
		else
		{
			if(data.getWidth() != data.getRowPitch())
				glPixelStorei(GL_UNPACK_ROW_LENGTH, data.getRowPitch());

			if(data.getHeight()*data.getWidth() != data.getSlicePitch())
				glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, (data.getSlicePitch()/data.getWidth()));

			if(data.getLeft() > 0 || data.getTop() > 0 || data.getFront() > 0)
				glPixelStorei(GL_UNPACK_SKIP_PIXELS, data.getLeft() + data.getRowPitch() * data.getTop() + data.getSlicePitch() * data.getFront());

			if((data.getWidth()*PixelUtil::getNumElemBytes(data.getFormat())) & 3)
				glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

			switch(mTarget) {
				case GL_TEXTURE_1D:
					glTexSubImage1D(GL_TEXTURE_1D, mLevel, 
						dest.left,
						dest.getWidth(),
						GLPixelUtil::getGLOriginFormat(data.getFormat()), GLPixelUtil::getGLOriginDataType(data.getFormat()),
						data.getData());
					break;
				case GL_TEXTURE_2D:
				case GL_TEXTURE_CUBE_MAP:
					glTexSubImage2D(mFaceTarget, mLevel, 
						dest.left, dest.top, 
						dest.getWidth(), dest.getHeight(),
						GLPixelUtil::getGLOriginFormat(data.getFormat()), GLPixelUtil::getGLOriginDataType(data.getFormat()),
						data.getData());
					break;
				case GL_TEXTURE_3D:
					glTexSubImage3D(
						GL_TEXTURE_3D, mLevel, 
						dest.left, dest.top, dest.front,
						dest.getWidth(), dest.getHeight(), dest.getDepth(),
						GLPixelUtil::getGLOriginFormat(data.getFormat()), GLPixelUtil::getGLOriginDataType(data.getFormat()),
						data.getData());
					break;
			}	
		}

		// Restore defaults
		glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
		glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, 0);
		glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
		glPixelStorei(GL_UNPACK_ALIGNMENT, 4);

		BS_INC_RENDER_STAT_CAT(ResWrite, RenderStatObject_Texture);
	}
Exemple #10
0
void ImageRenderable::drawContent(const DrawContext& context)
{
    WidgetRenderable::drawContent(context);

    PixelData* tex = myOwner->getData();
    if(tex != NULL)
    {
        DrawInterface* di = getRenderer();
        di->fillTexture(tex);
        di->textureRegion(0, 0, 1, 1);
        if(!myOwner->myUseFullSource)
        {
            Rect& r = myOwner->mySourceRect;
            int w = tex->getWidth();
            int h = tex->getHeight();
            float su = (float)r.x() / w;
            float sv = 1 - (float)r.y() / h;
            float eu = (float)(r.x() + r.width()) / w;
            float ev = 1 - (float)(r.y() + r.height()) / h;
            di->textureRegion(su, ev, eu, sv);
        }
        else if(myOwner->myTile)
        {
            int w = tex->getWidth();
            int h = tex->getHeight();
            int W = myOwner->getWidth();
            int H = myOwner->getHeight();
            float eu = (float)(W) / w;
            float ev = (float)(H) / h;
            di->textureRegion(0, 0, eu, ev);
        }

        if(myTextureUniform != 0)
        {
            glUniform1i(myTextureUniform, 0);
        }

        if(myOwner->isStereo())
        {
            DrawContext::Eye eye = context.eye;
            if(eye == DrawContext::EyeLeft)
            {
                di->textureRegion(0, 0, 0.5f, 1);
            }
            else if(eye == DrawContext::EyeRight)
            {
                di->textureRegion(0.5f, 0, 0.5f, 1);
            }
        }

        Vector2f size = myOwner->getSize();
        if(myOwner->myUseFullDest)
        {
            di->rect(0, 0, size[0], size[1]);
        }
        else
        {
            Rect& r = myOwner->myDestRect;
            di->rect(r.x(), r.y(), r.width(), r.height());
        }
    }
    else
    {
        refresh();
    }
}
Exemple #11
0
PixelData* TIFFInputFormat::CreatePixelData(const char* filePath)
{
	PixelData* pData = nullptr;

	TIFF* tif = TIFFOpen(filePath, "r");

	if (tif != nullptr)
	{

		
		uint32 w, h;
		size_t npixels;
		uint32* raster;

		TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &w);
		TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &h);

		npixels = w * h;

		//cout << "Creating pixel data from TIFF Image " << w << " x " << h << " px" << endl;

		raster = (uint32*) _TIFFmalloc(npixels * sizeof (uint32));

		if (raster != nullptr) 
		{
			if (TIFFReadRGBAImageOriented(tif, w, h, raster, ORIENTATION_TOPLEFT, 0))
			{
				//this allocates the internal pixel buffer	
				pData = new PixelData(w, h, FORMAT_RGBA);


				for (size_t i = 0; i < npixels; i++)
				{
					uint32& packed = raster[i];
					

					float* pixel = pData->GetPixel(i);
							
					pixel[0] = TIFFGetR(packed);
					pixel[1] = TIFFGetG(packed);
					pixel[2] = TIFFGetB(packed);
					pixel[3] = TIFFGetA(packed);
					
					pixel[0] /= 255.f;
					pixel[1] /= 255.f;
					pixel[2] /= 255.f;
					pixel[3] /= 255.f;
				}



			}
			_TIFFfree(raster);
		}

		TIFFClose(tif);
	}


	return pData;
}
	void GLTextureBuffer::download(const PixelData &data)
	{
		if (data.getWidth() != getWidth() || data.getHeight() != getHeight() || data.getDepth() != getDepth())
		{
			LOGERR("Only download of entire buffer is supported by OpenGL.");
			return;
		}

		glBindTexture(mTarget, mTextureID);
		BS_CHECK_GL_ERROR();

		if(PixelUtil::isCompressed(data.getFormat()))
		{
			// Block-compressed data cannot be smaller than 4x4, and must be a multiple of 4
			const UINT32 actualWidth = Math::divideAndRoundUp(std::max(mWidth, 4U), 4U) * 4U;
			const UINT32 actualHeight = Math::divideAndRoundUp(std::max(mHeight, 4U), 4U) * 4U;

			const UINT32 expectedRowPitch = actualWidth;
			const UINT32 expectedSlicePitch = actualWidth * actualHeight;

			const bool isConsecutive = data.getRowPitch() == expectedRowPitch && data.getSlicePitch() == expectedSlicePitch;
			if (data.getFormat() != mFormat || !isConsecutive)
			{
				LOGERR("Compressed images must be consecutive, in the source format");
				return;
			}

			// Data must be consecutive and at beginning of buffer as PixelStorei not allowed
			// for compressed formate
			glGetCompressedTexImage(mFaceTarget, mLevel, data.getData());
			BS_CHECK_GL_ERROR();
		} 
		else
		{
			if (data.getWidth() != data.getRowPitch())
			{
				glPixelStorei(GL_PACK_ROW_LENGTH, data.getRowPitch());
				BS_CHECK_GL_ERROR();
			}

			if (data.getHeight()*data.getWidth() != data.getSlicePitch())
			{
				glPixelStorei(GL_PACK_IMAGE_HEIGHT, (data.getSlicePitch() / data.getWidth()));
				BS_CHECK_GL_ERROR();
			}

			if (data.getLeft() > 0 || data.getTop() > 0 || data.getFront() > 0)
			{
				glPixelStorei(
					GL_PACK_SKIP_PIXELS, 
					data.getLeft() + data.getRowPitch() * data.getTop() + data.getSlicePitch() * data.getFront());
				BS_CHECK_GL_ERROR();
			}

			if ((data.getWidth()*PixelUtil::getNumElemBytes(data.getFormat())) & 3)
			{
				glPixelStorei(GL_PACK_ALIGNMENT, 1);
				BS_CHECK_GL_ERROR();
			}

			// We can only get the entire texture
			glGetTexImage(mFaceTarget, mLevel, GLPixelUtil::getGLOriginFormat(data.getFormat()), 
				GLPixelUtil::getGLOriginDataType(data.getFormat()), data.getData());
			BS_CHECK_GL_ERROR();

			// Restore defaults
			glPixelStorei(GL_PACK_ROW_LENGTH, 0);
			BS_CHECK_GL_ERROR();

			glPixelStorei(GL_PACK_IMAGE_HEIGHT, 0);
			BS_CHECK_GL_ERROR();

			glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
			BS_CHECK_GL_ERROR();

			glPixelStorei(GL_PACK_ALIGNMENT, 4);
			BS_CHECK_GL_ERROR();
		}

		BS_INC_RENDER_STAT_CAT(ResRead, RenderStatObject_Texture);
	}
	void GLTextureBuffer::upload(const PixelData& data, const PixelVolume& dest)
	{
		if ((mUsage & TU_DEPTHSTENCIL) != 0)
		{
			LOGERR("Writing to depth stencil texture from CPU not supported.");
			return;
		}

		glBindTexture(mTarget, mTextureID);
		BS_CHECK_GL_ERROR();

		if(PixelUtil::isCompressed(data.getFormat()))
		{
			// Block-compressed data cannot be smaller than 4x4, and must be a multiple of 4
			const UINT32 actualWidth = Math::divideAndRoundUp(std::max(mWidth, 4U), 4U) * 4U;
			const UINT32 actualHeight = Math::divideAndRoundUp(std::max(mHeight, 4U), 4U) * 4U;

			const UINT32 expectedRowPitch = actualWidth;
			const UINT32 expectedSlicePitch = actualWidth * actualHeight;

			const bool isConsecutive = data.getRowPitch() == expectedRowPitch && data.getSlicePitch() == expectedSlicePitch;
			if (data.getFormat() != mFormat || !isConsecutive)
			{
				LOGERR("Compressed images must be consecutive, in the source format");
				return;
			}

			GLenum format = GLPixelUtil::getGLInternalFormat(mFormat, mHwGamma);
			switch(mTarget) 
			{
				case GL_TEXTURE_1D:
					glCompressedTexSubImage1D(GL_TEXTURE_1D, mLevel,
						dest.left,
						dest.getWidth(),
						format, data.getConsecutiveSize(),
						data.getData());
					BS_CHECK_GL_ERROR();
					break;
				case GL_TEXTURE_2D:
				case GL_TEXTURE_CUBE_MAP:
					glCompressedTexSubImage2D(mFaceTarget, mLevel,
						dest.left, dest.top,
						dest.getWidth(), dest.getHeight(),
						format, data.getConsecutiveSize(),
						data.getData());
					BS_CHECK_GL_ERROR();
					break;
				case GL_TEXTURE_3D:
					glCompressedTexSubImage3D(GL_TEXTURE_3D, mLevel,
						dest.left, dest.top, dest.front,
						dest.getWidth(), dest.getHeight(), dest.getDepth(),
						format, data.getConsecutiveSize(),
						data.getData());
					BS_CHECK_GL_ERROR();
					break;
				default:
					break;
			}
		
		} 
		else
		{
			if (data.getWidth() != data.getRowPitch())
			{
				glPixelStorei(GL_UNPACK_ROW_LENGTH, data.getRowPitch());
				BS_CHECK_GL_ERROR();
			}

			if (data.getHeight()*data.getWidth() != data.getSlicePitch())
			{
				glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, (data.getSlicePitch() / data.getWidth()));
				BS_CHECK_GL_ERROR();
			}

			if (data.getLeft() > 0 || data.getTop() > 0 || data.getFront() > 0)
			{
				glPixelStorei(
					GL_UNPACK_SKIP_PIXELS, 
					data.getLeft() + data.getRowPitch() * data.getTop() + data.getSlicePitch() * data.getFront());
				BS_CHECK_GL_ERROR();
			}

			if ((data.getWidth()*PixelUtil::getNumElemBytes(data.getFormat())) & 3)
			{
				glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
				BS_CHECK_GL_ERROR();
			}

			switch(mTarget) {
				case GL_TEXTURE_1D:
					glTexSubImage1D(GL_TEXTURE_1D, mLevel, 
						dest.left,
						dest.getWidth(),
						GLPixelUtil::getGLOriginFormat(data.getFormat()), GLPixelUtil::getGLOriginDataType(data.getFormat()),
						data.getData());
					BS_CHECK_GL_ERROR();
					break;
				case GL_TEXTURE_2D:
				case GL_TEXTURE_CUBE_MAP:
					glTexSubImage2D(mFaceTarget, mLevel, 
						dest.left, dest.top, 
						dest.getWidth(), dest.getHeight(),
						GLPixelUtil::getGLOriginFormat(data.getFormat()), GLPixelUtil::getGLOriginDataType(data.getFormat()),
						data.getData());
					BS_CHECK_GL_ERROR();
					break;
				case GL_TEXTURE_2D_ARRAY:
				case GL_TEXTURE_3D:
					glTexSubImage3D(
						mTarget, mLevel,
						dest.left, dest.top, dest.front,
						dest.getWidth(), dest.getHeight(), dest.getDepth(),
						GLPixelUtil::getGLOriginFormat(data.getFormat()), GLPixelUtil::getGLOriginDataType(data.getFormat()),
						data.getData());
					BS_CHECK_GL_ERROR();
					break;
			}	
		}

		// Restore defaults
		glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
		BS_CHECK_GL_ERROR();

		glPixelStorei(GL_UNPACK_IMAGE_HEIGHT, 0);
		BS_CHECK_GL_ERROR();

		glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
		BS_CHECK_GL_ERROR();

		glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
		BS_CHECK_GL_ERROR();

		BS_INC_RENDER_STAT_CAT(ResWrite, RenderStatObject_Texture);
	}
Exemple #14
0
	void D3D9Device::copyContentsToMemory(const D3D9RenderWindowCore* renderWindow,
		PixelData &dst, RenderTargetCore::FrameBuffer buffer)
	{
		const RenderWindowProperties& props = renderWindow->getProperties();

		RenderWindowToResorucesIterator it = getRenderWindowIterator(renderWindow);
		RenderWindowResources* resources = it->second;
		bool swapChain = isSwapChainWindow(renderWindow);

		if ((dst.getLeft() < 0) || (dst.getRight() > props.getWidth()) ||
			(dst.getTop() < 0) || (dst.getBottom() > props.getHeight()) ||
			(dst.getFront() != 0) || (dst.getBack() != 1))
		{
			BS_EXCEPT(InvalidParametersException, "Invalid box.");
		}

		HRESULT hr;
		IDirect3DSurface9* pSurf = NULL;
		IDirect3DSurface9* pTempSurf = NULL;
		D3DSURFACE_DESC desc;
		D3DLOCKED_RECT lockedRect;


		if (buffer == RenderTargetCore::FB_AUTO)
		{
			buffer = RenderTargetCore::FB_FRONT;
		}

		if (buffer == RenderTargetCore::FB_FRONT)
		{
			D3DDISPLAYMODE dm;

			if (FAILED(hr = mpDevice->GetDisplayMode(0, &dm)))
			{
				BS_EXCEPT(RenderingAPIException, "Can't get display mode: TODO PORT NO ERROR"); // TODO PORT - Translate HR to error
			}

			desc.Width = dm.Width;
			desc.Height = dm.Height;
			desc.Format = D3DFMT_A8R8G8B8;
			if (FAILED(hr = mpDevice->CreateOffscreenPlainSurface(desc.Width, desc.Height,
				desc.Format,
				D3DPOOL_SYSTEMMEM,
				&pTempSurf,
				0)))
			{
				BS_EXCEPT(RenderingAPIException, "Can't create offscreen buffer: TODO PORT NO ERROR"); // TODO PORT - Translate HR to error
			}

			if (FAILED(hr = swapChain ? resources->swapChain->GetFrontBufferData(pTempSurf) :
				mpDevice->GetFrontBufferData(0, pTempSurf)))
			{
				SAFE_RELEASE(pTempSurf);
				BS_EXCEPT(RenderingAPIException, "Can't get front buffer: TODO PORT NO ERROR"); // TODO PORT - Translate HR to error
			}

			if (props.isFullScreen())
			{
				if ((dst.getLeft() == 0) && (dst.getRight() == props.getWidth()) && (dst.getTop() == 0) && (dst.getBottom() == props.getHeight()))
				{
					hr = pTempSurf->LockRect(&lockedRect, 0, D3DLOCK_READONLY | D3DLOCK_NOSYSLOCK);
				}
				else
				{
					RECT rect;

					rect.left = static_cast<LONG>(dst.getLeft());
					rect.right = static_cast<LONG>(dst.getRight());
					rect.top = static_cast<LONG>(dst.getTop());
					rect.bottom = static_cast<LONG>(dst.getBottom());

					hr = pTempSurf->LockRect(&lockedRect, &rect, D3DLOCK_READONLY | D3DLOCK_NOSYSLOCK);
				}
				if (FAILED(hr))
				{
					SAFE_RELEASE(pTempSurf);
					BS_EXCEPT(RenderingAPIException, "Can't lock rect:  TODO PORT NO ERROR"); // TODO PORT - Translate HR to error
				} 
			}
			else
			{
				RECT srcRect;
				//GetClientRect(mHWnd, &srcRect);
				srcRect.left = static_cast<LONG>(dst.getLeft());
				srcRect.top = static_cast<LONG>(dst.getTop());
				srcRect.right = static_cast<LONG>(dst.getRight());
				srcRect.bottom = static_cast<LONG>(dst.getBottom());
				POINT point;
				point.x = srcRect.left;
				point.y = srcRect.top;
				ClientToScreen(renderWindow->_getWindowHandle(), &point);
				srcRect.top = point.y;
				srcRect.left = point.x;
				srcRect.bottom += point.y;
				srcRect.right += point.x;

				desc.Width = srcRect.right - srcRect.left;
				desc.Height = srcRect.bottom - srcRect.top;

				if (FAILED(hr = pTempSurf->LockRect(&lockedRect, &srcRect, D3DLOCK_READONLY | D3DLOCK_NOSYSLOCK)))
				{
					SAFE_RELEASE(pTempSurf);
					BS_EXCEPT(RenderingAPIException, "Can't lock rect:  TODO PORT NO ERROR"); // TODO PORT - Translate HR to error
				} 
			}
		}
		else
		{
			SAFE_RELEASE(pSurf);
			if(FAILED(hr = swapChain? resources->swapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &pSurf) :
				mpDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &pSurf)))
			{
				BS_EXCEPT(RenderingAPIException, "Can't get back buffer:  TODO PORT NO ERROR"); // TODO PORT - Translate HR to error
			}

			if(FAILED(hr = pSurf->GetDesc(&desc)))
			{
				BS_EXCEPT(RenderingAPIException, "Can't get description:  TODO PORT NO ERROR"); // TODO PORT - Translate HR to error
			}

			if (FAILED(hr = mpDevice->CreateOffscreenPlainSurface(desc.Width, desc.Height,
				desc.Format,
				D3DPOOL_SYSTEMMEM,
				&pTempSurf,
				0)))
			{
				BS_EXCEPT(RenderingAPIException, "Can't create offscreen surface:  TODO PORT NO ERROR"); // TODO PORT - Translate HR to error
			}

			if (desc.MultiSampleType == D3DMULTISAMPLE_NONE)
			{
				if (FAILED(hr = mpDevice->GetRenderTargetData(pSurf, pTempSurf)))
				{
					SAFE_RELEASE(pTempSurf);
					BS_EXCEPT(RenderingAPIException, "Can't get render target data:  TODO PORT NO ERROR"); // TODO PORT - Translate HR to error
				}
			}
			else
			{
				IDirect3DSurface9* pStretchSurf = 0;

				if (FAILED(hr = mpDevice->CreateRenderTarget(desc.Width, desc.Height,
					desc.Format,
					D3DMULTISAMPLE_NONE,
					0,
					false,
					&pStretchSurf,
					0)))
				{
					SAFE_RELEASE(pTempSurf);
					BS_EXCEPT(RenderingAPIException, "Can't create render target:  TODO PORT NO ERROR"); // TODO PORT - Translate HR to error
				}

				if (FAILED(hr = mpDevice->StretchRect(pSurf, 0, pStretchSurf, 0, D3DTEXF_NONE)))
				{
					SAFE_RELEASE(pTempSurf);
					SAFE_RELEASE(pStretchSurf);
					BS_EXCEPT(RenderingAPIException, "Can't stretch rect:  TODO PORT NO ERROR"); // TODO PORT - Translate HR to error
				}
				if (FAILED(hr = mpDevice->GetRenderTargetData(pStretchSurf, pTempSurf)))
				{
					SAFE_RELEASE(pTempSurf);
					SAFE_RELEASE(pStretchSurf);
					BS_EXCEPT(RenderingAPIException, "Can't get render target data:  TODO PORT NO ERROR"); // TODO PORT - Translate HR to error
				}
				SAFE_RELEASE(pStretchSurf);
			}

			if ((dst.getLeft() == 0) && (dst.getRight() == props.getWidth()) && (dst.getTop() == 0) && (dst.getBottom() == props.getHeight()))
			{
				hr = pTempSurf->LockRect(&lockedRect, 0, D3DLOCK_READONLY | D3DLOCK_NOSYSLOCK);
			}
			else
			{
				RECT rect;

				rect.left = static_cast<LONG>(dst.getLeft());
				rect.right = static_cast<LONG>(dst.getRight());
				rect.top = static_cast<LONG>(dst.getTop());
				rect.bottom = static_cast<LONG>(dst.getBottom());

				hr = pTempSurf->LockRect(&lockedRect, &rect, D3DLOCK_READONLY | D3DLOCK_NOSYSLOCK);
			}
			if (FAILED(hr))
			{
				SAFE_RELEASE(pTempSurf);
				BS_EXCEPT(RenderingAPIException, "Can't lock rect:  TODO PORT NO ERROR"); // TODO PORT - Translate HR to error
			}
		}

		PixelFormat format = BansheeEngine::D3D9Mappings::_getPF(desc.Format);

		if (format == PF_UNKNOWN)
		{
			SAFE_RELEASE(pTempSurf);
			BS_EXCEPT(RenderingAPIException, "Unsupported format");
		}

		PixelData src(dst.getWidth(), dst.getHeight(), 1, format);
		src.setExternalBuffer((UINT8*)lockedRect.pBits);
		src.setRowPitch(lockedRect.Pitch / PixelUtil::getNumElemBytes(format));
		src.setSlicePitch(desc.Height * src.getRowPitch());

		PixelUtil::bulkPixelConversion(src, dst);

		SAFE_RELEASE(pTempSurf);
		SAFE_RELEASE(pSurf);
	}