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; }
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); }
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(); } }
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); }
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); }