TexturePitches StreamingTexture::GetPitches(SubResource subRes) const { auto arrayIndex = subRes >> 16u, mip = subRes & 0xffffu; auto* image = _image.GetImage(mip, arrayIndex, 0); if (image) return TexturePitches(unsigned(image->rowPitch), unsigned(image->slicePitch)); return TexturePitches(); }
size_t StreamingTexture::GetDataSize(SubResource subRes) const { auto arrayIndex = subRes >> 16u, mip = subRes & 0xffffu; auto* image = _image.GetImage(mip, arrayIndex, 0); if (image) return image->slicePitch; return 0; }
void* StreamingTexture::GetData(SubResource subRes) { auto arrayIndex = subRes >> 16u, mip = subRes & 0xffffu; auto* image = _image.GetImage(mip, arrayIndex, 0); if (image) return image->pixels; return nullptr; }
void convertTexture(const std::wstring& source, const std::wstring& dest, TextureFormat sourceFormat, TextureFormat destFormat, bool alpha){ DirectX::ScratchImage srcImg; DirectX::TexMetadata srcMetadata; switch (sourceFormat) { case TextureFormat::Dds: DirectX::LoadFromDDSFile(source.c_str(), 0, &srcMetadata, srcImg); break; case TextureFormat::Tga: DirectX::LoadFromTGAFile(source.c_str(), &srcMetadata, srcImg); break; default: DirectX::LoadFromWICFile(source.c_str(), 0, &srcMetadata, srcImg); break; } switch (destFormat) { case TextureFormat::Jpg: DirectX::SaveToWICFile(*srcImg.GetImage(0, 0, 0), 0, DirectX::GetWICCodec(DirectX::WICCodecs::WIC_CODEC_JPEG), dest.c_str()); break; case TextureFormat::Png: DirectX::SaveToWICFile(*srcImg.GetImage(0, 0, 0), 0, DirectX::GetWICCodec(DirectX::WICCodecs::WIC_CODEC_PNG), dest.c_str()); break; case TextureFormat::Dds: { DirectX::ScratchImage imgWithMipMaps; auto hr = DirectX::GenerateMipMaps(*srcImg.GetImage(0, 0, 0), DirectX::TEX_FILTER_FLAGS::TEX_FILTER_CUBIC, 0, imgWithMipMaps); DirectX::ScratchImage imgInBC2; //hr = DirectX::Convert(imgWithMipMaps.GetImages(), imgWithMipMaps.GetImageCount(), srcMetadata, DXGI_FORMAT_BC2_UNORM, DirectX::TEX_FILTER_FLAGS::TEX_FILTER_CUBIC, 0.5f, imgInBC2); hr = DirectX::Compress(imgWithMipMaps.GetImages(), imgWithMipMaps.GetImageCount(), imgWithMipMaps.GetMetadata(), alpha ? DXGI_FORMAT_BC3_UNORM : DXGI_FORMAT_BC1_UNORM, DirectX::TEX_COMPRESS_FLAGS::TEX_COMPRESS_DEFAULT | DirectX::TEX_COMPRESS_PARALLEL, 0.5f, imgInBC2); hr = DirectX::SaveToDDSFile(imgInBC2.GetImages(), imgInBC2.GetImageCount(), imgInBC2.GetMetadata(), 0, dest.c_str()); } break; default: break; } }
// ------------------------------------------------------------------------------------------------- bool TextureFactory::LoadResource(Resource* resource, const WCHAR * filename) { if(!FileUtils::Exists(filename)) return false; HRESULT hr = S_OK; DirectX::TexMetadata metadata; DirectX::ScratchImage sourceScratch; hr = DXUtil::LoadTexture(filename,&metadata,sourceScratch); if (Logger::IsFailureLog(hr, L"LoadTexture")) { return false; } ID3D11Texture2D* dxtex = NULL; std::wstring ext = FileUtils::GetExtensionLower(filename); // generate full mip chains for non dds file. if(ext != L".dds") { const DirectX::Image* srcImage = sourceScratch.GetImage(0, 0, 0); DirectX::ScratchImage mipScratch; hr = DirectX::GenerateMipMaps(*srcImage, DirectX::TEX_FILTER_LINEAR, 0, mipScratch, false); if (Logger::IsFailureLog(hr, L"DirectX::GenerateMipMaps")) return false; hr = DirectX::CreateTexture(m_device, mipScratch.GetImages(), mipScratch.GetImageCount(), mipScratch.GetMetadata(), (ID3D11Resource**)&dxtex); } else { hr = DirectX::CreateTexture(m_device, sourceScratch.GetImages(), sourceScratch.GetImageCount(), metadata,(ID3D11Resource**)&dxtex); } if (Logger::IsFailureLog(hr, L"DirectX::CreateTexture")) return false; ID3D11ShaderResourceView* texview = CreateTextureView(m_device, dxtex); if(!dxtex) return false; Texture* tex = (Texture*)resource; tex->Set(dxtex,texview); return true; }
LVEDRENDERINGENGINE_API bool __stdcall LvEd_SaveRenderSurfaceToFile(ObjectGUID renderSurfaceId, wchar_t *fileName) { ErrorHandler::ClearError(); if(fileName == NULL || wcslen(fileName) == 0 ) { ErrorHandler::SetError(ErrorType::UnknownError, L"%s: filename is empty", __WFUNCTION__); return false; } DirectX::ScratchImage scratchImg; RenderSurface* renderSurface = reinterpret_cast<RenderSurface*>(renderSurfaceId); HRESULT hr = CaptureTexture(gD3D11->GetDevice(),::gD3D11->GetImmediateContext(), (ID3D11Resource*)renderSurface->GetColorBuffer()->GetTex(),scratchImg); if(FAILED(hr)) return false; const DirectX::Image* img = scratchImg.GetImage(0,0,0); ImageData imgdata; imgdata.InitFrom(img); imgdata.SaveToFile(fileName); return SUCCEEDED(hr); }
inline void images_to_gv(std::string output_path, std::vector<std::string> imagePaths, float fps, int *done_frames, bool hasAlpha, std::shared_ptr<Dx11> dx, ofxCoroutine::Yield &yield) { if (imagePaths.empty()) { return; } // memory uint32_t _width = 0; uint32_t _height = 0; float _fps = fps; uint32_t _bufferSize = 0; std::vector<uint8_t> _lz4CompressBuffer; std::vector<Lz4Block> _lz4blocks; std::unique_ptr<GpuVideoIO> _io; int _index = 0; int width; int height; ofPixels img; ofLoadImage(img, imagePaths[0]); width = img.getWidth(); height = img.getHeight(); _width = width; _height = height; int blockcount = ((_width + 3) / 4) * ((_height + 3) / 4); int blocksize = 16; _bufferSize = blockcount * blocksize; // 書き出し開始 _io = std::unique_ptr<GpuVideoIO>(new GpuVideoIO(output_path.c_str(), "wb")); // ヘッダー情報書き出し #define W(v) if(_io->write(&v, sizeof(v)) != sizeof(v)) { assert(0); } W(_width); W(_height); uint32_t frameCount = (uint32_t)imagePaths.size(); W(frameCount); W(_fps); uint32_t videoFmt = GPU_COMPRESS_BC7; W(videoFmt); W(_bufferSize); #undef W int compressBound = LZ4_compressBound(_bufferSize); _lz4CompressBuffer.resize(compressBound); for (int i = 0; i < imagePaths.size(); ++i) { DirectX::TexMetadata metadata; DirectX::ScratchImage image; auto imgPath = ofToDataPath(imagePaths[i]); HRESULT hr = DirectX::LoadFromWICFile(to_wstring(imgPath).c_str(), 0, &metadata, image); if (FAILED(hr)) { abort(); } DWORD flags = DirectX::TEX_COMPRESS_DEFAULT; flags |= DirectX::TEX_COMPRESS_PARALLEL; flags |= DirectX::TEX_COMPRESS_BC7_USE_3SUBSETS; flags |= DirectX::TEX_COMPRESS_UNIFORM; flags |= DirectX::TEX_COMPRESS_SRGB_IN; flags |= DirectX::TEX_COMPRESS_SRGB_OUT; float alphaWeight = hasAlpha ? 1.0f : 0.0f; DirectX::ScratchImage cImage; hr = DirectX::Compress(dx11->device(), *image.GetImage(0, 0, 0), DXGI_FORMAT_BC7_UNORM_SRGB, flags, alphaWeight, cImage); int src = cImage.GetPixelsSize(); if (_bufferSize != cImage.GetPixelsSize()) { abort(); } int compressed = LZ4_compress_HC((char *)cImage.GetPixels(), (char *)_lz4CompressBuffer.data(), _bufferSize, compressBound, LZ4HC_CLEVEL_MAX); // 住所を記録しつつ uint64_t head = _lz4blocks.empty() ? kRawMemoryAt : (_lz4blocks[_lz4blocks.size() - 1].address + _lz4blocks[_lz4blocks.size() - 1].size); Lz4Block lz4block; lz4block.address = head; lz4block.size = compressed; _lz4blocks.push_back(lz4block); // 書き込み if (_io->write(_lz4CompressBuffer.data(), compressed) != compressed) { assert(0); } (*done_frames)++; yield(); } // 最後に住所を記録 uint64_t size = _lz4blocks.size() * sizeof(Lz4Block); if (_io->write(_lz4blocks.data(), size) != size) { abort(); } // ファイルをクローズ _io.reset(); //for (;;) { // if (_index < imagePaths.size()) { // auto compress = [imagePaths, _width, _height, _squishFlag](int index, uint8_t *dst) { // std::string src = imagePaths[index]; // ofPixels img; // ofLoadImage(img, src); // img.setImageType(OF_IMAGE_COLOR_ALPHA); // squish::CompressImage(img.getData(), _width, _height, dst, _squishFlag); // }; // const int kBatchCount = 32; // int workCount = std::min((int)imagePaths.size() - _index, kBatchCount); // uint32_t lz4sizes[kBatchCount]; // int compressBound = LZ4_compressBound(_bufferSize); // _gpuCompressBuffer.resize(workCount * _bufferSize); // _lz4CompressBuffer.resize(workCount * compressBound); // tbb::parallel_for(tbb::blocked_range<int>(0, workCount, 1), [compress, _index, _bufferSize, compressBound, &lz4sizes, &_gpuCompressBuffer, &_lz4CompressBuffer, &done_frames](const tbb::blocked_range< int >& range) { // for (int i = range.begin(); i != range.end(); i++) { // compress(_index + i, _gpuCompressBuffer.data() + i * _bufferSize); // lz4sizes[i] = LZ4_compress_HC((char *)_gpuCompressBuffer.data() + i * _bufferSize, // (char *)_lz4CompressBuffer.data() + i * compressBound, // _bufferSize, compressBound, 16); // done_frames++; // } // }); // uint64_t head = _lz4blocks.empty() ? kRawMemoryAt : (_lz4blocks[_lz4blocks.size() - 1].address + _lz4blocks[_lz4blocks.size() - 1].size); // for (int i = 0; i < workCount; i++) { // // 住所を記録しつつ // Lz4Block lz4block; // lz4block.address = head; // lz4block.size = lz4sizes[i]; // head += lz4block.size; // _lz4blocks.push_back(lz4block); // // 書き込み // if (_io->write(_lz4CompressBuffer.data() + i * compressBound, lz4sizes[i]) != lz4sizes[i]) { // assert(0); // } // } // _index += workCount; // // 強制離脱 // if (interrupt) { // _io.reset(); // ::remove(output_path.c_str()); // break; // } // } // else { // // 最後に住所を記録 // uint64_t size = _lz4blocks.size() * sizeof(Lz4Block); // if (_io->write(_lz4blocks.data(), size) != size) { // assert(0); // } // // ファイルをクローズ // _io.reset(); // // 終了 // break; // } //} }