void FreeTypeFont::doFillGlyphCache(GlyphCache& cache, const std::vector<char32_t>& characters)
#endif
{
    /** @bug Crash when atlas is too small */

    /* Get glyph codes from characters */
    std::vector<FT_UInt> charIndices;
    charIndices.resize(characters.size()+1);
    charIndices[0] = 0;
    std::transform(characters.begin(), characters.end(), charIndices.begin()+1,
        [this](const char32_t c) { return FT_Get_Char_Index(ftFont, c); });

    /* Remove duplicates (e.g. uppercase and lowercase mapped to same glyph) */
    std::sort(charIndices.begin(), charIndices.end());
    charIndices.erase(std::unique(charIndices.begin(), charIndices.end()), charIndices.end());

    /* Sizes of all characters */
    std::vector<Vector2i> charSizes;
    charSizes.reserve(charIndices.size());
    for(FT_UInt c: charIndices) {
        CORRADE_INTERNAL_ASSERT_OUTPUT(FT_Load_Glyph(ftFont, c, FT_LOAD_DEFAULT) == 0);
        charSizes.push_back(Vector2i(ftFont->glyph->metrics.width, ftFont->glyph->metrics.height)/64);
    }

    /* Create texture atlas */
    const std::vector<Rectanglei> charPositions = cache.reserve(charSizes);

    /* Render all characters to the atlas and create character map */
    unsigned char* pixmap = new unsigned char[cache.textureSize().product()]();
    /** @todo Some better way for this */
    #ifndef MAGNUM_TARGET_GLES2
    Image2D image(ImageFormat::Red, ImageType::UnsignedByte, cache.textureSize(), pixmap);
    #else
    Image2D image(Context::current() && Context::current()->isExtensionSupported<Extensions::GL::EXT::texture_rg>() ?
        ImageFormat::Red : ImageFormat::Luminance, ImageType::UnsignedByte, cache.textureSize(), pixmap);
    #endif
    for(std::size_t i = 0; i != charPositions.size(); ++i) {
        /* Load and render glyph */
        /** @todo B&W only if radius != 0 */
        FT_GlyphSlot glyph = ftFont->glyph;
        CORRADE_INTERNAL_ASSERT_OUTPUT(FT_Load_Glyph(ftFont, charIndices[i], FT_LOAD_DEFAULT) == 0);
        CORRADE_INTERNAL_ASSERT_OUTPUT(FT_Render_Glyph(glyph, FT_RENDER_MODE_NORMAL) == 0);

        /* Copy rendered bitmap to texture image */
        const FT_Bitmap& bitmap = glyph->bitmap;
        CORRADE_INTERNAL_ASSERT(std::abs(bitmap.width-charPositions[i].width()) <= 2);
        CORRADE_INTERNAL_ASSERT(std::abs(bitmap.rows-charPositions[i].height()) <= 2);
        for(Int yin = 0, yout = charPositions[i].bottom(), ymax = bitmap.rows; yin != ymax; ++yin, ++yout)
            for(Int xin = 0, xout = charPositions[i].left(), xmax = bitmap.width; xin != xmax; ++xin, ++xout)
                pixmap[yout*cache.textureSize().x() + xout] = bitmap.buffer[(bitmap.rows-yin-1)*bitmap.width + xin];

        /* Insert glyph parameters into cache */
        cache.insert(charIndices[i],
            Vector2i(glyph->bitmap_left, glyph->bitmap_top-charPositions[i].height()),
            charPositions[i]);
    }

    /* Set cache image */
    cache.setImage({}, image);
}
bool Dumpster::next() {
    /* No more things available */
    if(_current == _conf.groupCount("item")) return false;

    /* Find empty dumpster */
    Int empty = -1;
    for(Int i = 0; i != 3; ++i) if(!_dumpsterItems[i]) {
        empty = i;
        break;
    }

    /* All dumpsters full */
    if(empty == -1) return false;

    /* Load info about current item from config file */
    auto itemData = _conf.group("item", _current);
    CORRADE_INTERNAL_ASSERT(itemData);
    auto imageData = _conf.group("images")->group(itemData->value("image"));
    CORRADE_INTERNAL_ASSERT(imageData);

    /* Populate the item */
    auto item = new Item(this);
    item->reset(imageData->value<Vector2i>("size"), imageData->value("file"));
    item->_contents = itemData->value("contents");
    item->_size = itemData->value<Int>("size");
    item->_value = itemData->value<Int>("value");

    /* Move to next item in the dumpster (nothing fancy now, just sequential) */
    ++_current;

    put(empty, item);
    return true;
}
Пример #3
0
int DistanceFieldConverter::exec() {
    /* Load plugins */
    PluginManager::Manager<Trade::AbstractImporter> importerManager(MAGNUM_IMPORTER_PLUGIN_DIR);
    if(!(importerManager.load(args.value("importer")) & PluginManager::LoadState::Loaded)) {
        Error() << "Cannot load importer plugin" << args.value("importer") << "from" << MAGNUM_IMPORTER_PLUGIN_DIR;
        return 1;
    }
    PluginManager::Manager<Trade::AbstractImageConverter> converterManager(MAGNUM_IMAGECONVERTER_PLUGIN_DIR);
    if(!(converterManager.load(args.value("converter")) & PluginManager::LoadState::Loaded)) {
        Error() << "Cannot load converter plugin" << args.value("converter") << "from" << MAGNUM_IMAGECONVERTER_PLUGIN_DIR;
        return 1;
    }

    /* Instance plugins */
    std::unique_ptr<Trade::AbstractImporter> importer = importerManager.instance(args.value("importer"));
    CORRADE_INTERNAL_ASSERT(importer);
    std::unique_ptr<Trade::AbstractImageConverter> converter = converterManager.instance(args.value("converter"));
    CORRADE_INTERNAL_ASSERT(converter);

    /* Open input file */
    std::optional<Trade::ImageData2D> image;
    if(!importer->openFile(args.value("input")) || !(image = importer->image2D(0))) {
        Error() << "Cannot open file" << args.value("input");
        return 1;
    }

    if(image->format() != ColorFormat::Red) {
        Error() << "Unsupported image format" << image->format();
        return 1;
    }

    /* Input texture */
    Texture2D input;
    input.setMinificationFilter(Sampler::Filter::Linear)
        .setMagnificationFilter(Sampler::Filter::Linear)
        .setWrapping(Sampler::Wrapping::ClampToEdge)
        .setImage(0, TextureFormat::R8, *image);

    /* Output texture */
    Texture2D output;
    output.setStorage(1, TextureFormat::R8, args.value<Vector2i>("output-size"));

    CORRADE_INTERNAL_ASSERT(Renderer::error() == Renderer::Error::NoError);

    /* Do it */
    Debug() << "Converting image of size" << image->size() << "to distance field...";
    TextureTools::distanceField(input, output, {{}, args.value<Vector2i>("output-size")}, args.value<Int>("radius"), image->size());

    /* Save image */
    Image2D result(ColorFormat::Red, ColorType::UnsignedByte);
    output.image(0, result);
    if(!converter->exportToFile(result, args.value("output"))) {
        Error() << "Cannot save file" << args.value("output");
        return 1;
    }

    return 0;
}
Пример #4
0
void Buffer::unbind(const Target target, const UnsignedInt index) {
    #ifdef MAGNUM_BUILD_DEPRECATED
    #ifndef MAGNUM_TARGET_WEBGL
    CORRADE_INTERNAL_ASSERT(target == Target::AtomicCounter || target == Target::ShaderStorage || target == Target::Uniform);
    #else
    CORRADE_INTERNAL_ASSERT(target == Target::Uniform);
    #endif
    #endif
    glBindBufferBase(GLenum(target), index, 0);
}
Пример #5
0
void Buffer::unbind(const Target target, const UnsignedInt firstIndex, const std::size_t count) {
    #ifdef MAGNUM_BUILD_DEPRECATED
    #ifndef MAGNUM_TARGET_WEBGL
    CORRADE_INTERNAL_ASSERT(target == Target::AtomicCounter || target == Target::ShaderStorage || target == Target::Uniform);
    #else
    CORRADE_INTERNAL_ASSERT(target == Target::Uniform);
    #endif
    #endif
    Context::current()->state().buffer->bindBasesImplementation(target, firstIndex, {nullptr, count});
}
Пример #6
0
/** @todoc const std::initializer_list makes Doxygen grumpy */
void Buffer::bind(const Target target, const UnsignedInt firstIndex, std::initializer_list<std::tuple<Buffer*, GLintptr, GLsizeiptr>> buffers) {
    #ifdef MAGNUM_BUILD_DEPRECATED
    #ifndef MAGNUM_TARGET_WEBGL
    CORRADE_INTERNAL_ASSERT(target == Target::AtomicCounter || target == Target::ShaderStorage || target == Target::Uniform || GLenum(target) == GL_TRANSFORM_FEEDBACK_BUFFER);
    #else
    CORRADE_INTERNAL_ASSERT(target == Target::Uniform || GLenum(target) == GL_TRANSFORM_FEEDBACK_BUFFER);
    #endif
    #endif
    Context::current().state().buffer->bindRangesImplementation(target, firstIndex, {buffers.begin(), buffers.size()});
}
Пример #7
0
Buffer& Buffer::bind(const Target target, const UnsignedInt index) {
    #ifdef MAGNUM_BUILD_DEPRECATED
    #ifndef MAGNUM_TARGET_WEBGL
    CORRADE_INTERNAL_ASSERT(target == Target::AtomicCounter || target == Target::ShaderStorage || target == Target::Uniform || GLenum(target) == GL_TRANSFORM_FEEDBACK_BUFFER);
    #else
    CORRADE_INTERNAL_ASSERT(target == Target::Uniform || GLenum(target) == GL_TRANSFORM_FEEDBACK_BUFFER);
    #endif
    #endif
    glBindBufferBase(GLenum(target), index, _id);
    return *this;
}
void AbstractFramebuffer::setViewportInternal() {
    Implementation::FramebufferState& state = *Context::current()->state().framebuffer;

    CORRADE_INTERNAL_ASSERT(_viewport != Implementation::FramebufferState::DisengagedViewport);
    CORRADE_INTERNAL_ASSERT(state.drawBinding == _id);

    /* Already up-to-date, nothing to do */
    if(state.viewport == _viewport)
        return;

    /* Update the state and viewport */
    state.viewport = _viewport;
    glViewport(_viewport.left(), _viewport.bottom(), _viewport.sizeX(), _viewport.sizeY());
}
void Sprite::reset(const Vector2i& size, const ResourceKey& texture) {
    /* Don't allow sprites with odd sizes */
    CORRADE_INTERNAL_ASSERT((size%2).isZero());

    _size = size/2; /* Square texture is 2x2, thus halving the size */
    _texture = Manager::instance().get<Texture2D>(texture);
}
void WireframeSpheroid::bottomHemisphere(const Float endY, const UnsignedInt rings) {
    CORRADE_INTERNAL_ASSERT(_positions.empty());

    /* Initial vertex */
    _positions.push_back(Vector3::yAxis(endY - 1.0f));

    /* Connect initial vertex to first ring */
    for(UnsignedInt i = 0; i != 4; ++i)
        _indices.insert(_indices.end(), {0, i+1});

    /* Hemisphere vertices and indices */
    const Rad ringAngleIncrement(Constants::piHalf()/rings);
    for(UnsignedInt j = 0; j != rings-1; ++j) {
        const Rad angle = Float(j+1)*ringAngleIncrement;

        _positions.emplace_back(0.0f, endY - Math::cos(angle), Math::sin(angle));
        _positions.emplace_back(Math::sin(angle), endY - Math::cos(angle), 0.0f);
        _positions.emplace_back(0.0f, endY - Math::cos(angle), -Math::sin(angle));
        _positions.emplace_back(-Math::sin(angle), endY - Math::cos(angle), 0.0f);

        /* Connect vertices to next ring */
        for(UnsignedInt i = 0; i != 4; ++i)
            _indices.insert(_indices.end(), {UnsignedInt(_positions.size())-4+i, UnsignedInt(_positions.size())+i});
    }
}
Пример #11
0
std::string AbstractObject::getLabelImplementationExt(const GLenum identifier, const GLuint name) {
    const GLenum type = extTypeFromKhrIdentifier(identifier);

    /* Get label size (w/o null terminator) */
    GLsizei size;
    /** @todo Re-enable when extension loader is available for ES */
    #ifndef MAGNUM_TARGET_GLES
    glGetObjectLabelEXT(type, name, 0, &size, nullptr);
    #else
    static_cast<void>(type);
    static_cast<void>(name);
    CORRADE_INTERNAL_ASSERT(false);
    #endif

    /* Make place also for the null terminator */
    std::string label;
    label.resize(size+1);
    /** @todo Re-enable when extension loader is available for ES */
    #ifndef MAGNUM_TARGET_GLES
    glGetObjectLabelEXT(identifier, name, size+1, nullptr, &label[0]);
    #endif

    /* Pop null terminator and return the string */
    label.resize(size);
    return label;
}
Пример #12
0
void AnyImporter::doOpenFile(const std::string& filename) {
    CORRADE_INTERNAL_ASSERT(manager());

    /* Detect type from extension */
    std::string plugin;
    if(Utility::String::endsWith(filename, ".ogg"))
        plugin = "VorbisAudioImporter";
    else if(Utility::String::endsWith(filename, ".wav"))
        plugin = "WavAudioImporter";
    else {
        Error() << "Audio::AnyImporter::openFile(): cannot determine type of file" << filename;
        return;
    }

    /* Try to load the plugin */
    if(!(manager()->load(plugin) & PluginManager::LoadState::Loaded)) {
        Error() << "Audio::AnyImporter::openFile(): cannot load" << plugin << "plugin";
        return;
    }

    /* Try to open the file (error output should be printed by the plugin
       itself) */
    std::unique_ptr<AbstractImporter> importer = static_cast<PluginManager::Manager<AbstractImporter>*>(manager())->instance(plugin);
    if(!importer->openFile(filename)) return;

    /* Success, save the instance */
    _in = std::move(importer);
}
Пример #13
0
Emitter::~Emitter() {
    for(auto connection: connections) {
        const Implementation::AbstractConnectionData* data = connection.second;

        /* Remove connection from receiver, if this is member function connection */
        if(data->type == Implementation::AbstractConnectionData::Type::Member) {
            auto& receiverConnections = static_cast<const Implementation::AbstractMemberConnectionData*>(data)->receiver->connections;
            for(auto end = receiverConnections.end(), rit = receiverConnections.begin(); rit != end; ++rit) {
                if(*rit != data) continue;

                receiverConnections.erase(rit);
                break;
            }
        }

        /* If there is connection object, remove reference to connection data
           from it and mark it as disconnected */
        if(data->connection) {
            CORRADE_INTERNAL_ASSERT(data == data->connection->data);
            data->connection->data = nullptr;
            data->connection->connected = false;
        }

        /* Delete connection data (as they make no sense without emitter) */
        delete data;
    }
}
Containers::Array<char> StbPngImageConverter::doExportToData(const ImageView2D& image) {
    #ifndef MAGNUM_TARGET_GLES
    if(image.storage().swapBytes()) {
        Error() << "Trade::StbPngImageConverter::exportToData(): pixel byte swap is not supported";
        return nullptr;
    }
    #endif

    if(image.type() != PixelType::UnsignedByte) {
        Error() << "Trade::StbPngImageConverter::exportToData(): unsupported pixel type" << image.type();
        return nullptr;
    }

    Int components;
    switch(image.format()) {
        #if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2))
        case PixelFormat::Red:
        #endif
        #ifdef MAGNUM_TARGET_GLES2
        case PixelFormat::Luminance:
        #endif
            components = 1;
            break;
        #if !(defined(MAGNUM_TARGET_WEBGL) && defined(MAGNUM_TARGET_GLES2))
        case PixelFormat::RG:
        #endif
        #ifdef MAGNUM_TARGET_GLES2
        case PixelFormat::LuminanceAlpha:
        #endif
            components = 2;
            break;
        case PixelFormat::RGB: components = 3; break;
        case PixelFormat::RGBA: components = 4; break;
        default:
            Error() << "Trade::StbPngImageConverter::exportToData(): unsupported pixel format" << image.format();
            return nullptr;
    }

    /* Data properties */
    std::size_t offset;
    Math::Vector2<std::size_t> dataSize;
    std::tie(offset, dataSize, std::ignore) = image.dataProperties();

    /* Reverse rows in image data */
    Containers::Array<unsigned char> reversedData{image.data().size()};
    for(Int y = 0; y != image.size().y(); ++y) {
        std::copy(image.data<unsigned char>() + offset + y*dataSize.x(), image.data<unsigned char>() + offset + (y + 1)*dataSize.x(), reversedData + (image.size().y() - y - 1)*dataSize.x());
    }

    Int size;
    unsigned char* const data = stbi_write_png_to_mem(reversedData, dataSize.x(), image.size().x(), image.size().y(), components, &size);
    CORRADE_INTERNAL_ASSERT(data);

    /* Wrap the data in an array with custom deleter (we can't use delete[]) */
    Containers::Array<char> fileData{reinterpret_cast<char*>(data), std::size_t(size),
        [](char* data, std::size_t) { std::free(data); }};

    return fileData;
}
Пример #15
0
Buffer::Buffer(const TargetHint targetHint): _targetHint{targetHint}, _flags{ObjectFlag::DeleteOnDestruction}
    #ifdef CORRADE_TARGET_NACL
    , _mappedBuffer{nullptr}
    #endif
{
    (this->*Context::current().state().buffer->createImplementation)();
    CORRADE_INTERNAL_ASSERT(_id != Implementation::State::DisengagedBinding);
}
Пример #16
0
void AbstractFont::close() {
    if(isOpened()) {
        doClose();
        _size = 0.0f;
        _lineHeight = 0.0f;
        CORRADE_INTERNAL_ASSERT(!isOpened());
    }
}
Пример #17
0
int DistanceFieldConverter::exec() {
    /* Load importer plugin */
    PluginManager::Manager<Trade::AbstractImporter> importerManager(Utility::Directory::join(args.value("plugin-dir"), "importers/"));
    if(!(importerManager.load(args.value("importer")) & PluginManager::LoadState::Loaded))
        return 1;
    std::unique_ptr<Trade::AbstractImporter> importer = importerManager.instance(args.value("importer"));

    /* Load converter plugin */
    PluginManager::Manager<Trade::AbstractImageConverter> converterManager(Utility::Directory::join(args.value("plugin-dir"), "imageconverters/"));
    if(!(converterManager.load(args.value("converter")) & PluginManager::LoadState::Loaded))
        return 1;
    std::unique_ptr<Trade::AbstractImageConverter> converter = converterManager.instance(args.value("converter"));

    /* Open input file */
    std::optional<Trade::ImageData2D> image;
    if(!importer->openFile(args.value("input")) || !(image = importer->image2D(0))) {
        Error() << "Cannot open file" << args.value("input");
        return 1;
    }

    /* Decide about internal format */
    TextureFormat internalFormat;
    if(image->format() == PixelFormat::Red) internalFormat = TextureFormat::R8;
    else if(image->format() == PixelFormat::RGB) internalFormat = TextureFormat::RGB8;
    else if(image->format() == PixelFormat::RGBA) internalFormat = TextureFormat::RGBA8;
    else {
        Error() << "Unsupported image format" << image->format();
        return 1;
    }

    /* Input texture */
    Texture2D input;
    input.setMinificationFilter(Sampler::Filter::Linear)
        .setMagnificationFilter(Sampler::Filter::Linear)
        .setWrapping(Sampler::Wrapping::ClampToEdge)
        .setStorage(1, internalFormat, image->size())
        .setSubImage(0, {}, *image);

    /* Output texture */
    Texture2D output;
    output.setStorage(1, TextureFormat::R8, args.value<Vector2i>("output-size"));

    CORRADE_INTERNAL_ASSERT(Renderer::error() == Renderer::Error::NoError);

    /* Do it */
    Debug() << "Converting image of size" << image->size() << "to distance field...";
    TextureTools::distanceField(input, output, {{}, args.value<Vector2i>("output-size")}, args.value<Int>("radius"), image->size());

    /* Save image */
    Image2D result(PixelFormat::Red, PixelType::UnsignedByte);
    output.image(0, result);
    if(!converter->exportToFile(result, args.value("output"))) {
        Error() << "Cannot save file" << args.value("output");
        return 1;
    }

    return 0;
}
Пример #18
0
bool NaClApplication::HandleInputEvent(const pp::InputEvent& event) {
    /* Don't handle anything during switch from/to fullscreen */
    if(flags & Flag::FullscreenSwitchInProgress) return false;

    Flags tmpFlags = flags;

    switch(event.GetType()) {
        case PP_INPUTEVENT_TYPE_KEYDOWN:
        case PP_INPUTEVENT_TYPE_KEYUP: {
            pp::KeyboardInputEvent keyEvent(event);
            KeyEvent e(static_cast<KeyEvent::Key>(keyEvent.GetKeyCode()), static_cast<InputEvent::Modifier>(keyEvent.GetModifiers()));
            event.GetType() == PP_INPUTEVENT_TYPE_KEYDOWN ? keyPressEvent(e) : keyReleaseEvent(e);
            if(!e.isAccepted()) return false;
            break;
        }

        case PP_INPUTEVENT_TYPE_MOUSEDOWN:
        case PP_INPUTEVENT_TYPE_MOUSEUP: {
            pp::MouseInputEvent mouseEvent(event);
            MouseEvent e(static_cast<MouseEvent::Button>(mouseEvent.GetButton()), {mouseEvent.GetPosition().x(), mouseEvent.GetPosition().y()}, static_cast<InputEvent::Modifier>(mouseEvent.GetModifiers()));
            event.GetType() == PP_INPUTEVENT_TYPE_MOUSEDOWN ? mousePressEvent(e) : mouseReleaseEvent(e);
            if(!e.isAccepted()) return false;
            break;
        }

        case PP_INPUTEVENT_TYPE_WHEEL: {
            pp::WheelInputEvent wheelEvent(event);
            if(Math::TypeTraits<Float>::equals(wheelEvent.GetDelta().y(), 0.0f)) return false;
            MouseEvent e(wheelEvent.GetDelta().y() > 0 ? MouseEvent::Button::WheelUp : MouseEvent::Button::WheelDown, {}, static_cast<InputEvent::Modifier>(wheelEvent.GetModifiers()));
            mousePressEvent(e);
            if(!e.isAccepted()) return false;
            break;
        }

        case PP_INPUTEVENT_TYPE_MOUSEMOVE: {
            pp::MouseInputEvent mouseEvent(event);
            MouseMoveEvent e({mouseEvent.GetPosition().x(), mouseEvent.GetPosition().y()},  {mouseEvent.GetMovement().x(), mouseEvent.GetMovement().y()}, static_cast<InputEvent::Modifier>(mouseEvent.GetModifiers()));
            mouseMoveEvent(e);
            if(!e.isAccepted()) return false;
            break;
        }

        default: return false;
    }

    /* Assume everything is properly sequential here */
    CORRADE_INTERNAL_ASSERT((tmpFlags & Flag::SwapInProgress) == (flags & Flag::SwapInProgress));

    /* Redraw, if it won't be handled after swap automatically */
    if((flags & Flag::Redraw) && !(flags & Flag::SwapInProgress)) {
        flags &= ~Flag::Redraw;
        drawEvent();
    }

    return true;
}
Пример #19
0
inline void TransformFeedback::createIfNotAlready() {
    if(_created) return;

    /* glGen*() does not create the object, just reserves the name. Some
       commands (such as glObjectLabel()) operate with IDs directly and they
       require the object to be created. Binding the transform feedback finally
       creates it. Also all EXT DSA functions implicitly create it. */
    bindInternal();
    CORRADE_INTERNAL_ASSERT(_created);
}
Пример #20
0
std::vector<std::string> Resource::list() const {
    CORRADE_INTERNAL_ASSERT(_group != resources().end());

    std::vector<std::string> result;
    result.reserve(_group->second.resources.size());
    for(const auto& filename: _group->second.resources)
        result.push_back(filename.first);

    return result;
}
void AbstractFramebuffer::createIfNotAlready() {
    if(_flags & ObjectFlag::Created) return;

    /* glGen*() does not create the object, just reserves the name. Some
       commands (such as glObjectLabel()) operate with IDs directly and they
       require the object to be created. Binding the framebuffer finally
       creates it. Also all EXT DSA functions implicitly create it. */
    bindInternal();
    CORRADE_INTERNAL_ASSERT(_flags & ObjectFlag::Created);
}
Пример #22
0
bool AbstractFont::openFile(const std::string& filename, const Float size) {
    close();
    const Metrics metrics = doOpenFile(filename, size);
    _size = metrics.size;
    _ascent = metrics.ascent;
    _descent = metrics.descent;
    _lineHeight = metrics.lineHeight;
    CORRADE_INTERNAL_ASSERT(isOpened() || (!_size && !_ascent && !_descent && !_lineHeight));
    return isOpened();
}
AbstractFramebuffer& AbstractFramebuffer::setViewport(const Range2Di& rectangle) {
    CORRADE_INTERNAL_ASSERT(rectangle != Implementation::FramebufferState::DisengagedViewport);
    _viewport = rectangle;

    /* Update the viewport if the framebuffer is currently bound */
    if(Context::current()->state().framebuffer->drawBinding == _id)
        setViewportInternal();

    return *this;
}
void Dumpster::put(Int index, Item* i) {
    CORRADE_INTERNAL_ASSERT(!_dumpsterItems[index]);

    i->setTransformation(_dumpsterPositions[index]);
    i->setParent(this);
    _drawables->add(*i);

    _dumpsterItems[index] = i;
    _dumpsterSprites[index]->reset(dumpsterSpriteSize, "dumpster-on");
}
Пример #25
0
bool Context::isDriverWorkaroundDisabled(const std::string& workaround) {
    CORRADE_INTERNAL_ASSERT(std::find(KnownWorkarounds.begin(), KnownWorkarounds.end(), workaround) != KnownWorkarounds.end());

    /* If the workaround was already asked for or disabled, return its state,
       otherwise add it to the list as used one */
    for(const auto& i: _driverWorkarounds)
        if(i.first == workaround) return i.second;
    _driverWorkarounds.emplace_back(workaround, false);
    return false;
}
Пример #26
0
AbstractQuery::AbstractQuery(): target() {
    /** @todo Re-enable when extension loader is available for ES */
    #ifndef MAGNUM_TARGET_GLES2
    glGenQueries(1, &_id);
    #elif defined(CORRADE_TARGET_NACL)
    glGenQueriesEXT(1, &_id);
    #else
    CORRADE_INTERNAL_ASSERT(false);
    #endif
}
Пример #27
0
Reflector::Reflector(Object3D* parent, SceneGraph::DrawableGroup3D* group): Object3D(parent), SceneGraph::Drawable3D(*this, group) {
    CubeMapResourceManager& resourceManager = CubeMapResourceManager::instance();

    /* Sphere mesh */
    if(!(_sphere = resourceManager.get<GL::Mesh>("sphere"))) {
        Trade::MeshData3D sphereData = Primitives::uvSphereSolid(16, 32, Primitives::UVSphereTextureCoords::Generate);

        GL::Buffer* buffer = new GL::Buffer;
        buffer->setData(MeshTools::interleave(sphereData.positions(0), sphereData.textureCoords2D(0)), GL::BufferUsage::StaticDraw);

        Containers::Array<char> indexData;
        MeshIndexType indexType;
        UnsignedInt indexStart, indexEnd;
        std::tie(indexData, indexType, indexStart, indexEnd) = MeshTools::compressIndices(sphereData.indices());

        GL::Buffer* indexBuffer = new GL::Buffer;
        indexBuffer->setData(indexData, GL::BufferUsage::StaticDraw);

        GL::Mesh* mesh = new GL::Mesh;
        mesh->setPrimitive(sphereData.primitive())
            .setCount(sphereData.indices().size())
            .addVertexBuffer(*buffer, 0, ReflectorShader::Position{}, ReflectorShader::TextureCoords{})
            .setIndexBuffer(*indexBuffer, 0, indexType, indexStart, indexEnd);

        resourceManager.set("sphere-buffer", buffer, ResourceDataState::Final, ResourcePolicy::Resident)
            .set("sphere-index-buffer", indexBuffer, ResourceDataState::Final, ResourcePolicy::Resident)
            .set(_sphere.key(), mesh, ResourceDataState::Final, ResourcePolicy::Resident);
    }

    /* Tarnish texture */
    if(!(_tarnishTexture = resourceManager.get<GL::Texture2D>("tarnish-texture"))) {
        Resource<Trade::AbstractImporter> importer = resourceManager.get<Trade::AbstractImporter>("jpeg-importer");
        Utility::Resource rs("data");
        importer->openData(rs.getRaw("tarnish.jpg"));

        Containers::Optional<Trade::ImageData2D> image = importer->image2D(0);
        CORRADE_INTERNAL_ASSERT(image);
        auto texture = new GL::Texture2D;
        texture->setWrapping(GL::SamplerWrapping::ClampToEdge)
            .setMagnificationFilter(GL::SamplerFilter::Linear)
            .setMinificationFilter(GL::SamplerFilter::Linear, GL::SamplerMipmap::Linear)
            .setStorage(Math::log2(image->size().min())+1, GL::TextureFormat::RGB8, image->size())
            .setSubImage(0, {}, *image)
            .generateMipmap();

        resourceManager.set<GL::Texture2D>(_tarnishTexture.key(), texture, ResourceDataState::Final, ResourcePolicy::Resident);
    }

    /* Reflector shader */
    if(!(_shader = resourceManager.get<GL::AbstractShaderProgram, ReflectorShader>("reflector-shader")))
        resourceManager.set<GL::AbstractShaderProgram>(_shader.key(), new ReflectorShader, ResourceDataState::Final, ResourcePolicy::Resident);

    /* Texture (created in CubeMap class) */
    _texture = resourceManager.get<GL::CubeMapTexture>("texture");
}
Пример #28
0
void AbstractQuery::end() {
#ifdef MAGNUM_BUILD_DEPRECATED
    CORRADE_INTERNAL_ASSERT(_target);
#endif

#ifndef MAGNUM_TARGET_GLES2
    glEndQuery(_target);
#else
    glEndQueryEXT(_target);
#endif
}
Пример #29
0
bool AbstractFont::openSingleData(const Containers::ArrayReference<const unsigned char> data, const Float size) {
    CORRADE_ASSERT(features() & Feature::OpenData,
        "Text::AbstractFont::openSingleData(): feature not supported", false);
    CORRADE_ASSERT(!(features() & Feature::MultiFile),
        "Text::AbstractFont::openSingleData(): the format is not single-file", false);

    close();
    std::tie(_size, _lineHeight) = doOpenSingleData(data, size);
    CORRADE_INTERNAL_ASSERT(isOpened() || (_size == 0.0f && _lineHeight == 0.0f));
    return isOpened();
}
void AbstractFramebuffer::bindImplementationSingle(FramebufferTarget) {
    Implementation::FramebufferState& state = *Context::current()->state().framebuffer;
    CORRADE_INTERNAL_ASSERT(state.readBinding == state.drawBinding);
    if(state.readBinding == _id) return;

    state.readBinding = state.drawBinding = _id;

    /* Binding the framebuffer finally creates it */
    _flags |= ObjectFlag::Created;
    glBindFramebuffer(GL_FRAMEBUFFER, _id);
}