Skip to content

Instantly share code, notes, and snippets.

@meshula
Created March 20, 2024 01:00
Show Gist options
  • Save meshula/36b8e310f93bb68a854f0eebf4391222 to your computer and use it in GitHub Desktop.
Save meshula/36b8e310f93bb68a854f0eebf4391222 to your computer and use it in GitHub Desktop.
// 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