예제 #1
0
void AccumBufferObject::_reset()
{
    EQ_GL_CALL( glMatrixMode(GL_PROJECTION));
    EQ_GL_CALL( glPopMatrix());
    EQ_GL_CALL( glPopAttrib());
    EQ_GL_CALL( glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, _previousFBO ));
}
예제 #2
0
bool Window::configInitGL( const uint128_t& )
{
    const bool coreProfile = getIAttribute(
                WindowSettings::IATTR_HINT_CORE_PROFILE ) == ON;
    if( !coreProfile )
    {
        EQ_GL_CALL( glEnable( GL_LIGHTING ));
        EQ_GL_CALL( glEnable( GL_LIGHT0 ));

        EQ_GL_CALL( glColorMaterial( GL_FRONT_AND_BACK,
                                     GL_AMBIENT_AND_DIFFUSE ));
        EQ_GL_CALL( glEnable( GL_COLOR_MATERIAL ));
    }

    EQ_GL_CALL( glEnable( GL_SCISSOR_TEST )); // to constrain channel viewport
    EQ_GL_CALL( glEnable( GL_DEPTH_TEST ));
    EQ_GL_CALL( glDepthFunc( GL_LESS ));
    EQ_GL_CALL( glClearDepth( 1.f ));

    EQ_GL_CALL( glClear( GL_COLOR_BUFFER_BIT ));
    swapBuffers();
    EQ_GL_CALL( glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ));

    return true;
}
예제 #3
0
    bool setup( const size_t newSize, const GLuint type )
        {
            if( !GLEW_ARB_pixel_buffer_object )
            {
                _setError( ERROR_PBO_UNSUPPORTED );
                return false;
            }

            if( newSize == 0 )
            {
                _setError( ERROR_PBO_SIZE_TOO_SMALL );
                destroy();
                return false;
            }

            if( pboID == 0 )
            {
                EQ_GL_CALL( glGenBuffersARB( 1, &pboID ));
            }
            if( pboID == 0 )
            {
                _setError( ERROR_PBO_NOT_INITIALIZED );
                return false;
            }

            if( _type == type && size >= newSize )
            {
                bind();
                return true;
            }

            _type = type;
            size = newSize;
            bind();

            switch( type )
            {
              case GL_READ_ONLY_ARB:
                  EQ_GL_CALL( 
                      glBufferDataARB( GL_PIXEL_PACK_BUFFER_ARB, newSize, 0,
                                       GL_STREAM_READ_ARB ));
                  return true;

              case GL_WRITE_ONLY_ARB:
                  EQ_GL_CALL(
                      glBufferDataARB( GL_PIXEL_UNPACK_BUFFER_ARB, newSize, 0,
                                       GL_STREAM_DRAW_ARB ));
                  return true;

              default:
                  _setError( ERROR_PBO_TYPE_UNSUPPORTED );
                  destroy();
                  return false;
            }
        }
예제 #4
0
파일: Channel.cpp 프로젝트: hernando/Livre
    void applyCamera()
    {
        ConstCameraSettingsPtr cameraSettings = getFrameData()->getCameraSettings( );

        const Matrix4f& cameraRotation = cameraSettings->getCameraRotation( );
        const Matrix4f& modelRotation = cameraSettings->getModelRotation( );
        const Vector3f& cameraPosition = cameraSettings->getCameraPosition( );

        EQ_GL_CALL( glMultMatrixf( cameraRotation.array ) );
        EQ_GL_CALL( glTranslatef( cameraPosition[ 0 ], cameraPosition[ 1 ],
                                  cameraPosition[ 2 ] ) );
        EQ_GL_CALL( glMultMatrixf( modelRotation.array ) );
    }
