Example #1
0
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);
}