//シェーダリソースビューの作成 ComPtr<ID3D11ShaderResourceView> GameObject::CreateShaderResView(const wstring& TextureFileName){ //テクスチャ作成 DirectX::TexMetadata metadata; DirectX::ScratchImage image; ThrowIfFailed( DirectX::LoadFromWICFile(TextureFileName.c_str(), 0, &metadata, image), L"テクスチャの読み込みに失敗しました", TextureFileName, L"GameObject::CreateShaderResView()" ); //デバイスとコンテキストインターフェイスの取得 //デバイスの取得 auto Dev = App::GetApp()->GetDeviceResources(); ID3D11Device* pDx11Device = Dev->GetD3DDevice(); ID3D11DeviceContext* pID3D11DeviceContex = Dev->GetD3DDeviceContext(); //ミューテックス std::mutex Mutex; ComPtr<ID3D11ShaderResourceView> ResView; Util::DemandCreate(ResView, Mutex, [&](ID3D11ShaderResourceView** pResult) -> HRESULT { // 画像からシェーダリソースViewの作成 return ThrowIfFailed(CreateShaderResourceView(pDx11Device, image.GetImages(), image.GetImageCount(), metadata, pResult), L"シェーダーリソースビューを作成できません", L"if( FAILED( CreateShaderResourceView() ) )", L"Texture::Impl::Impl()" ); }); return ResView; }
HRESULT GraphicsManager::CreateShaderResourceViewFromFile(ID3D11Device *device, ID3D11DeviceContext *dc, const wchar_t *filename, ID3D11ShaderResourceView **resourceView) { HRESULT result = E_FAIL; #ifdef OLD_DX_SDK //If not, then we have to load it! D3DX11_IMAGE_LOAD_INFO imageInfo; result = D3DX11CreateShaderResourceViewFromFile(device, filename, &imageInfo, NULL, resourceView, NULL); #else ID3D11Texture2D *tex; result = CreateWICTextureFromFile(device, dc, filename, (ID3D11Resource **)&tex, resourceView); if (FAILED(result)) { DirectX::TexMetadata md; DirectX::ScratchImage img; result = LoadFromDDSFile(filename, 0, &md, img); result = CreateShaderResourceView(device, img.GetImages(), img.GetImageCount(), md, resourceView); } #endif if (FAILED(result)) { printf("There was a problem loading \"%s\"\n", filename); } return result; }
static ff::SpriteType UpdateSpriteType(const OptimizedSpriteInfo &sprite, const DirectX::ScratchImage &alphaTexture) { const ff::SpriteData &data = sprite._sprite->GetSpriteData(); if (data._type != ff::SpriteType::Unknown || alphaTexture.GetImageCount() == 0) { return data._type; } ff::RectInt rect = sprite._destRect; ff::SpriteType newType = ff::SpriteType::Opaque; const DirectX::Image &image = *alphaTexture.GetImages(); for (int y = rect.top; y < rect.bottom && newType == ff::SpriteType::Opaque; y++) { const uint8_t *alpha = image.pixels + y * image.rowPitch + rect.left; for (int x = rect.left; x < rect.right; x++, alpha++) { if (*alpha && *alpha != 0xFF) { newType = ff::SpriteType::Transparent; break; } } } return newType; }
static bool ConvertOptimizedTextures( DXGI_FORMAT format, size_t mipMapLevels, ff::Vector<ff::ComPtr<ff::IGraphTexture>> &textures, ff::Vector<ff::ComPtr<ff::IGraphTexture>> &finalTextures, ff::Vector<std::shared_ptr<DirectX::ScratchImage>> &alphaTextures) { for (size_t i = 0; i < textures.Size(); i++) { ff::IGraphTexture *texture = textures[i]; ff::IGraphDevice *device = texture->GetDevice(); ff::ComPtr<ff::IGraphTexture> newTexture; assertRetVal(texture->Convert(format, mipMapLevels, &newTexture), false); finalTextures.Push(newTexture); DirectX::ScratchImage scratch; assertHrRetVal(DirectX::CaptureTexture(device->Get3d(), device->GetContext(), texture->GetTexture(), scratch), false); std::shared_ptr<DirectX::ScratchImage> alphaScratch = std::make_shared<DirectX::ScratchImage>(); assertHrRetVal(DirectX::Convert(scratch.GetImages(), 1, scratch.GetMetadata(), DXGI_FORMAT_A8_UNORM, DirectX::TEX_FILTER_DEFAULT, 0, *alphaScratch), false); alphaTextures.Push(alphaScratch); } return true; }
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 SaveTextureToDDSFile(ID3D11Resource* tex, LPCWSTR filename) { // from http://directxtex.codeplex.com/wikipage?title=CaptureTexture DirectX::ScratchImage image; HRESULT hr; hr = DirectX::CaptureTexture(d3dDevice, immediateContext, tex, image); if (FAILED(hr)) { return; } hr = DirectX::SaveToDDSFile(image.GetImages(), image.GetImageCount(), image.GetMetadata(), DDS_FLAGS_NONE, filename); if (FAILED(hr)) { return; } }
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); }
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; }
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; // } //} }