예제 #5
0
void AccumBufferObject::accum( const GLfloat value )
{
    _texture->copyFromFrameBuffer( _texture->getInternalFormat(), _pvp );

    const PixelViewport pvp( 0, 0, getWidth(), getHeight( ));
    _setup( pvp );
    EQ_GL_CALL( glEnable( GL_BLEND ));
    EQ_GL_CALL( glBlendFunc( GL_ONE, GL_ONE ));

    _drawQuadWithTexture( _texture, pvp, value );

    EQ_GL_CALL( glBlendFunc( GL_ONE, GL_ZERO ));
    EQ_GL_CALL( glDisable( GL_BLEND ));
    _reset();
}
예제 #6
0
void CompressorReadDrawPixels::download( const GLEWContext* glewContext,
                                         const eq_uint64_t  inDims[4],
                                         const unsigned     source,
                                         const eq_uint64_t  flags,
                                               eq_uint64_t  outDims[4],
                                         void**             out )
{
    _init( inDims, outDims );

    if( flags & EQ_COMPRESSOR_USE_FRAMEBUFFER )
    {
        EQ_GL_CALL( glReadPixels( inDims[0], inDims[2], inDims[1], inDims[3], 
                      _format, _type, _buffer.getData() ) );
    }
    else 
    {
        _initTexture( glewContext, flags );
        _texture->setGLData( source, _internalFormat, inDims[1], inDims[3] );
        _texture->setExternalFormat( _format, _type );
        _texture->download( _buffer.getData( ));
        _texture->flushNoDelete();
    }

    *out = _buffer.getData();
}
예제 #7
0
/**
 *  Function for creating and holding of shared context.
 *  Generation and uploading of new textures over some period with sleep time.
 */
void AsyncFetcher::run()
{
    EQASSERT( !_sharedContextWindow );
    _sharedContextWindow = initSharedContextWindow( _wnd );
    _outQueue.push( TextureId( )); // unlock pipe thread
    if( !_sharedContextWindow )
        return;

    _objectManager = new ObjectManager( glewGetContext( ));
    EQINFO << "async fetcher initialized: " << _wnd << std::endl;

    int i = 0;
    bool running = true;
    co::base::sleep( 1000 ); // imitate loading of the first texture
    while( running )
    {
        // generate new texture
        eq::util::Texture* tx = _objectManager->newEqTexture( ++i,
                                                              GL_TEXTURE_2D );
        tx->init( GL_RGBA8, 64, 64 );

        int j = 0;
        co::base::RNG rng;
        for( int y = 0; y < 64; ++y )
        {
            for( int x = 0; x < 64; ++x )
            {
                const GLbyte rnd = rng.get< uint8_t >() % 127;
                const GLbyte val = (x / 8) % 2 == (y / 8) % 2 ? rnd : 0;
                _tmpTexture[ j++ ] = val;
                _tmpTexture[ j++ ] = val;
                _tmpTexture[ j++ ] = val;
                _tmpTexture[ j++ ] = val;
            }
        }
        tx->upload( 64, 64, _tmpTexture );
        EQ_GL_CALL( glFinish( ));

        // add new texture to the pool
        _outQueue.push( TextureId( tx->getName( ), i ));

        // imitate hard work of loading something else
        co::base::sleep( rng.get< uint32_t >() % 5000u );

        // clean unused textures
        int keyToDelete = 0;
        while( _inQueue.tryPop( keyToDelete ))
        {
            if( keyToDelete )
            {
                EQWARN << "Deleting eq texture " << keyToDelete << std::endl;
                _objectManager->deleteEqTexture( keyToDelete );
            }
            else
                running = false;
        }
    }
    deleteSharedContextWindow( _wnd, &_sharedContextWindow, &_objectManager );
}
예제 #8
0
    bool bind() const
        {
            if( !_testInitialized( ))
                return false;

            EQ_GL_CALL( glBindBufferARB( _getName(), pboID ));
            return true;
        }
예제 #9
0
/**
 *  Function for creating and holding of shared context.
 *  Generation and uploading of new textures over some period with sleep time.
 */
