Exemple #1
0
void djvOpenGlTest::members()
{
    DJV_DEBUG("djvOpenGlTest::members");
    
    djvImageContext context;
    
    QScopedPointer<djvOpenGlContext> openGlContext(
        context.openGlContextFactory()->create());
    
    djvOpenGlContextScope contextScope(openGlContext.data());

    QScopedPointer<djvOpenGlOffscreenBuffer> buffer(
        new djvOpenGlOffscreenBuffer(djvPixelDataInfo(100, 100, djvPixel::RGBA_U8)));
    
    djvOpenGlOffscreenBufferScope bufferScope(buffer.data());
    
    DJV_DEBUG_PRINT("buffer = " << buffer->info());
    DJV_DEBUG_PRINT("buffer id = " << buffer->id());
    DJV_DEBUG_PRINT("buffer texture = " << buffer->texture());

    {
       djvOpenGlUtil::ortho(djvVector2i(100, 100));
       
       DJV_ASSERT(GL_NO_ERROR == ::glGetError());
       
       djvOpenGlUtil::color(djvColor(0.5));
       
       DJV_ASSERT(GL_NO_ERROR == ::glGetError());

       djvOpenGlUtil::drawBox(djvBox2i(25, 25, 50, 50));

       DJV_ASSERT(GL_NO_ERROR == ::glGetError());

       djvOpenGlUtil::drawBox(djvBox2f(50.0, 50.0, 50.0, 50.0));       

       DJV_ASSERT(GL_NO_ERROR == ::glGetError());
       
       djvVector2f uv[4] =
       {
           djvVector2f(0.0, 0.0),
           djvVector2f(0.1, 0.0),
           djvVector2f(0.1, 1.0),
           djvVector2f(0.0, 1.0)
       };

       djvOpenGlUtil::drawBox(djvBox2i(25, 25, 50, 50), uv);

       DJV_ASSERT(GL_NO_ERROR == ::glGetError());

       djvOpenGlUtil::drawBox(djvBox2f(50.0, 50.0, 50.0, 50.0), uv);

       DJV_ASSERT(GL_NO_ERROR == ::glGetError());
    }
    
    {
        for (int i = 0; i < djvPixel::PIXEL_COUNT; ++i)
        {
            DJV_ASSERT(djvOpenGlUtil::format(static_cast<djvPixel::PIXEL>(i)));
            DJV_ASSERT(djvOpenGlUtil::type(static_cast<djvPixel::PIXEL>(i)));
        }
    }
}
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;
    }
}