Example #1
0
void djvOpenGlLut::init(const djvPixelData & data) throw (djvError)
{
    init(data.info());

    bind();

    copy(data);
}
Example #2
0
void djvOpenGlLut::copy(const djvPixelData & in)
{
    //DJV_DEBUG("djvOpenGlLut::copy");
    //DJV_DEBUG_PRINT("in = " << in);

    const djvPixelDataInfo & info = in.info();

    djvOpenGlImage::stateUnpack(in.info());

    DJV_DEBUG_OPEN_GL(
        glTexSubImage1D(
            GL_TEXTURE_1D,
            0,
            0,
            info.size.x,
            djvOpenGlUtil::format(info.pixel, info.bgr),
            djvOpenGlUtil::type(info.pixel),
            in.data()));
}
Example #3
0
void djvOpenGlImageTexture::init(
    const djvPixelData & data,
    GLenum               min,
    GLenum               mag) throw (djvError)
{
    init(data.info(), min, mag);

    bind();

    copy(data);
}
Example #4
0
void djvOpenGlImage::draw(
    const djvPixelData &          data,
    const djvOpenGlImageOptions & options,
    djvOpenGlImageState *         state) throw (djvError)
{
    //DJV_DEBUG("djvOpenGlImage::draw");
    //DJV_DEBUG_PRINT("data = " << data);
    //DJV_DEBUG_PRINT("color profile = " << options.colorProfile);
    
    RestoreState restoreState;

    djvOpenGlImageState defaultState;

    if (! state)
    {
        state = &defaultState;
    }

    const djvPixelDataInfo & info = data.info();

    const int proxyScale =
        options.proxyScale ?
        djvPixelDataUtil::proxyScale(info.proxy) :
        1;

    const djvVector2i scale = djvVectorUtil::ceil<double, int>(
        options.xform.scale * djvVector2f(info.size * proxyScale));

    const djvVector2i scaleTmp(scale.x, data.h());

    //DJV_DEBUG_PRINT("scale = " << scale);
    //DJV_DEBUG_PRINT("scale tmp = " << scaleTmp);

    // Initialize.

    const djvOpenGlImageFilter::FILTER filter =
        info.size == scale ? djvOpenGlImageFilter::NEAREST :
        (djvVectorUtil::area(scale) < djvVectorUtil::area(info.size) ?
         options.filter.min : options.filter.mag);

    //DJV_DEBUG_PRINT("filter min = " << options.filter.min);
    //DJV_DEBUG_PRINT("filter mag = " << options.filter.mag);
    //DJV_DEBUG_PRINT("filter = " << filter);

    if (! state->_init || state->_info != info || state->_options != options)
    {
        switch (filter)
        {
            case djvOpenGlImageFilter::NEAREST:
            case djvOpenGlImageFilter::LINEAR:
            {
                //DJV_DEBUG_PRINT("init single pass");

                state->_texture->init(
                    data.info(),
                    djvOpenGlImageFilter::toGl(filter),
                    djvOpenGlImageFilter::toGl(filter));

                state->_shader->init(
                    sourceVertex,
                    sourceFragment(
                        options.colorProfile.type,
                        options.displayProfile,
                        options.channel,
                        false,
                        0,
                        false));
            }
            break;

            case djvOpenGlImageFilter::BOX:
            case djvOpenGlImageFilter::TRIANGLE:
            case djvOpenGlImageFilter::BELL:
            case djvOpenGlImageFilter::BSPLINE:
            case djvOpenGlImageFilter::LANCZOS3:
            case djvOpenGlImageFilter::CUBIC:
            case djvOpenGlImageFilter::MITCHELL:
            {
                //DJV_DEBUG_PRINT("init two pass");

                state->_texture->init(
                    data.info(),
                    GL_NEAREST,
                    GL_NEAREST);

                // Initialize horizontal pass.

                djvPixelData contrib;

                scaleContrib(
                    data.w(),
                    scale.x,
                    filter,
                    contrib);

                state->_scaleXContrib->init(
                    contrib,
                    GL_NEAREST,
                    GL_NEAREST);

                state->_scaleXShader->init(
                    sourceVertex,
                    sourceFragment(
                        options.colorProfile.type,
                        djvOpenGlImageDisplayProfile(),
                        static_cast<djvOpenGlImageOptions::CHANNEL>(0),
                        true,
                        contrib.h(),
                        true));

                // Initialize vertical pass.

                scaleContrib(
                    data.h(),
                    scale.y,
                    filter,
                    contrib);

                state->_scaleYContrib->init(
                    contrib,
                    GL_NEAREST,
                    GL_NEAREST);

                state->_scaleYShader->init(
                    sourceVertex,
                    sourceFragment(
                        static_cast<djvColorProfile::PROFILE>(0),
                        options.displayProfile,
                        options.channel,
                        true,
                        contrib.h(),
                        false));
            }
            break;

            default: break;
        }

        state->_init    = true;
        state->_info    = info;
        state->_options = options;
    }

    // Render.

    const djvPixelDataInfo::Mirror mirror(
        info.mirror.x ? (! options.xform.mirror.x) : options.xform.mirror.x,
        info.mirror.y ? (! options.xform.mirror.y) : options.xform.mirror.y);

    //DJV_DEBUG_PRINT("mirror = " << mirror.x << " " << mirror.y);

    switch (filter)
    {
        case djvOpenGlImageFilter::NEAREST:
        case djvOpenGlImageFilter::LINEAR:
        {
            //DJV_DEBUG_PRINT("draw single pass");

            state->_shader->bind();

            // Initialize color and display profiles.

            colorProfileInit(
                options,
                state->_shader->program(),
                *state->_lutColorProfile);

            displayProfileInit(
                options,
                state->_shader->program(),
                *state->_lutDisplayProfile);

            // Draw.

            activeTexture(GL_TEXTURE0);

            uniform1i(state->_shader->program(), "inTexture", 0);

            state->_texture->copy(data);
            state->_texture->bind();

            DJV_DEBUG_OPEN_GL(glPushMatrix());
            const djvMatrix3f m = djvOpenGlImageXform::xformMatrix(options.xform);
            //DJV_DEBUG_PRINT("m = " << m);
            DJV_DEBUG_OPEN_GL(glLoadMatrixd(djvMatrixUtil::matrix4(m).e));

            quad(info.size, mirror, proxyScale);

            DJV_DEBUG_OPEN_GL(glPopMatrix());
        }
        break;

        case djvOpenGlImageFilter::BOX:
        case djvOpenGlImageFilter::TRIANGLE:
        case djvOpenGlImageFilter::BELL:
        case djvOpenGlImageFilter::BSPLINE:
        case djvOpenGlImageFilter::LANCZOS3:
        case djvOpenGlImageFilter::CUBIC:
        case djvOpenGlImageFilter::MITCHELL:
        {
            //DJV_DEBUG_PRINT("draw two pass");

            // Horizontal pass.

            djvOpenGlOffscreenBuffer buffer(
                djvPixelDataInfo(scaleTmp, data.pixel()));

            {
                djvOpenGlOffscreenBufferScope bufferScope(&buffer);

                state->_scaleXShader->bind();

                colorProfileInit(
                    options,
                    state->_scaleXShader->program(),
                    *state->_lutColorProfile);

                activeTexture(GL_TEXTURE0);

                uniform1i(state->_scaleXShader->program(), "inTexture", 0);

                state->_texture->copy(data);
                state->_texture->bind();

                activeTexture(GL_TEXTURE1);

                uniform1i(
                    state->_scaleXShader->program(), "inScaleContrib", 1);

                state->_scaleXContrib->bind();

                glPushAttrib(GL_TRANSFORM_BIT | GL_VIEWPORT_BIT);
                glMatrixMode(GL_PROJECTION);
                glPushMatrix();
                glMatrixMode(GL_MODELVIEW);
                glPushMatrix();

                djvOpenGlUtil::ortho(scaleTmp);
                glViewport(0, 0, scaleTmp.x, scaleTmp.y);
                quad(scaleTmp, mirror);

                glMatrixMode(GL_PROJECTION);
                glPopMatrix();
                glMatrixMode(GL_MODELVIEW);
                glPopMatrix();
                glPopAttrib();
            }

            // Vertical pass.

            state->_scaleYShader->bind();

            displayProfileInit(
                options,
                state->_scaleYShader->program(),
                *state->_lutDisplayProfile);

            activeTexture(GL_TEXTURE0);

            uniform1i(state->_scaleYShader->program(), "inTexture", 0);

            DJV_DEBUG_OPEN_GL(glBindTexture(GL_TEXTURE_2D, buffer.texture()));

            activeTexture(GL_TEXTURE1);

            uniform1i(state->_scaleYShader->program(), "inScaleContrib", 1);

            state->_scaleYContrib->bind();

            djvOpenGlImageXform xform = options.xform;
            xform.scale = djvVector2f(1.0);
            const djvMatrix3f m = djvOpenGlImageXform::xformMatrix(xform);

            DJV_DEBUG_OPEN_GL(glPushMatrix());
            DJV_DEBUG_OPEN_GL(glLoadMatrixd(djvMatrixUtil::matrix4(m).e));

            quad(scale);

            DJV_DEBUG_OPEN_GL(glPopMatrix());
        }
        break;

        default: break;
    }
}