void AsyncFetcher::run()
{
    LBASSERT( _sharedWindow );
    if( !_sharedWindow )
        return;

    _sharedWindow->makeCurrent();
    eq::util::ObjectManager objects( glewGetContext( ));
    lunchbox::Bufferb textureData( 64*64*4 );
    LBINFO << "async fetcher initialized" << std::endl;

    bool running = true;
    lunchbox::sleep( 1000 ); // imitate loading of the first texture
    for( uint8_t* i = 0; running; ++i )
    {
        // generate new texture
        eq::util::Texture* tx = objects.newEqTexture( i, GL_TEXTURE_2D );
        tx->init( GL_RGBA8, 64, 64 );

        int j = 0;
        lunchbox::RNG rng;
        for( int y = 0; y < 64; ++y )
        {
            for( int x = 0; x < 64; ++x )
            {
                const GLbyte rnd = rng.get< uint8_t >() % 127;
                const GLbyte val = (x / 8) % 2 == (y / 8) % 2 ? rnd : 0;
                textureData[ j++ ] = val;
                textureData[ j++ ] = val;
                textureData[ j++ ] = val;
                textureData[ j++ ] = val;
            }
        }
        tx->upload( 64, 64, textureData.getData( ));
        EQ_GL_CALL( glFinish( ));

        // add new texture to the pool
        _outQueue.push( TextureId( tx->getName(), i ));

        // imitate hard work of loading something else
        lunchbox::sleep( rng.get< uint32_t >() % 5000u );

        // clean unused textures
        const void* keyToDelete = 0;
        while( _inQueue.tryPop( keyToDelete ))
        {
            if( keyToDelete )
            {
                LBWARN << "Deleting eq texture " << keyToDelete << std::endl;
                objects.deleteEqTexture( keyToDelete );
            }
            else
                running = false;
        }
    }
    objects.deleteAll();
}
예제 #10
0
void Texture::_generate()
{
    LB_TS_THREAD( _thread );
    if( _impl->name != 0 )
        return;

    _impl->defined = false;
    EQ_GL_CALL( glGenTextures( 1, &_impl->name ));
}
예제 #11
0
void ObjectManager::deleteShader( const void* key )
{
    ObjectHash::iterator i = _impl->shaders.find( key );
    if( i == _impl->shaders.end() )
        return;

    const Object& object = i->second;
    EQ_GL_CALL( glDeleteShader( object.id ));
    _impl->shaders.erase( i );
}
예제 #12
0
void ObjectManager::deleteList( const void* key )
{
    ObjectHash::iterator i = _impl->lists.find( key );
    if( i == _impl->lists.end( ))
        return;

    const Object& object = i->second;
    EQ_GL_CALL( glDeleteLists( object.id, object.num ));
    _impl->lists.erase( i );
}
예제 #13
0
void CompressorReadDrawPixels::startDownload( const GLEWContext* glewContext,
                                              const eq_uint64_t dims[4],
                                              const unsigned source,
                                              const eq_uint64_t flags )
{
    const eq_uint64_t size = dims[1] * dims[3] * _depth;

    if( flags & EQ_COMPRESSOR_USE_FRAMEBUFFER )
    {
#ifdef EQ_ASYNC_PBO
        if( _initPBO( glewContext, size ))
        {
            EQ_GL_CALL( glReadPixels( dims[0], dims[2], dims[1], dims[3],
                                      _format, _type, 0 ));
            _pbo->unbind();
            glFlush(); // Fixes https://github.com/Eyescale/Equalizer/issues/118
            return;
        }
#else  // async RB through texture
        const PixelViewport pvp( dims[0], dims[2], dims[1], dims[3] );
        _initAsyncTexture( glewContext, pvp.w, pvp.h );
        _asyncTexture->setExternalFormat( _format, _type );
        _asyncTexture->copyFromFrameBuffer( _internalFormat, pvp );
        return;
#endif
        // else

        LBWARN << "Can't initialize PBO for async readback" << std::endl;
        _resizeBuffer( size );
        EQ_GL_CALL( glReadPixels( dims[0], dims[2], dims[1], dims[3],
                                  _format, _type, _buffer.getData( )));
    }
    else
    {
        // TODO: fix Texture class for async texture download
        _resizeBuffer( size );
        _initTexture( glewContext, flags );
        _texture->setGLData( source, _internalFormat, dims[1], dims[3] );
        _texture->setExternalFormat( _format, _type );
        _texture->download( _buffer.getData( ));
        _texture->flushNoDelete();
    }
}
예제 #14
0
void Channel::_drawOverlay()
{
    // Draw the overlay logo
    const Window* window = static_cast<Window*>( getWindow( ));
    const eq::util::Texture* texture = window->getLogoTexture();
    if( !texture )
        return;

    applyOverlayState();
    EQ_GL_CALL( glDisable( GL_COLOR_LOGIC_OP ));
    EQ_GL_CALL( glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ));

    // logo
    EQ_GL_CALL( glEnable( GL_BLEND ));
    EQ_GL_CALL( glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ));
    const GLenum target = texture->getTarget();
    EQ_GL_CALL( glEnable( target ));
    texture->bind();
    EQ_GL_CALL( glTexParameteri( target, GL_TEXTURE_MAG_FILTER, GL_LINEAR ));
    EQ_GL_CALL( glTexParameteri( target, GL_TEXTURE_MIN_FILTER, GL_LINEAR ));

    const float tWidth = float( texture->getWidth( ));
    const float tHeight = float( texture->getHeight( ));

    const float width = target == GL_TEXTURE_2D ? 1.0f : tWidth;
    const float height = target == GL_TEXTURE_2D ? 1.0f : tHeight;

    glBegin( GL_QUADS );
    {
        glTexCoord2f( 0, 0 );
        glVertex3f( 5.0f, 5.0f, 0.0f );

        glTexCoord2f( width, 0 );
        glVertex3f( tWidth + 5.0f, 5.0f, 0.0f );

        glTexCoord2f( width, height );
        glVertex3f( tWidth + 5.0f, tHeight + 5.0f, 0.0f );

        glTexCoord2f( 0, height );
        glVertex3f( 5.0f, tHeight + 5.0f, 0.0f );

    }
    glEnd();

    EQ_GL_CALL( glDisable( target ));
    EQ_GL_CALL( glDisable( GL_BLEND ));
    resetOverlayState();
}
예제 #15
0
void ObjectManager::deleteVertexArray( const void* key )
{
    ObjectHash::iterator i = _impl->vertexArrays.find( key );
    if( i == _impl->vertexArrays.end( ))
        return;

    const Object& object = i->second;
    EQ_GL_CALL( glDeleteVertexArrays( 1, &object.id ));
    _impl->vertexArrays.erase( i );
}
예제 #16
0
bool eqHello::Renderer::_loadShaders()
{
    seq::ObjectManager& om = getObjectManager();

    if (_program)
        return true;

    _program = om.newProgram(&_program);
    if (!seq::linkProgram(om.glewGetContext(), _program, vertexShader_glsl,
                          fragmentShader_glsl))
    {
        return false;
    }

    EQ_GL_CALL(glUseProgram(_program));
    _matrixUniform = glGetUniformLocation(_program, "MVP");
    EQ_GL_CALL(glUseProgram(0));
    return true;
}
예제 #17
0
void AccumBufferObject::_setup( const PixelViewport& pvp )
{
    EQ_GL_CALL( glGetIntegerv( GL_FRAMEBUFFER_BINDING_EXT, &_previousFBO ));
    bind();
    EQ_GL_CALL( glPushAttrib( GL_SCISSOR_BIT | GL_VIEWPORT_BIT |
                              GL_TRANSFORM_BIT ));
    EQ_GL_CALL( glMatrixMode(GL_PROJECTION));
    EQ_GL_CALL( glPushMatrix());
    EQ_GL_CALL( glLoadIdentity());
    EQ_GL_CALL( glOrtho(0, pvp.w, 0, pvp.h, -1, 1));
    EQ_GL_CALL( glScissor(0, 0, pvp.w, pvp.h));
    EQ_GL_CALL( glViewport(0, 0, pvp.w, pvp.h));
}
예제 #18
0
void Window::swapBuffers()
{
    const Pipe*         pipe      = static_cast<Pipe*>( getPipe( ));
    const FrameData&    frameData = pipe->getFrameData();
    const eq::Channels& channels  = getChannels();

    if( frameData.useStatistics() && !channels.empty( ))
        EQ_GL_CALL( channels.back()->drawStatistics( ));

    eq::Window::swapBuffers();
}
예제 #19
0
 void destroy()
     {
         if( pboID != 0 )
         {
             unbind();
             EQ_GL_CALL( glDeleteBuffersARB( 1, &pboID ));
         }
         pboID = 0;
         size = 0;
         _type = 0;
     }
