Created
March 20, 2024 01:00
-
-
Save meshula/36b8e310f93bb68a854f0eebf4391222 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 1. demonstrate writing OpenEXR using Hio, then reading the file back in. | |
// 2. read a two channel exr file using Hio, then creata HioTexture with it | |
do { | |
float* data4 = (float*) malloc(w*h*4); | |
float* amplify = data4; | |
for (int i = 0; i < h; ++i) { | |
for (int j = 0; j < w; ++j) { | |
if (i&1) { | |
amplify[0] = 0.f; | |
amplify[1] = 0.f; | |
amplify[2] = 0.f; | |
} | |
else { | |
amplify[0] = 1.f; | |
amplify[1] = 1.f; | |
amplify[2] = 1.f; | |
} | |
amplify[3] = 1.f; | |
amplify += 4; | |
} | |
} | |
foo = data; | |
for (int i = 0; i < h; ++i) { | |
for (int j = 0; j < w; ++j) { | |
foo[j] /= 256.f; | |
} | |
foo += w; | |
} | |
std::cerr << "Writing EXR.\n"; | |
pxr::HioImage::StorageSpec storage; | |
storage.width = w; | |
storage.height = h; | |
storage.format = pxr::HioFormatFloat32; | |
storage.flipped = 0; | |
storage.data = data; | |
std::string filename("/var/tmp/output.exr"); | |
pxr::HioImageSharedPtr image = pxr::HioImage::OpenForWriting(filename); | |
image->Write(storage); | |
std::cerr << "Reading EXR.\n"; | |
pxr::HioImageSharedPtr image2 = pxr::HioImage::OpenForReading(filename); | |
pxr::HioImage::StorageSpec storage2; | |
storage2.width = image2->GetWidth(); | |
storage2.height = image2->GetHeight(); | |
storage2.format = pxr::HioFormatFloat32; | |
storage2.flipped = 0; | |
storage2.data = (float*)malloc(sizeof(float) * storage2.width * storage2.height); | |
std::cerr << storage2.width << " " << storage2.height << "\n"; | |
image2->Read(storage2); | |
std::cerr << storage2.width << " " << storage2.height << "\n"; | |
float *data2 = (float*)storage2.data; | |
for (int row=0; row < h; row++) { | |
int bad=0; | |
for (int x=0; x < w; x++) { | |
int i = row*h + x; | |
float diff = fabs(data2[i] - data[i]); | |
if (diff > 0.001) { | |
bad++; | |
} | |
} | |
if (bad > 0) { | |
//std::cerr << "row " << row << " has " << bad << " bad pixels.\n"; | |
} | |
} | |
} while (false); | |
2. | |
std::string path = "RG32F.exr"; | |
std::string filename = resource_path + path; | |
HioImageSharedPtr _image; | |
bool canReadExr = HioImage::IsSupportedImageFile(filename); | |
std::unique_ptr<char[]> imageData; | |
HioImage::StorageSpec _spec; | |
if (canReadExr) { | |
_image = HioImage::OpenForReading(filename, | |
0, // int subimage, | |
0, // int mip, | |
HioImage::SourceColorSpace::Auto, | |
false); //bool suppressErrors) | |
} | |
if (_image) { | |
std::cout << "filename: " << _image->GetFilename() << "\n"; | |
std::cout << " dimensions: " << _image->GetWidth() << ", " << _image->GetHeight() << "\n"; | |
switch (_image->GetFormat()) { | |
case HioFormatFloat16: | |
std::cout << " format: HioFormatFloat16\n"; break; | |
case HioFormatFloat16Vec2: | |
std::cout << " format: HioFormatFloat16Vec2\n"; break; | |
case HioFormatFloat16Vec3: | |
std::cout << " format: HioFormatFloat16Vec3\n"; break; | |
case HioFormatFloat16Vec4: | |
std::cout << " format: HioFormatFloat16Vec4\n"; break; | |
case HioFormatFloat32: | |
std::cout << " format: HioFormatFloat32\n"; break; | |
case HioFormatFloat32Vec2: | |
std::cout << " format: HioFormatFloat32Vec2\n"; break; | |
case HioFormatFloat32Vec3: | |
std::cout << " format: HioFormatFloat32Vec3\n"; break; | |
case HioFormatFloat32Vec4: | |
std::cout << " format: HioFormatFloat32Vec4\n"; break; | |
case HioFormatUNorm8srgb: | |
std::cout << " format: HioFormatUNorm8srgb\n"; break; | |
case HioFormatUNorm8Vec2srgb: | |
std::cout << " format: HioFormatUNorm8Vec2srgb\n"; break; | |
case HioFormatUNorm8Vec3srgb: | |
std::cout << " format: HioFormatUNorm8Vec3srgb\n"; break; | |
case HioFormatUNorm8Vec4srgb: | |
std::cout << " format: HioFormatUNorm8Vec4srgb\n"; break; | |
default: | |
std::cout << " format: " << _image->GetFormat() << "\n"; break; | |
} | |
std::cout << " bytes per pixel: " << _image->GetBytesPerPixel() << "\n"; | |
std::cout << " mips: " << _image->GetNumMipLevels() << "\n"; | |
std::cout << (_image->IsColorSpaceSRGB() ? " srgb pixels\n" : " linear pixels\n"); | |
const bool premultiplyAlpha = false; | |
auto hgiFormat = HdStTextureUtils::GetHgiFormat( | |
_image->GetFormat(), | |
premultiplyAlpha); | |
const int layerCount = 1; | |
const GfVec3i dimensions((int)_image->GetWidth(), (int)_image->GetHeight(), 1); | |
const std::vector<HgiMipInfo> mipInfos = | |
HgiGetMipInfos(hgiFormat, dimensions, layerCount); | |
int cropTop = 0; | |
int cropBottom = 0; | |
float scale = 1.f; | |
_spec.width = (int)(_image->GetWidth() * scale); | |
_spec.height = (int)((_image->GetHeight() - cropTop - cropBottom) * scale); | |
_spec.format = HioFormatFloat32Vec4; // _image->GetFormat(); | |
_spec.flipped = false; | |
size_t bufsize = _spec.width * _spec.height * HioGetDataSizeOfType(_spec.format) * HioGetComponentCount(_spec.format); | |
imageData.reset(new char[bufsize]); | |
_spec.data = imageData.get(); | |
if (_image->ReadCropped(cropTop, cropBottom, 0, 0, _spec)) { | |
// successfully read the image! | |
if (_spec.format == HioFormatUNorm8Vec3srgb) { | |
_spec.format = HioFormatUNorm8Vec4srgb; // force reading as rgba because MTL knows R, RG, RGBA, but not RGB | |
bufsize = _spec.width * _spec.height * HioGetDataSizeOfType(_spec.format) * HioGetComponentCount(_spec.format); | |
char* newData = new char[bufsize]; | |
uint8_t* dst = (uint8_t*) newData; | |
uint8_t* src = (uint8_t*) _spec.data; | |
for (int i = 0; i < _spec.width * _spec.height * 3; i += 3) { | |
*dst++ = src[i]; | |
*dst++ = src[i+1]; | |
*dst++ = src[i+2]; | |
*dst++ = 255; | |
} | |
imageData.reset(newData); | |
_spec.data = imageData.get(); | |
} | |
} | |
const char* output = "/var/tmp/test_exr.exr"; | |
auto writeImage = HioImage::OpenForWriting(output); | |
writeImage->Write(_spec); | |
//------------------------------------------------------------------------- | |
// Create a hydra texture from the OpenEXR image | |
//------------------------------------------------------------------------- | |
id<MTLTexture> _metalTexture = nil; | |
if (_image) { | |
HgiTextureDesc textureDesc; | |
textureDesc.debugName = "OpenEXRTexture"; | |
textureDesc.usage = HgiTextureUsageBitsShaderRead; | |
textureDesc.format = HdStTextureUtils::GetHgiFormat(_spec.format, true); | |
textureDesc.type = HgiTextureType2D; | |
textureDesc.dimensions = GfVec3i(_spec.width, _spec.height, 1); | |
textureDesc.layerCount = 1; | |
textureDesc.mipLevels = 1; | |
textureDesc.pixelsByteSize = HioGetDataSizeOfType(_spec.format) * HioGetComponentCount(_spec.format); | |
textureDesc.initialData = _spec.data; | |
HgiTextureHandle _gpuTexture = _harness->hgi->CreateTexture(textureDesc); | |
HgiMetalTexture* hgiMetalTexture = static_cast<HgiMetalTexture*>(_gpuTexture.Get()); | |
if (hgiMetalTexture) { | |
_metalTexture = hgiMetalTexture->GetTextureId(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment