Esempio n. 1
0
void TextureOgl::setTexels(
    const Separate3dRegion &region, const void *data )
{
    storm_assert( _description.layout == Layout::Separate3d );

    const MipLevelDimensions mipLevelDimensions =
        getMipLevelDimensions( region.mipLevel );

    storm_assert( region.mipLevel < _description.mipLevels );
    storm_assert( region.x + region.width <= mipLevelDimensions.width );
    storm_assert( region.y + region.height <= mipLevelDimensions.height );
    storm_assert( region.z + region.depth <= mipLevelDimensions.depth );

    ScopeTextureBinding scopeTextureBinding( _target, _texture );

    setTexelTransferAlignment( region.width );

    ::glTexSubImage3D(
        _target,
        region.mipLevel,
        region.x,
        region.y,
        region.z,
        region.width,
        region.height,
        region.depth,
        _texelDescription.format, _texelDescription.type, data );
    checkResult( "::glTexSubImage3D" );

    resetTexelTransferAlignment();
}
Esempio n. 2
0
void TextureOgl::getTexels(
    unsigned int mipLevel, unsigned int /*size*/, void *texels ) const
{
    storm_assert( _description.layout != Layout::Separate2dMsaa );
    storm_assert( _description.layout != Layout::Layered2dMsaa );

    storm_assert( mipLevel < _description.mipLevels );

    // TODO: check size

    ScopeTextureBinding scopeTextureBinding( _target, _texture );

    if( _description.layout == Layout::CubeMap ) {

        if( _texelDescription.compressed )
            throwNotImplemented();

        const MipLevelDimensions mipLevelDimensions =
            getMipLevelDimensions( mipLevel );

        setTexelTransferAlignment( mipLevelDimensions.width );

        const GLenum targets[] = {
            GL_TEXTURE_CUBE_MAP_POSITIVE_X,
            GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
            GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
            GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
            GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
            GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
        };

        for( GLenum target : targets ) {
            ::glGetTexImage( target, mipLevel,
                _texelDescription.format, _texelDescription.type, texels );
            checkResult( "::glGetTexImage" );

            texels = static_cast<unsigned char*>( texels ) +
                _texelDescription.size *
                mipLevelDimensions.width *
                mipLevelDimensions.height;
        }

        resetTexelTransferAlignment();
        return;
    }

    if( !_texelDescription.compressed ) {
        setTexelTransferAlignment( getMipLevelDimensions(mipLevel).width );

        ::glGetTexImage( _target, mipLevel,
            _texelDescription.format, _texelDescription.type, texels );
        checkResult( "::glGetTexImage" );

        resetTexelTransferAlignment();
    } else {
        ::glGetCompressedTexImage( _target, mipLevel, texels );
        checkResult( "::glGetCompressedTexImage" );
    }
}
Esempio n. 3
0
void TextureOgl::generateMipMap() {
    storm_assert( _description.layout != Layout::Separate2dMsaa );
    storm_assert( _description.layout != Layout::Layered2dMsaa );

    ScopeTextureBinding scopeTextureBinding( _target, _texture );

    ::glGenerateMipmap( _target );
    checkResult( "::glGenerateMipmap" );
}
Esempio n. 4
0
GLenum TextureOgl::convertCubeMapFace( unsigned int face ) {
    storm_assert( face >= CubeMapFace::PositiveX );
    storm_assert( face <= CubeMapFace::NegativeZ );

    static const GLenum faces[] = {
        GL_TEXTURE_CUBE_MAP_POSITIVE_X,
        GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
        GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
        GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
        GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
        GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
    };

    return faces[face];
}
Esempio n. 5
0
void TextureOgl::setTexels(
    const Layered2dRegion &region, const void *data )
{
    storm_assert( _description.layout == Layout::Layered2d );

    const MipLevelDimensions mipLevelDimensions =
        getMipLevelDimensions( region.mipLevel );

    storm_assert( region.mipLevel < _description.mipLevels );
    storm_assert( region.layer < _description.layers );
    storm_assert( region.x + region.width <= mipLevelDimensions.width );
    storm_assert( region.y + region.height <= mipLevelDimensions.height );

    ScopeTextureBinding scopeTextureBinding( _target, _texture );

    if( _texelDescription.compressed ) {
        CompressedRegion compressedRegion;

        compressedRegion.target = _target;
        compressedRegion.mipLevel = region.mipLevel;
        compressedRegion.x = region.x;
        compressedRegion.y = region.y;
        compressedRegion.z = region.layer;
        compressedRegion.width = region.width;
        compressedRegion.height = region.height;
        compressedRegion.depth = 1;

        setTexelsCompressed( compressedRegion, data );
        return;
    }

    setTexelTransferAlignment( region.width );

    ::glTexSubImage3D(
        _target,
        region.mipLevel,
        region.x,
        region.y,
        region.layer,
        region.width,
        region.height,
        /* depth = */ 1,
        _texelDescription.format, _texelDescription.type, data );
    checkResult( "::glTexSubImage3D" );

    resetTexelTransferAlignment();
}
void RenderingSystemOgl::setOutputTechnique(
    OutputTechnique::Pointer technique )
{
    storm_assert( technique );
    if( _outputTechnique == technique ) return;

    auto nativeTechnique =
        std::static_pointer_cast< OutputTechniqueOgl >( technique );

    const auto &description = nativeTechnique->getNativeDescription();

    const auto &depthTest = description.depthTest;
    const auto &stencilTest = description.stencilTest;

    setBooleanGlState( GL_DEPTH_TEST, depthTest.has_value() );
    setBooleanGlState( GL_STENCIL_TEST, stencilTest.has_value() );

    if( depthTest ) {
        ::glDepthFunc( depthTest->passCondition );
        checkResult( "::glDepthFunc" );
    }

    if( stencilTest ) {
        ::glStencilOpSeparate(
            GL_FRONT,
            stencilTest->algorithmForFrontFaces.operationOnStencilTestFail,
            stencilTest->algorithmForFrontFaces.operationOnDepthTestFail,
            stencilTest->algorithmForFrontFaces.operationOnDepthTestPass );
        checkResult( "::glStencilOpSeparate" );

        ::glStencilOpSeparate(
            GL_BACK,
            stencilTest->algorithmForBackFaces.operationOnStencilTestFail,
            stencilTest->algorithmForBackFaces.operationOnDepthTestFail,
            stencilTest->algorithmForBackFaces.operationOnDepthTestPass );
        checkResult( "::glStencilOpSeparate" );

        ::glStencilFuncSeparate(
            GL_FRONT,
            stencilTest->algorithmForFrontFaces.passCondition,
            stencilTest->referenceValue,
            stencilTest->mask );
        checkResult( "::glStencilFuncSeparate" );

        ::glStencilFuncSeparate(
            GL_BACK,
            stencilTest->algorithmForBackFaces.passCondition,
            stencilTest->referenceValue,
            stencilTest->mask );
        checkResult( "::glStencilFuncSeparate" );
    }

    ::glDepthMask( description.writeDepthValues );
    checkResult( "::glDepthMask" );

    _outputTechnique = technique;
    return;
}
void RenderingSystemOgl::setBlendingTechnique(
    BlendingTechnique::Pointer technique )
{
    storm_assert( technique );
    if( _blendingTechnique == technique ) return;

    auto nativeTechnique = std::static_pointer_cast< BlendingTechniqueOgl >( technique );

    const BlendingTechniqueOgl::EquationOgl colorEquation =
        nativeTechnique->getColorEquation();
    const BlendingTechniqueOgl::EquationOgl alphaEquation =
        nativeTechnique->getAlphaEquation();

    const bool blendingDisabled =
        colorEquation.operation == GL_FUNC_ADD &&
        alphaEquation.operation == GL_FUNC_ADD &&
        colorEquation.sourceFactor == GL_ONE &&
        alphaEquation.sourceFactor == GL_ONE &&
        colorEquation.destinationFactor == GL_ZERO &&
        alphaEquation.destinationFactor == GL_ZERO;
    const bool blendingEnabled = !blendingDisabled;

    setBooleanGlState( GL_BLEND, blendingEnabled );

    if( blendingEnabled ) {
        if( colorEquation.operation == alphaEquation.operation ) {
            ::glBlendEquation( colorEquation.operation );
            checkResult( "::glBlendEquation" );
        } else {
            ::glBlendEquationSeparate(
                colorEquation.operation,
                alphaEquation.operation );
            checkResult( "::glBlendEquationSeparate" );
        }

        if( colorEquation.sourceFactor == alphaEquation.sourceFactor &&
            colorEquation.destinationFactor == alphaEquation.destinationFactor )
        {
            ::glBlendFunc(
                colorEquation.sourceFactor,
                colorEquation.destinationFactor );
            checkResult( "::glBlendFunc" );
        } else {
            ::glBlendFuncSeparate(
                colorEquation.sourceFactor,
                colorEquation.destinationFactor,
                alphaEquation.sourceFactor,
                alphaEquation.destinationFactor );
            checkResult( "::glBlendFuncSeparate" );
        }
    }

    _blendingTechnique = technique;
}
Esempio n. 8
0
void TextureOgl::setTexels(
    const Separate1dRegion &region, const void *data )
{
    storm_assert( _description.layout == Layout::Separate1d );

    const MipLevelDimensions mipLevelDimensions =
        getMipLevelDimensions( region.mipLevel );

    storm_assert( region.mipLevel < _description.mipLevels );
    storm_assert( region.x + region.width <= mipLevelDimensions.width );

    ScopeTextureBinding scopeTextureBinding( _target, _texture );

    ::glTexSubImage1D(
        _target,
        region.mipLevel,
        region.x,
        region.width,
        _texelDescription.format, _texelDescription.type, data );
    checkResult( "::glTexSubImage1D" );
}
void RenderingSystemOgl::renderMesh( Mesh::Pointer mesh, unsigned count ) {
    storm_assert( mesh );

    auto nativeMesh = std::static_pointer_cast< MeshOgl >( mesh );
    bindVertexArray( nativeMesh->getHandle() );

    const auto &indexBufferDescription =
        mesh->getDescription().indexBuffer->getDescription();

    storm_assert(
        indexBufferDescription.elementSize == 2 ||
        indexBufferDescription.elementSize == 4 );

    const GLuint primitiveRestartIndex =
        (indexBufferDescription.elementSize == 2) ? 0xffff : 0xffffffff;

    if( _primitiveRestartIndex != primitiveRestartIndex ) {
        _primitiveRestartIndex = primitiveRestartIndex;
        ::glPrimitiveRestartIndex( _primitiveRestartIndex );
    }

    const GLenum primitiveTopology = nativeMesh->getPrimitiveTopology();
    const GLsizei indexCount = static_cast<GLsizei>(
        indexBufferDescription.size / indexBufferDescription.elementSize );
    const GLenum indexFormat = (indexBufferDescription.elementSize == 2) ?
        GL_UNSIGNED_SHORT : GL_UNSIGNED_INT;
    const GLvoid *indexOffset = nullptr;

    if( count == 1 ) {
        ::glDrawElements(
            primitiveTopology, indexCount, indexFormat, indexOffset );
        checkResult( "::glDrawElements" );
    } else {
        ::glDrawElementsInstanced(
            primitiveTopology, indexCount, indexFormat, indexOffset, count );
        checkResult( "::glDrawElementsInstanced" );
    }
}
Esempio n. 10
0
void TextureOgl::validateDescription() const {
    storm_assert( _description.width );
    storm_assert( _description.height );
    storm_assert( _description.depth );
    storm_assert( _description.mipLevels );
    storm_assert( _description.layers );
    storm_assert( _description.texelSamples );

    if( _texelDescription.compressed ) {
        storm_assert(
            _description.layout == Layout::Separate2d ||
            _description.layout == Layout::Layered2d ||
            _description.layout == Layout::CubeMap );
    }
}
Esempio n. 11
0
void RenderingSystemOgl::setShader( Shader::Pointer shader ) {
    storm_assert( shader );

    const Shader::Type shaderType = shader->getType();

    if( getShader(shaderType) == shader )
        return;

    RenderingSystemCommon::setShader( shader );

    const auto nativeShader = std::static_pointer_cast< ShaderOgl >( shader );

    const GLbitfield stage = selectShaderStage( shaderType );

    ::glUseProgramStages( *_programPipeline, stage, nativeShader->getHandle() );
    checkResult( "::glUseProgramStages" );

    nativeShader->install();
    nativeShader->handleRootBufferUpdate(
        _rootBufferData, /* offset */ 0, _rootBufferData.size() );
}
Esempio n. 12
0
void RenderingSystemOgl::setRootBufferData(
    size_t offset, size_t size, const void *data )
{
    storm_assert( _rootBufferData.size() >= offset + size );
    std::copy(
        static_cast<const uint8_t*>(data),
        static_cast<const uint8_t*>(data) + size,
        _rootBufferData.begin() + offset );

    Shader *shaders[] = {
        _geometryShader.get(),
        _vertexShader.get(),
        _pixelShader.get()
    };

    for( Shader *shader : shaders ) {
        if( shader ) {
            static_cast<ShaderOgl*>( shader )->handleRootBufferUpdate(
                _rootBufferData, offset, size );
        }
    }
}
Esempio n. 13
0
void RenderingSystemOgl::setRasterizationTechnique(
    RasterizationTechnique::Pointer technique )
{
    storm_assert( technique );
    if( _rasterizationTechnique == technique ) return;

    auto nativeTechnique = std::static_pointer_cast< RasterizationTechniqueOgl >( technique );

    GLenum cullMode = nativeTechnique->getCullMode();
    GLenum fillMode = nativeTechnique->getFillMode();

    const bool cullingEnabled = (cullMode != GL_NONE);
    setBooleanGlState( GL_CULL_FACE, cullingEnabled );

    if( cullingEnabled ) {
        ::glFrontFace( GL_CW );
        checkResult( "::glFrontFace" );

        ::glCullFace( cullMode );
        checkResult( "::glCullFace" );
    }

    ::glPolygonMode( GL_FRONT_AND_BACK, fillMode );
    checkResult( "::glPolygonMode" );

    const auto &description = nativeTechnique->getDescription();

    setBooleanGlState( GL_SCISSOR_TEST, description.rectangleClippingEnabled );
    setBooleanGlState( GL_DEPTH_CLAMP, !description.depthClippingEnabled );

    ::glPolygonOffset(
        static_cast<GLfloat>(description.slopeScaleDepthBias),
        static_cast<GLfloat>(description.depthBias) );
    checkResult( "::glPolygonOffset" );

    _rasterizationTechnique = technique;
    return;
}
Esempio n. 14
0
void OrthographicCamera::setFrameDimensions( Vector2d frameDimensions ) {
    storm_assert(
        frameDimensions.x > 0 &&
        frameDimensions.y > 0 );
    _frameDimensions = frameDimensions;
}
Esempio n. 15
0
void PerspectiveCamera::setFrameAspectRatio( float frameAspectRatio ) {
    storm_assert( frameAspectRatio > 0 );
    _frameAspectRatio = frameAspectRatio;
}
Esempio n. 16
0
void PerspectiveCamera::setFieldOfView( float fieldOfView ) {
    storm_assert( fieldOfView > 0 );
    _fieldOfView = fieldOfView;
}
Esempio n. 17
0
void TextureOgl::setTexelsCompressed(
    const CompressedRegion &region, const void *texels )
{
    struct BlockDescription {
        GLsizei width;
        GLsizei height;
        GLsizei size;
    };

    static const std::map<Format, BlockDescription> formatBlockDescriptions = {
        {Format::RgbDxt1, {4, 4, 8}},
        {Format::RgbaDxt1, {4, 4, 8}},
        {Format::RgbaDxt3, {4, 4, 16}},
        {Format::RgbaDxt5, {4, 4, 16}},
        {Format::SrgbDxt1, {4, 4, 8}},
        {Format::SrgbaDxt1, {4, 4, 8}},
        {Format::SrgbaDxt3, {4, 4, 16}},
        {Format::SrgbaDxt5, {4, 4, 16}}
    };

    const BlockDescription &block =
        formatBlockDescriptions.at( _description.format );

    const MipLevelDimensions mipLevelDimensions =
        getMipLevelDimensions( region.mipLevel );

    storm_assert( (region.x % block.width) == 0 );
    storm_assert( (region.y % block.height) == 0 );
    storm_assert( (region.width % block.width) == 0 ||
        region.x + region.width == mipLevelDimensions.width );
    storm_assert( (region.height % block.height) == 0 ||
        region.y + region.height == mipLevelDimensions.height );

    const GLsizei dataSize =
        static_cast<GLsizei>( ceil(1.0f * region.width / block.width) ) *
        static_cast<GLsizei>( ceil(1.0f * region.height / block.height) ) *
        static_cast<GLsizei>( region.depth ) * block.size;

    if( region.target != GL_TEXTURE_2D_ARRAY ) {
        ::glCompressedTexSubImage2D(
            region.target,
            region.mipLevel,
            region.x,
            region.y,
            region.width,
            region.height,
            _texelDescription.internalFormat,
            dataSize,
            texels );
        checkResult( "::glCompressedTexSubImage2D" );
    } else {
        ::glCompressedTexSubImage3D(
            region.target,
            region.mipLevel,
            region.x,
            region.y,
            region.z,
            region.width,
            region.height,
            region.depth,
            _texelDescription.internalFormat,
            dataSize,
            texels );
        checkResult( "::glCompressedTexSubImage3D" );
    }
}
Esempio n. 18
0
TextureOgl::TextureOgl( const Description &description ) :
    _description( description ),
    _texelDescription( selectTexelDescription(description.format) ),
    _target( selectTarget(description.layout) )
{
    validateDescription();

    ScopeTextureBinding scopeTextureBinding( _target, _texture );

    const unsigned int levelsMaximum = getMipLevelsMaximum( _description );
    const unsigned int levels = _description.mipLevels == CompleteMipMap ?
        levelsMaximum : _description.mipLevels;
    storm_assert( levels <= levelsMaximum );

    if( _description.mipLevels == CompleteMipMap )
        _description.mipLevels = levels;

    switch( _description.layout ) {
    case Layout::Separate1d:
        ::glTexStorage1D(
            _target, levels, _texelDescription.internalFormat,
            description.width );
        checkResult( "::glTexStorage1D" );
        break;
    case Layout::Separate2d:
    case Layout::CubeMap:
        ::glTexStorage2D(
            _target, levels, _texelDescription.internalFormat,
            description.width,
            description.height );
        checkResult( "::glTexStorage2D" );
        break;
    case Layout::Separate3d:
        ::glTexStorage3D(
            _target, levels, _texelDescription.internalFormat,
            description.width,
            description.height,
            description.depth );
        checkResult( "::glTexStorage3D" );
        break;
    case Layout::Layered1d:
        ::glTexStorage2D(
            _target, levels, _texelDescription.internalFormat,
            description.width,
            description.layers );
        checkResult( "::glTexStorage2D" );
        break;
    case Layout::Layered2d:
        ::glTexStorage3D(
            _target, levels, _texelDescription.internalFormat,
            description.width,
            description.height,
            description.layers );
        checkResult( "::glTexStorage3D" );
        break;
    case Layout::Separate2dMsaa:
        ::glTexStorage2DMultisample(
            _target, description.texelSamples,
            _texelDescription.internalFormat,
            description.width,
            description.height,
            GL_TRUE );
        checkResult( "::glTexStorage2DMultisample" );
        break;
    case Layout::Layered2dMsaa:
        ::glTexStorage3DMultisample(
            _target, description.texelSamples,
            _texelDescription.internalFormat,
            description.width,
            description.height,
            description.layers,
            GL_TRUE );
        checkResult( "::glTexStorage3DMultisample" );
        break;
    default:
        throwNotImplemented();
    }
}
Esempio n. 19
0
void Camera::setDepthRange( DepthRange depthRange ) {
    storm_assert(
        depthRange.maximum - depthRange.minimum > 0 &&
        depthRange.minimum >= 0 );
    _depthRange = depthRange;
}