예제 #20
0
void Channel::frameDraw( const eq::uint128_t& )
{
    // Setup frustum
    EQ_GL_CALL( applyBuffer( ));
    EQ_GL_CALL( applyViewport( ));

    EQ_GL_CALL( glMatrixMode( GL_PROJECTION ));
    EQ_GL_CALL( glLoadIdentity( ));
    EQ_GL_CALL( applyFrustum( ));

    EQ_GL_CALL( glMatrixMode( GL_MODELVIEW ));
    EQ_GL_CALL( glLoadIdentity( ));

    // Setup lights before applying head transform, so the light will be
    // consistent in the cave
    const FrameData&    frameData   = _getFrameData();
    const eq::Matrix4f& rotation    = frameData.getRotation();
    const eq::Vector3f& translation = frameData.getTranslation();

    eq::Matrix4f     invRotationM;
    rotation.inverse( invRotationM );
    setLights( invRotationM );

    EQ_GL_CALL( applyHeadTransform( ));

    glTranslatef(  translation.x(), translation.y(), translation.z() );
    glMultMatrixf( rotation.array );

    Pipe*     pipe     = static_cast<Pipe*>( getPipe( ));
    Renderer* renderer = pipe->getRenderer();
    LBASSERT( renderer );

    const eq::Matrix4f& modelview = _computeModelView();

    // set fancy data colors
    const eq::Vector4f taintColor = _getTaintColor( frameData.getColorMode(),
                                                    getUniqueColor( ));
    const int normalsQuality = _getFrameData().getNormalsQuality();

    const eq::Range& range = getRange();
    renderer->render( range, modelview, invRotationM, taintColor,
                      normalsQuality );
    checkError( "error during rendering " );

    _drawRange = range;

#ifndef NDEBUG
    outlineViewport();
#endif
}
예제 #21
0
void GPUAsyncLoader::cleanup()
{
    _decompressor.reset();

    if( _storageTexture3D )
    {
        EQ_GL_CALL( glDeleteTextures( 1, &_storageTexture3D ));
        _storageTexture3D = 0;
    }

    if( _pbo )
        _pbo->destroy();
}
예제 #22
0
void GLWindow::updateFrameBuffer() const
{
    if( !_impl->glewContext || !_impl->fboMultiSample )
        return;

    _impl->fboMultiSample->bind( GL_READ_FRAMEBUFFER_EXT );
    _impl->fbo->bind( GL_DRAW_FRAMEBUFFER_EXT );
    const PixelViewport& pvp = getPixelViewport();
    EQ_GL_CALL( glBlitFramebuffer( 0, 0, pvp.w, pvp.h,
                                   0, 0, pvp.w, pvp.h,
                                   GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT |
                                   GL_STENCIL_BUFFER_BIT, GL_NEAREST ));
}
예제 #23
0
void Texture::resize( const int32_t width, const int32_t height )
{
    LB_TS_THREAD( _thread );
    LBASSERT( _impl->name );
    LBASSERT( _impl->internalFormat );
    LBASSERT( width > 0 && height > 0 );

    if( _impl->width == width && _impl->height == height && _impl->defined )
        return;

    if( _impl->target == GL_TEXTURE_2D && !_isPOT( width, height ))
    {
        LBASSERT( _impl->glewContext );
        LBASSERT( GLEW_ARB_texture_non_power_of_two );
    }

    EQ_GL_CALL( glBindTexture( _impl->target, _impl->name ));
    EQ_GL_CALL( glTexImage2D( _impl->target, 0, _impl->internalFormat, width,
                              height, 0, _impl->format, _impl->type, 0 ));
    _impl->width  = width;
    _impl->height = height;
    _impl->defined = true;
}
예제 #24
0
void Channel::frameDraw( const eq::uint128_t& frameID )
{
    // Setup frustum
    EQ_GL_CALL( applyBuffer( ));
    EQ_GL_CALL( applyViewport( ));
    
    EQ_GL_CALL( glMatrixMode( GL_PROJECTION ));
    EQ_GL_CALL( glLoadIdentity( ));
    EQ_GL_CALL( applyFrustum( ));

    EQ_GL_CALL( glMatrixMode( GL_MODELVIEW ));
    EQ_GL_CALL( glLoadIdentity( ));

    // Setup lights before applying head transform, so the light will be
    // consistent in the cave
    const FrameData&    frameData   = _getFrameData();
    const eq::Matrix4f& rotation    = frameData.getRotation();
    const eq::Vector3f& translation = frameData.getTranslation();

    eq::Matrix4f     invRotationM;
    rotation.inverse( invRotationM );
    setLights( invRotationM );

    EQ_GL_CALL( applyHeadTransform( ));

    glTranslatef(  translation.x(), translation.y(), translation.z() );
    glMultMatrixf( rotation.array );

    Pipe*     pipe     = static_cast<Pipe*>( getPipe( ));
    Renderer* renderer = pipe->getRenderer();
    EQASSERT( renderer );

    eq::Matrix4f  modelviewM;     // modelview matrix
    eq::Matrix3f  modelviewITM;   // modelview inversed transposed matrix
    _calcMVandITMV( modelviewM, modelviewITM );

    const eq::Range& range = getRange();
    renderer->render( range, modelviewM, modelviewITM, invRotationM );

    checkError( "error during rendering " );

    _drawRange = range;

#ifndef NDEBUG
    outlineViewport();
#endif
}
예제 #25
0
    void* mapWrite()
        {
            if( !_testInitialized( ))
                return 0;

            if( _type != GL_WRITE_ONLY_ARB )
            {
                _setError( ERROR_PBO_READ_ONLY );
                return 0;
            }

            bind();
            // cancel all draw operations on this buffer to prevent stalling
            EQ_GL_CALL( glBufferDataARB( GL_PIXEL_UNPACK_BUFFER_ARB, size, 0, 
                                         GL_STREAM_DRAW_ARB ));
            return glMapBufferARB( GL_PIXEL_UNPACK_BUFFER_ARB, _type );
        }
