bool fcExrContext::addLayerTexture(void *tex, fcTextureFormat fmt, int channel, const char *name, bool flipY) { std::string *raw_frame = nullptr; // フレームバッファの内容取得 if (tex == m_tex_prev) { // 前回取得した結果を使い回す raw_frame = &m_exr->raw_frames.back(); } else { m_tex_prev = tex; m_exr->raw_frames.push_back(std::string()); raw_frame = &m_exr->raw_frames.back(); raw_frame->resize(m_exr->width * m_exr->height * fcGetPixelSize(fmt)); if (!m_dev->readTexture(&(*raw_frame)[0], raw_frame->size(), tex, m_exr->width, m_exr->height, fmt)) { m_exr->raw_frames.pop_back(); return false; } if (flipY) { fcImageFlipY(&(*raw_frame)[0], m_exr->width, m_exr->height, m_exr->width * fcGetPixelSize(fmt)); } } { Imf::PixelType pixel_type = Imf::HALF; int channels = 0; int tsize = 0; switch (fmt) { case fcTextureFormat_ARGBHalf: pixel_type = Imf::HALF; channels = 4; tsize = 2; break; case fcTextureFormat_RGHalf: pixel_type = Imf::HALF; channels = 2; tsize = 2; break; case fcTextureFormat_RHalf: pixel_type = Imf::HALF; channels = 1; tsize = 2; break; case fcTextureFormat_ARGBFloat: pixel_type = Imf::FLOAT; channels = 4; tsize = 4; break; case fcTextureFormat_RGFloat: pixel_type = Imf::FLOAT; channels = 2; tsize = 4; break; case fcTextureFormat_RFloat: pixel_type = Imf::FLOAT; channels = 1; tsize = 4; break; case fcTextureFormat_ARGBInt: pixel_type = Imf::UINT; channels = 4; tsize = 4; break; case fcTextureFormat_RGInt: pixel_type = Imf::UINT; channels = 2; tsize = 4; break; case fcTextureFormat_RInt: pixel_type = Imf::UINT; channels = 1; tsize = 4; break; default: m_exr->raw_frames.pop_back(); return false; } int psize = tsize * channels; char *raw_data = &(*raw_frame)[0]; m_exr->header.channels().insert(name, Imf::Channel(pixel_type)); m_exr->frame_buffer.insert(name, Imf::Slice(pixel_type, raw_data + (tsize * channel), psize, psize * m_exr->width)); } return true; }
bool fcExrContext::addLayerTexture(void *tex, fcPixelFormat fmt, int channel, const char *name) { if (m_dev == nullptr) { fcDebugLog("fcExrContext::addLayerTexture(): gfx device is null."); return false; } if (m_task == nullptr) { fcDebugLog("fcExrContext::addLayerTexture(): maybe beginFrame() is not called."); return false; } Buffer *raw_frame = nullptr; if (tex == m_frame_prev) { raw_frame = m_src_prev; fmt = m_fmt_prev; } else { m_frame_prev = tex; m_task->pixels.push_back(Buffer()); raw_frame = &m_task->pixels.back(); raw_frame->resize(m_task->width * m_task->height * fcGetPixelSize(fmt)); // get frame buffer if (!m_dev->readTexture(&(*raw_frame)[0], raw_frame->size(), tex, m_task->width, m_task->height, fmt)) { m_task->pixels.pop_back(); return false; } m_src_prev = raw_frame; // convert pixel format if it is not supported by exr if ((fmt & fcPixelFormat_TypeMask) == fcPixelFormat_Type_u8) { m_task->pixels.emplace_back(Buffer()); auto *buf = &m_task->pixels.back(); int channels = fmt & fcPixelFormat_ChannelMask; auto src_fmt = fmt; fmt = fcPixelFormat(fcPixelFormat_Type_f16 | channels); buf->resize(m_task->width * m_task->height * fcGetPixelSize(fmt)); fcConvertPixelFormat(&(*buf)[0], fmt, &(*raw_frame)[0], src_fmt, m_task->width * m_task->height); m_src_prev = raw_frame = buf; } m_fmt_prev = fmt; } return addLayerImpl(&(*raw_frame)[0], fmt, channel, name); }