예제 #26
0
GLuint ObjectManager::newVertexArray( const void* key )
{
    if( _impl->vertexArrays.find( key ) != _impl->vertexArrays.end( ))
    {
        LBWARN << "Requested new vertex array for existing key" << std::endl;
        return INVALID;
    }

    GLuint id = INVALID;
    EQ_GL_CALL( glGenVertexArrays( 1, &id ));
    if( !id )
    {
        LBWARN << "glGenVertexArrays failed: " << glGetError() << std::endl;
        return INVALID;
    }

    Object& object   = _impl->vertexArrays[ key ];
    object.id        = id;
    return id;
}
예제 #27
0
void AccumBufferObject::_drawQuadWithTexture( Texture* texture,
                                              const PixelViewport& pvp,
                                              const GLfloat value )
{
    texture->bind();

    EQ_GL_CALL( glDepthMask( false ));
    EQ_GL_CALL( glDisable( GL_LIGHTING ));
    EQ_GL_CALL( glEnable( GL_TEXTURE_RECTANGLE_ARB ));
    EQ_GL_CALL( glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ));
    texture->applyWrap();
    texture->applyZoomFilter( FILTER_NEAREST );

    EQ_GL_CALL( glColor4f( value, value, value, value ));

    const float startX = static_cast< float >( pvp.x );
    const float endX   = static_cast< float >( pvp.x + pvp.w );
    const float startY = static_cast< float >( pvp.y );
    const float endY   = static_cast< float >( pvp.y + pvp.h );

    glBegin( GL_QUADS );
        glTexCoord2f( 0.0f, 0.0f );
        glVertex3f( startX, startY, 0.0f );

        glTexCoord2f( static_cast< float >( pvp.w ), 0.0f );
        glVertex3f( endX, startY, 0.0f );

        glTexCoord2f( static_cast<float>( pvp.w ), static_cast<float>( pvp.h ));
        glVertex3f( endX, endY, 0.0f );

        glTexCoord2f( 0.0f, static_cast< float >( pvp.h ));
        glVertex3f( startX, endY, 0.0f );
    glEnd();

    // restore state
    EQ_GL_CALL( glDisable( GL_TEXTURE_RECTANGLE_ARB ));
    EQ_GL_CALL( glDepthMask( true ));
}
예제 #28
0
void GLWindow::queryDrawableConfig( DrawableConfig& dc )
{
    dc = DrawableConfig();

    // GL version
    const char* glVersion = (const char*)glGetString( GL_VERSION );
    if( !glVersion ) // most likely no context
    {
        LBWARN << "glGetString(GL_VERSION) returned 0, assuming GL version 1.1"
               << std::endl;
        dc.glVersion = 1.1f;
    }
    else
        dc.glVersion = static_cast<float>( std::atof( glVersion ));

    if( dc.glVersion >= 3.2f )
    {
        GLint mask;
        EQ_GL_CALL( glGetIntegerv( GL_CONTEXT_PROFILE_MASK, &mask ));
        dc.coreProfile = mask & GL_CONTEXT_CORE_PROFILE_BIT;
    }

    TEST_GLEW_VERSION( 1, 1 );
    TEST_GLEW_VERSION( 1, 2 );
    TEST_GLEW_VERSION( 1, 3 );
    TEST_GLEW_VERSION( 1, 4 );
    TEST_GLEW_VERSION( 1, 5 );
    TEST_GLEW_VERSION( 2, 0 );
    TEST_GLEW_VERSION( 2, 1 );
    TEST_GLEW_VERSION( 3, 0 );
    TEST_GLEW_VERSION( 3, 1 );
    TEST_GLEW_VERSION( 3, 2 );
    TEST_GLEW_VERSION( 3, 3 );
    TEST_GLEW_VERSION( 4, 0 );
    TEST_GLEW_VERSION( 4, 1 );
    TEST_GLEW_VERSION( 4, 2 );
    TEST_GLEW_VERSION( 4, 3 );
#ifdef GLEW_VERSION_4_5
    TEST_GLEW_VERSION( 4, 4 );
    TEST_GLEW_VERSION( 4, 5 );
#endif

    // Framebuffer capabilities
    GLboolean result;
    EQ_GL_CALL( glGetBooleanv( GL_STEREO, &result ));
    dc.stereo = result;

    EQ_GL_CALL( glGetBooleanv( GL_DOUBLEBUFFER, &result ));
    dc.doublebuffered = result;

    if( dc.coreProfile )
    {
        if( getFrameBufferObject( ))
        {
            glGetFramebufferAttachmentParameteriv( GL_FRAMEBUFFER,
                GL_DEPTH_STENCIL_ATTACHMENT,
                GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE, &dc.stencilBits );
            // eat GL error if no stencil attachment; should return '0' bits
            // according to spec, but gives GL_INVALID_OPERATION
            glGetError();
            EQ_GL_CALL( glGetFramebufferAttachmentParameteriv( GL_FRAMEBUFFER,
                GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE,
                                                               &dc.colorBits ));
            EQ_GL_CALL( glGetFramebufferAttachmentParameteriv( GL_FRAMEBUFFER,
                GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE,
                                                               &dc.alphaBits ));
        }
        else
        {
            EQ_GL_CALL( glGetFramebufferAttachmentParameteriv( GL_FRAMEBUFFER,
                GL_FRONT_LEFT, GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE,
                                                               &dc.stencilBits ));
            EQ_GL_CALL( glGetFramebufferAttachmentParameteriv( GL_FRAMEBUFFER,
                GL_FRONT_LEFT, GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE,
                                                               &dc.colorBits ));
            EQ_GL_CALL( glGetFramebufferAttachmentParameteriv( GL_FRAMEBUFFER,
                GL_FRONT_LEFT, GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE,
                                                               &dc.alphaBits ));
        }
    }
    else
    {
        EQ_GL_CALL( glGetIntegerv( GL_STENCIL_BITS, &dc.stencilBits ));
        EQ_GL_CALL( glGetIntegerv( GL_RED_BITS, &dc.colorBits ));
        EQ_GL_CALL( glGetIntegerv( GL_ALPHA_BITS, &dc.alphaBits ));
        EQ_GL_CALL( glGetIntegerv( GL_ACCUM_RED_BITS, &dc.accumBits ));
    }

    dc.accumBits *= 4;
    LBDEBUG << "Window drawable config: " << dc << std::endl;
}
예제 #29
0
void ROIFinder::_readbackInfo( util::ObjectManager& glObjects )
{
    LBASSERT( glObjects.supportsEqTexture( ));
    LBASSERT( glObjects.supportsEqFrameBufferObject( ));

    PixelViewport pvp = _pvp;
    pvp.apply( Zoom( GRID_SIZE, GRID_SIZE ));
    pvp.w = LB_MIN( pvp.w+pvp.x, _pvpOriginal.w+_pvpOriginal.x ) - pvp.x;
    pvp.h = LB_MIN( pvp.h+pvp.y, _pvpOriginal.h+_pvpOriginal.y ) - pvp.y;

    LBASSERT( pvp.isValid());

    // copy frame buffer to texture
    const void* bufferKey = _getInfoKey( );
    util::Texture* texture =
        glObjects.obtainEqTexture( bufferKey, GL_TEXTURE_RECTANGLE_ARB );

#ifdef EQ_ROI_USE_DEPTH_TEXTURE
    texture->copyFromFrameBuffer( GL_DEPTH_COMPONENT, pvp );
#else
    texture->copyFromFrameBuffer( GL_RGBA, pvp );
#endif

    // draw zoomed quad into FBO
    const void*     fboKey = _getInfoKey( );
    util::FrameBufferObject* fbo = glObjects.getEqFrameBufferObject( fboKey );

    if( fbo )
    {
        LBCHECK( fbo->resize( _pvp.w, _pvp.h ));
    }
    else
    {
        fbo = glObjects.newEqFrameBufferObject( fboKey );
        LBCHECK( fbo->init( _pvp.w, _pvp.h, GL_RGBA32F, 0, 0 ));
    }
    fbo->bind();

    texture->bind();

    // Enable & download depth texture
    glEnable( GL_TEXTURE_RECTANGLE_ARB );

    texture->applyWrap();
    texture->applyZoomFilter( FILTER_LINEAR );

    // Enable shaders
    GLuint program = glObjects.getProgram( shaderRBInfo );
    if( program == util::ObjectManager::INVALID )
    {
        // Create fragment shader which reads depth values from
        // rectangular textures
        const GLuint shader = glObjects.newShader( shaderRBInfo,
                                                        GL_FRAGMENT_SHADER );
        LBASSERT( shader != util::ObjectManager::INVALID );

#ifdef EQ_ROI_USE_DEPTH_TEXTURE
        const GLchar* fShaderPtr = roiFragmentShader_glsl.c_str();
#else
        const GLchar* fShaderPtr = roiFragmentShaderRGB_glsl.c_str();
#endif
        EQ_GL_CALL( glShaderSource( shader, 1, &fShaderPtr, 0 ));
        EQ_GL_CALL( glCompileShader( shader ));

        GLint status;
        glGetShaderiv( shader, GL_COMPILE_STATUS, &status );
        if( !status )
            LBERROR << "Failed to compile fragment shader for ROI finder"
                    << std::endl;

        program = glObjects.newProgram( shaderRBInfo );

        EQ_GL_CALL( glAttachShader( program, shader ));
        EQ_GL_CALL( glLinkProgram( program ));

        glGetProgramiv( program, GL_LINK_STATUS, &status );
        if( !status )
        {
            LBWARN << "Failed to link shader program for ROI finder"
                   << std::endl;
            return;
        }

        // use fragment shader and setup uniforms
        EQ_GL_CALL( glUseProgram( program ));

        GLint param = glGetUniformLocation( program, "texture" );
        glUniform1i( param, 0 );
    }
    else
    {
        // use fragment shader
        EQ_GL_CALL( glUseProgram( program ));
    }

    // Draw Quad
    glDisable( GL_LIGHTING );
    glColor3f( 1.0f, 1.0f, 1.0f );

    glBegin( GL_QUADS );
        glVertex3i(      0,      0, 0 );
        glVertex3i( _pvp.w,      0, 0 );
        glVertex3i( _pvp.w, _pvp.h, 0 );
        glVertex3i(      0, _pvp.h, 0 );
    glEnd();

    // restore state
    glDisable( GL_TEXTURE_RECTANGLE_ARB );
    EQ_GL_CALL( glUseProgram( 0 ));

    fbo->unbind();

    // finish readback of info
    LBASSERT( static_cast<int32_t>(_perBlockInfo.size()) >= _pvp.w*_pvp.h*4 );

    texture = fbo->getColorTextures()[0];
    LBASSERT( texture->getFormat() == GL_RGBA );
    LBASSERT( texture->getType() == GL_FLOAT );
    texture->download( &_perBlockInfo[0] );
}
예제 #30
0
void FrameBufferObject::unbind()
{
    EQ_GL_CALL( glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 ));
}