예제 #1
0
bool FontFaceSet::remove(FontFace& face)
{
    bool result = m_backing->hasFace(face.backing());
    if (result)
        m_backing->remove(face.backing());
    return result;
}
예제 #2
0
	//--------------------------------------------------------------------------------------------------------------
	//更新字体渲染数据
	void FontManager::UpdateFont()
	{
		FontFaceList::Iterator it = mFontFaceList.Begin();
		FontFaceList::Iterator end = mFontFaceList.End();
		for(; it!=end; ++it )
		{
			FontFace* pFont = *it;
			pFont->ResetGlyphData();
		}
	}
예제 #3
0
FontFace* FontFace::create(ExecutionContext* context, const AtomicString& family, const String& source, const FontFaceDescriptors& descriptors)
{
    FontFace* fontFace = new FontFace(context, family, descriptors);

    CSSValue* src = parseCSSValue(toDocument(context), source, CSSPropertySrc);
    if (!src || !src->isValueList())
        fontFace->setError(DOMException::create(SyntaxError, "The source provided ('" + source + "') could not be parsed as a value list."));

    fontFace->initCSSFontFace(toDocument(context), src);
    return fontFace;
}
예제 #4
0
파일: Text.cpp 프로젝트: rokups/Urho3D
void Text::UpdateCharLocations()
{
    // Remember the font face to see if it's still valid when it's time to render
    FontFace* face = font_ ? font_->GetFace(fontSize_) : nullptr;
    if (!face)
        return;
    fontFace_ = face;

    auto rowHeight = RoundToInt(rowSpacing_ * rowHeight_);

    // Store position & size of each character, and locations per texture page
    unsigned numChars = unicodeText_.size();
    charLocations_.resize(numChars + 1);
    pageGlyphLocations_.resize(face->GetTextures().size());
    for (unsigned i = 0; i < pageGlyphLocations_.size(); ++i)
        pageGlyphLocations_[i].clear();

    IntVector2 offset = font_->GetTotalGlyphOffset(fontSize_);

    unsigned rowIndex = 0;
    unsigned lastFilled = 0;
    float x = Round(GetRowStartPosition(rowIndex) + offset.x_);
    float y = Round(offset.y_);

    for (unsigned i = 0; i < printText_.size(); ++i)
    {
        CharLocation loc;
        loc.position_ = Vector2(x, y);

        unsigned c = printText_[i];
        if (c != '\n')
        {
            const FontGlyph* glyph = face->GetGlyph(c);
            loc.size_ = Vector2(glyph ? glyph->advanceX_ : 0, rowHeight_);
            if (glyph)
            {
                // Store glyph's location for rendering. Verify that glyph page is valid
                if (glyph->page_ < pageGlyphLocations_.size())
                    pageGlyphLocations_[glyph->page_].push_back(GlyphLocation(x, y, glyph));
                x += glyph->advanceX_;
                if (i < printText_.size() - 1)
                    x += face->GetKerning(c, printText_[i + 1]);
            }
        }
        else
        {
            loc.size_ = Vector2::ZERO;
            x = GetRowStartPosition(++rowIndex);
            y += rowHeight;
        }

        if (lastFilled > printToText_[i])
            lastFilled = printToText_[i];

        // Fill gaps in case characters were skipped from printing
        for (unsigned j = lastFilled; j <= printToText_[i]; ++j)
            charLocations_[j] = loc;
        lastFilled = printToText_[i] + 1;
    }
    // Store the ending position
    charLocations_[numChars].position_ = Vector2(x, y);
    charLocations_[numChars].size_ = Vector2::ZERO;

    charLocationsDirty_ = false;
}
예제 #5
0
파일: Text.cpp 프로젝트: rokups/Urho3D
void Text::UpdateText(bool onResize)
{
    rowWidths_.clear();
    printText_.clear();

    if (font_)
    {
        FontFace* face = font_->GetFace(fontSize_);
        if (!face)
            return;

        rowHeight_ = face->GetRowHeight();

        int width = 0;
        int height = 0;
        int rowWidth = 0;
        auto rowHeight = RoundToInt(rowSpacing_ * rowHeight_);

        // First see if the text must be split up
        if (!wordWrap_)
        {
            printText_ = unicodeText_;
            printToText_.resize(printText_.size());
            for (unsigned i = 0; i < printText_.size(); ++i)
                printToText_[i] = i;
        }
        else
        {
            int maxWidth = GetWidth();
            unsigned nextBreak = 0;
            unsigned lineStart = 0;
            printToText_.clear();

            for (unsigned i = 0; i < unicodeText_.size(); ++i)
            {
                unsigned j;
                unsigned c = unicodeText_[i];

                if (c != '\n')
                {
                    bool ok = true;

                    if (nextBreak <= i)
                    {
                        int futureRowWidth = rowWidth;
                        for (j = i; j < unicodeText_.size(); ++j)
                        {
                            unsigned d = unicodeText_[j];
                            if (d == ' ' || d == '\n')
                            {
                                nextBreak = j;
                                break;
                            }
                            const FontGlyph* glyph = face->GetGlyph(d);
                            if (glyph)
                            {
                                futureRowWidth += glyph->advanceX_;
                                if (j < unicodeText_.size() - 1)
                                    futureRowWidth += face->GetKerning(d, unicodeText_[j + 1]);
                            }
                            if (d == '-' && futureRowWidth <= maxWidth)
                            {
                                nextBreak = j + 1;
                                break;
                            }
                            if (futureRowWidth > maxWidth)
                            {
                                ok = false;
                                break;
                            }
                        }
                    }

                    if (!ok)
                    {
                        // If did not find any breaks on the line, copy until j, or at least 1 char, to prevent infinite loop
                        if (nextBreak == lineStart)
                        {
                            while (i < j)
                            {
                                printText_.push_back(unicodeText_[i]);
                                printToText_.push_back(i);
                                ++i;
                            }
                        }
                        // Eliminate spaces that have been copied before the forced break
                        while (printText_.size() && printText_.back() == ' ')
                        {
                            printText_.pop_back();
                            printToText_.pop_back();
                        }
                        printText_.push_back('\n');
                        printToText_.push_back(Min(i, unicodeText_.size() - 1));
                        rowWidth = 0;
                        nextBreak = lineStart = i;
                    }

                    if (i < unicodeText_.size())
                    {
                        // When copying a space, position is allowed to be over row width
                        c = unicodeText_[i];
                        const FontGlyph* glyph = face->GetGlyph(c);
                        if (glyph)
                        {
                            rowWidth += glyph->advanceX_;
                            if (i < unicodeText_.size() - 1)
                                rowWidth += face->GetKerning(c, unicodeText_[i + 1]);
                        }
                        if (rowWidth <= maxWidth)
                        {
                            printText_.push_back(c);
                            printToText_.push_back(i);
                        }
                    }
                }
                else
                {
                    printText_.push_back('\n');
                    printToText_.push_back(Min(i, unicodeText_.size() - 1));
                    rowWidth = 0;
                    nextBreak = lineStart = i;
                }
            }
        }

        rowWidth = 0;

        for (unsigned i = 0; i < printText_.size(); ++i)
        {
            unsigned c = printText_[i];

            if (c != '\n')
            {
                const FontGlyph* glyph = face->GetGlyph(c);
                if (glyph)
                {
                    rowWidth += glyph->advanceX_;
                    if (i < printText_.size() - 1)
                        rowWidth += face->GetKerning(c, printText_[i + 1]);
                }
            }
            else
            {
                width = Max(width, rowWidth);
                height += rowHeight;
                rowWidths_.push_back(rowWidth);
                rowWidth = 0;
            }
        }

        if (rowWidth)
        {
            width = Max(width, rowWidth);
            height += rowHeight;
            rowWidths_.push_back(rowWidth);
        }

        // Set at least one row height even if text is empty
        if (!height)
            height = rowHeight;

        // Set minimum and current size according to the text size, but respect fixed width if set
        if (!IsFixedWidth())
        {
            if (wordWrap_)
                SetMinWidth(0);
            else
            {
                SetMinWidth(width);
                SetWidth(width);
            }
        }
        SetFixedHeight(height);

        charLocationsDirty_ = true;
    }
    else
    {
        // No font, nothing to render
        pageGlyphLocations_.clear();
    }

    // If wordwrap is on, parent may need layout update to correct for overshoot in size. However, do not do this when the
    // update is a response to resize, as that could cause infinite recursion
    if (wordWrap_ && !onResize)
    {
        UIElement* parent = GetParent();
        if (parent && parent->GetLayoutMode() != LM_FREE)
            parent->UpdateLayout();
    }
}
예제 #6
0
파일: Text.cpp 프로젝트: rokups/Urho3D
void Text::GetBatches(ea::vector<UIBatch>& batches, ea::vector<float>& vertexData, const IntRect& currentScissor)
{
    FontFace* face = font_ ? font_->GetFace(fontSize_) : nullptr;
    if (!face)
    {
        hovering_ = false;
        return;
    }

    // If face has changed or char locations are not valid anymore, update before rendering
    if (charLocationsDirty_ || !fontFace_ || face != fontFace_)
        UpdateCharLocations();
    // If face uses mutable glyphs mechanism, reacquire glyphs before rendering to make sure they are in the texture
    else if (face->HasMutableGlyphs())
    {
        for (unsigned i = 0; i < printText_.size(); ++i)
            face->GetGlyph(printText_[i]);
    }

    // Hovering and/or whole selection batch
    UISelectable::GetBatches(batches, vertexData, currentScissor);

    // Partial selection batch
    if (!selected_ && selectionLength_ && charLocations_.size() >= selectionStart_ + selectionLength_ && selectionColor_.a_ > 0.0f)
    {
        UIBatch batch(this, BLEND_ALPHA, currentScissor, nullptr, &vertexData);
        batch.SetColor(selectionColor_);

        Vector2 currentStart = charLocations_[selectionStart_].position_;
        Vector2 currentEnd = currentStart;
        for (unsigned i = selectionStart_; i < selectionStart_ + selectionLength_; ++i)
        {
            // Check if row changes, and start a new quad in that case
            if (charLocations_[i].size_ != Vector2::ZERO)
            {
                if (charLocations_[i].position_.y_ != currentStart.y_)
                {
                    batch.AddQuad(currentStart.x_, currentStart.y_, currentEnd.x_ - currentStart.x_,
                        currentEnd.y_ - currentStart.y_, 0, 0);
                    currentStart = charLocations_[i].position_;
                    currentEnd = currentStart + charLocations_[i].size_;
                }
                else
                {
                    currentEnd.x_ += charLocations_[i].size_.x_;
                    currentEnd.y_ = Max(currentStart.y_ + charLocations_[i].size_.y_, currentEnd.y_);
                }
            }
        }
        if (currentEnd != currentStart)
        {
            batch.AddQuad(currentStart.x_, currentStart.y_, currentEnd.x_ - currentStart.x_, currentEnd.y_ - currentStart.y_, 0, 0);
        }

        UIBatch::AddOrMerge(batch, batches);
    }

    // Text batch
    TextEffect textEffect = font_->IsSDFFont() ? TE_NONE : textEffect_;
    const ea::vector<ea::shared_ptr<Texture2D> >& textures = face->GetTextures();
    for (unsigned n = 0; n < textures.size() && n < pageGlyphLocations_.size(); ++n)
    {
        // One batch per texture/page
        UIBatch pageBatch(this, BLEND_ALPHA, currentScissor, textures[n], &vertexData);

        const ea::vector<GlyphLocation>& pageGlyphLocation = pageGlyphLocations_[n];

        switch (textEffect)
        {
        case TE_NONE:
            ConstructBatch(pageBatch, pageGlyphLocation, 0, 0);
            break;

        case TE_SHADOW:
            ConstructBatch(pageBatch, pageGlyphLocation, shadowOffset_.x_, shadowOffset_.y_, &effectColor_, effectDepthBias_);
            ConstructBatch(pageBatch, pageGlyphLocation, 0, 0);
            break;

        case TE_STROKE:
            if (roundStroke_)
            {
                // Samples should be even or glyph may be redrawn in wrong x y pos making stroke corners rough
                // Adding to thickness helps with thickness of 1 not having enought samples for this formula
                // or certain fonts with reflex corners requiring more glyph samples for a smooth stroke when large
                int thickness = Min(strokeThickness_, fontSize_);
                int samples = thickness * thickness + (thickness % 2 == 0 ? 4 : 3);
                float angle = 360.f / samples;
                auto floatThickness = (float)thickness;
                for (int i = 0; i < samples; ++i)
                {
                    float x = Cos(angle * i) * floatThickness;
                    float y = Sin(angle * i) * floatThickness;
                    ConstructBatch(pageBatch, pageGlyphLocation, x, y, &effectColor_, effectDepthBias_);
                }
            }
            else
            {
                int thickness = Min(strokeThickness_, fontSize_);
                int x, y;
                for (x = -thickness; x <= thickness; ++x)
                {
                    for (y = -thickness; y <= thickness; ++y)
                    {
                        // Don't draw glyphs that aren't on the edges
                        if (x > -thickness && x < thickness &&
                            y > -thickness && y < thickness)
                            continue;

                        ConstructBatch(pageBatch, pageGlyphLocation, x, y, &effectColor_, effectDepthBias_);
                    }
                }
            }
            ConstructBatch(pageBatch, pageGlyphLocation, 0, 0);
            break;
        }

        UIBatch::AddOrMerge(pageBatch, batches);
    }
}
예제 #7
0
void Context::setFontFace( const FontFace &font_face )
{
	cairo_set_font_face( mCairo, font_face.getCairoFontFace() );
}
예제 #8
0
bool FontFaceSet::has(FontFace& face) const
{
    return m_backing->hasFace(face.backing());
}
예제 #9
0
    Glyph::Glyph(FT_Library &library, FontFace &fontFace, int c, int outlineWidth, bool hinting) :
    mFont(fontFace)
    {
        mChar = c;
        
        FT_Face &face = fontFace.GetFTFace();

        int flags = FT_LOAD_DEFAULT;
        if (!hinting)
        {
            flags = FT_LOAD_NO_AUTOHINT | FT_LOAD_NO_HINTING;
        }
        
        FT_Error error = FT_Load_Char(face, c, flags);
        if (error) {
            return;
        }
        
        mGlyphIndex = FT_Get_Char_Index(face, c);
        
        // Load The Glyph For Our Character.
        if(FT_Load_Glyph( face, mGlyphIndex, flags ))
            throw std::runtime_error("FT_Load_Glyph failed");
        
        // Move The Face's Glyph Into A Glyph Object.
        FT_Glyph glyph;
        if(FT_Get_Glyph( face->glyph, &glyph ))
            throw std::runtime_error("FT_Get_Glyph failed");
        
        FT_Stroker stroker;
        FT_Stroker_New(library, &stroker);
        FT_Stroker_Set(stroker, outlineWidth * 64, FT_STROKER_LINECAP_ROUND, FT_STROKER_LINEJOIN_ROUND, 0);
        FT_Glyph_StrokeBorder(&glyph, stroker, false, true);
        
        FT_OutlineGlyph olglyph = reinterpret_cast<FT_OutlineGlyph>(glyph);
        
        FT_Outline outline = olglyph->outline;
        
        RenderSpans(library, &outline);
        
        FT_Stroker_Done(stroker);
        
        // Get metrics
        FT_Glyph_Metrics metrics = face->glyph->metrics;
        mAdvance.x = metrics.horiAdvance * kOneOver64;
        mAdvance.y = metrics.vertAdvance * kOneOver64;
        
        mBearing.x = metrics.horiBearingX * kOneOver64;
        mBearing.y = metrics.horiBearingY * kOneOver64;
        
        mSize.x = glm::round(metrics.width * kOneOver64);
        mSize.y = glm::round(metrics.height * kOneOver64);
        
        // Adjust for outline?
        mAdvance.x += outlineWidth;
        
        // Draw spans
        if(mSpans.size() > 0)
        {
            GlyphSpan front = mSpans.front();
            Rect bounds(front.x, front.y, front.x, front.y);
            for(int i = 0; i < mSpans.size(); i++)
            {
                bounds.Include(mSpans[i].x, mSpans[i].y + 1);
                bounds.Include(mSpans[i].x + mSpans[i].width, mSpans[i].y);
            }
            
            int width = bounds.GetWidth();
            int height = bounds.GetHeight();
            
            mDataSize.x = width;
            mDataSize.y = height;
            
            int size = width * height;
            
            mBuffer = new unsigned char[size];
            memset(mBuffer, 0, size);
            for(int i = 0; i < mSpans.size(); i++)
            {
                GlyphSpan &span = mSpans[i];
                for (int w = 0; w < span.width; ++w)
                {
                    mBuffer[(int)((height - 1 - (span.y - bounds.top)) * width
                                  + span.x - bounds.left + w)] = span.coverage;
                }
            }
        }
        FT_Done_Glyph(glyph);
    }
예제 #10
0
FontFace* FontFace::create(ExecutionContext* context, const AtomicString& family, DOMArrayBuffer* source, const FontFaceDescriptors& descriptors)
{
    FontFace* fontFace = new FontFace(context, family, descriptors);
    fontFace->initCSSFontFace(static_cast<const unsigned char*>(source->data()), source->byteLength());
    return fontFace;
}
예제 #11
0
FontFace* FontFace::create(Document* document, const StyleRuleFontFace* fontFaceRule)
{
    const StylePropertySet& properties = fontFaceRule->properties();

    // Obtain the font-family property and the src property. Both must be defined.
    CSSValue* family = properties.getPropertyCSSValue(CSSPropertyFontFamily);
    if (!family || (!family->isFontFamilyValue() && !family->isPrimitiveValue()))
        return nullptr;
    CSSValue* src = properties.getPropertyCSSValue(CSSPropertySrc);
    if (!src || !src->isValueList())
        return nullptr;

    FontFace* fontFace = new FontFace(document);

    if (fontFace->setFamilyValue(*family)
        && fontFace->setPropertyFromStyle(properties, CSSPropertyFontStyle)
        && fontFace->setPropertyFromStyle(properties, CSSPropertyFontWeight)
        && fontFace->setPropertyFromStyle(properties, CSSPropertyFontStretch)
        && fontFace->setPropertyFromStyle(properties, CSSPropertyUnicodeRange)
        && fontFace->setPropertyFromStyle(properties, CSSPropertyFontVariant)
        && fontFace->setPropertyFromStyle(properties, CSSPropertyFontFeatureSettings)
        && fontFace->setPropertyFromStyle(properties, CSSPropertyFontDisplay)
        && !fontFace->family().isEmpty()
        && fontFace->traits().bitfield()) {
        fontFace->initCSSFontFace(document, src);
        return fontFace;
    }
    return nullptr;
}
예제 #12
0
FontFace * FontImporter::loadFont(const std::string & filename)
{
    std::ifstream in(filename, std::ios::in | std::ios::binary);

    if (!in)
    {
        return nullptr;
    }

    FontFace * font = new FontFace();

    std::string line;
    std::string identifier;
    while (std::getline(in, line))
    {
        std::stringstream ss(line);

        if (std::getline(ss, identifier, ' '))
        {
            if (identifier == "info")
            {
                handleInfo(ss, font);
            }
            else if (identifier == "common")
            {
                handleCommon(ss, font);
            }
            else if (identifier == "page")
            {
                handlePage(ss, font, filename);
            }
            else if (identifier == "chars")
            {
                handleChars(ss, font);
            }
            else if (identifier == "char")
            {
                handleChar(ss, font);
            }
            else if (identifier == "kernings")
            {
                handleKernings(ss, font);
            }
            else if (identifier == "kerning")
            {
                handleKerning(ss, font);
            }
            else
            {
                assert(false);
            }
        }
        else
        {
            assert(false);
        }
    }

    if (!font->glyphTexture())
    {
        delete font;

        return nullptr;
    }

    return font;
}
예제 #13
0
BasicSceneExample::BasicSceneExample(int argc, const char* argv[]):
	ExampleApplication("Basic Scene", argc, argv)
{
	// Open Sans
	openSans = new FontFamily(resourceContext->getFontManager());

	openSans->setName("Open Sans");
	FontFace* openSansRegular = openSans->createFontFace();
	openSansRegular->setSource("data/fonts/Open_Sans/OpenSans-Regular.ttf");

	FontFace* openSansItalic = openSans->createFontFace();
	openSansItalic->setSource("data/fonts/Open_Sans/OpenSans-Italic.ttf");
	openSansItalic->setStyle(FontStyle::ITALIC);

	FontFace* openSansBold = openSans->createFontFace();
	openSansBold->setSource("data/fonts/Open_Sans/OpenSans-Bold.ttf");
	openSansBold->setWeight(FontWeight::BOLD);

	FontFace* openSansBoldItalic = openSans->createFontFace();
	openSansBoldItalic->setSource("data/fonts/Open_Sans/OpenSans-BoldItalic.ttf");
	openSansBoldItalic->setStyle(FontStyle::ITALIC);
	openSansBoldItalic->setWeight(FontWeight::BOLD);

	SharedFont font = openSansItalic->getFont(22);
	if (!font)
	{
		std::cerr << "Failed to find font.\n";
	}

	// Load meshes
	object = resourceContext->getMeshManager()->load("data/models/Hexapod.mesh");
	lightMesh = resourceContext->getMeshManager()->load("data/models/circle.obj");
	checker = resourceContext->getImageManager()->load("data/textures/checker2.tga", true);

	//scene.addChild(new AmbientCubeNode(&ambientCube));

	floor = resourceContext->getMeshManager()->load("data/models/CheckerFloor.obj");

	// Setup camera
	camera.setLens(20.0f, 24.0f);
	camera.setAspectRatio(graphicsContext->getViewport().getAspectRatio());
	camera.setClipNear(0.1f);
	camera.setClipFar(100.0f);
	camera.lookAt(
		{0.0f, 0.0f, 3.0f},
		{0.0f, 0.0f, 0.0f},
		{0.0f, 1.0f, 0.0f});
	camera.update();

	orthoCamera.setClipTop(0.0f);
	orthoCamera.setClipLeft(0.0f);
	orthoCamera.setClipBottom(window->getHeight());
	orthoCamera.setClipRight(window->getWidth());
	orthoCamera.setClipNear(-1.0f);
	orthoCamera.setClipFar(1.0f);
	orthoCamera.lookAt(
		{0.0f, 0.0f, 0.0f},
		{0.0f, 0.0f, -1.0f},
		{0.0f, 1.0f, 0.0f});
	orthoCamera.update();
	
	yaw = 0.0f;
	pitch = 0.0f;
	mouseDown = false;
	
	// Setup lighting
	light.setColor({1.0f, 1.0f, 1.0f});
	light.setPosition({0.0f, 2.5f, 4.0f});
	light.setAttenuation({1.0f, 0.025f, 0.01f});
	light.setDirection(-light.getPosition().normalized());
	light.setCutoff(std::cos(math::radians<float>(30.0f)));
	light.setExponent(20.0f);

	plight.setColor(light.getColor());
	plight.setPosition(light.getPosition());
	plight.setAttenuation(light.getAttenuation());

	sun.setColor({1.0f, 1.0f, 1.0f});
	sun.setDirection(Vector<3, float>(0.75f, -0.5f, -1.0f).normalized());

	// Add lights to scene
	//scene.addChild(new SpotlightNode(&light));
	scene.addChild(new DirectionalLightNode(&sun));
	//scene.addChild(new PointLightNode(&plight));
	
	// Add geometry to scene
	scene.addChild(new GeometryNode(floor));

	GeometryNode* objectNode = nullptr;
	if (object->getSkeleton() && object->getSkeleton()->isLoaded())
	{
		// Pose
		const Skeleton* skeleton = object->getSkeleton().get();
		pose = new SkeletonPose(skeleton);
		objectNode = new RiggedGeometryNode(object, pose);
	}
	else
	{
		objectNode = new GeometryNode(object);
	}

	float objectHeight = (object->getAABB().getMax() - object->getAABB().getMin()).y;
	Vector<3, float> objectPosition = (object->getAABB().getMin() + object->getAABB().getMax()) * -0.5f;
	objectPosition.y += objectHeight * 0.5f;

	/*
	FogNode* fogNode = new FogNode();
	fogNode->setFogMode(FogMode::EXPONENTIAL_SQUARED);
	fogNode->setFogColor({1.0f, 1.0f, 1.0f});
	fogNode->setFogDensity(0.25f);
	scene.addChild(fogNode);
	*/

	SharedImage skyboxCubeMap = resourceContext->getImageManager()->load(
		"data/textures/cubemap_positive_x.tga",
		"data/textures/cubemap_negative_x.tga",
		"data/textures/cubemap_positive_y.tga",
		"data/textures/cubemap_negative_y.tga",
		"data/textures/cubemap_positive_z.tga",
		"data/textures/cubemap_negative_z.tga",
		true);
	SkyboxNode* skyboxNode = new SkyboxNode(skyboxCubeMap);
	scene.addChild(skyboxNode);

	camera.lookAt(
		{0.0f, objectHeight * 0.5f, 3.0f},
		{0.0f, objectHeight * 0.5f, 0.0f},
		{0.0f, 1.0f, 0.0f});
	camera.update();

	TransformNode* transform = new TransformNode();
	transform->setLocalTransform(
		Transform<float>(
			{objectPosition},
			{0, 0, 0, 1},
			{1.0f, 1.0f, 1.0f}));
	transform->addChild(objectNode);
	scene.addChild(transform);

	BillboardNode* billboardNode = new BillboardNode();
	billboardNode->setAlignment(BillboardAlignment::SCREEN);
	billboardNode->addChild(new GeometryNode(lightMesh));

	transform = new TransformNode();
	transform->setLocalTransform(
		Transform<float>(
			light.getPosition(),
			{0.0f, 0.0f, 0.0f, 1.0f},
			{1.0f, 1.0f, 1.0f}));
	transform->addChild(billboardNode);
	scene.addChild(transform);
	
	// Setup controls
	Keyboard* keyboard = getInputManager()->getKeyboard(0);
	moveForward = new KeyboardAction(keyboard, KeyCode::W);
	moveBack = new KeyboardAction(keyboard, KeyCode::S);
	strafeLeft = new KeyboardAction(keyboard, KeyCode::A);
	strafeRight = new KeyboardAction(keyboard, KeyCode::D);
	rollCW = new KeyboardAction(keyboard, KeyCode::E);
	rollCCW = new KeyboardAction(keyboard, KeyCode::Q);
	increaseAction = new KeyboardAction(keyboard, KeyCode::EQUALS);
	decreaseAction = new KeyboardAction(keyboard, KeyCode::MINUS);

	up = {0.0f, 1.0f, 0.0f};

	//graphicsContext->setClearColor({0.145f, 0.145f, 0.145f, 0.0f});
	
	getInputManager()->getMouse(0)->addObserver(this);
}
예제 #14
0
파일: Text.cpp 프로젝트: mrsaleh/Urho3D
void Text::GetBatches(PODVector<UIBatch>& batches, PODVector<float>& vertexData, const IntRect& currentScissor)
{
    FontFace* face = font_ ? font_->GetFace(fontSize_) : (FontFace*)0;
    if (!face)
    {
        hovering_ = false;
        return;
    }

    // If face has changed or char locations are not valid anymore, update before rendering
    if (charLocationsDirty_ || !fontFace_ || face != fontFace_)
        UpdateCharLocations();
    // If face uses mutable glyphs mechanism, reacquire glyphs before rendering to make sure they are in the texture
    else if (face->HasMutableGlyphs())
    {
        for (unsigned i = 0; i < printText_.Size(); ++i)
            face->GetGlyph(printText_[i]);
    }

    // Hovering and/or whole selection batch
    if ((hovering_ && hoverColor_.a_ > 0.0) || (selected_ && selectionColor_.a_ > 0.0f))
    {
        bool both = hovering_ && selected_ && hoverColor_.a_ > 0.0 && selectionColor_.a_ > 0.0f;
        UIBatch batch(this, BLEND_ALPHA, currentScissor, 0, &vertexData);
        batch.SetColor(both ? selectionColor_.Lerp(hoverColor_, 0.5f) :
            (selected_ && selectionColor_.a_ > 0.0f ? selectionColor_ : hoverColor_));
        batch.AddQuad(0, 0, GetWidth(), GetHeight(), 0, 0);
        UIBatch::AddOrMerge(batch, batches);
    }

    // Partial selection batch
    if (!selected_ && selectionLength_ && charLocations_.Size() >= selectionStart_ + selectionLength_ && selectionColor_.a_ > 0.0f)
    {
        UIBatch batch(this, BLEND_ALPHA, currentScissor, 0, &vertexData);
        batch.SetColor(selectionColor_);

        IntVector2 currentStart = charLocations_[selectionStart_].position_;
        IntVector2 currentEnd = currentStart;
        for (unsigned i = selectionStart_; i < selectionStart_ + selectionLength_; ++i)
        {
            // Check if row changes, and start a new quad in that case
            if (charLocations_[i].size_ != IntVector2::ZERO)
            {
                if (charLocations_[i].position_.y_ != currentStart.y_)
                {
                    batch.AddQuad(currentStart.x_, currentStart.y_, currentEnd.x_ - currentStart.x_,
                        currentEnd.y_ - currentStart.y_, 0, 0);
                    currentStart = charLocations_[i].position_;
                    currentEnd = currentStart + charLocations_[i].size_;
                }
                else
                {
                    currentEnd.x_ += charLocations_[i].size_.x_;
                    currentEnd.y_ = Max(currentStart.y_ + charLocations_[i].size_.y_, currentEnd.y_);
                }
            }
        }
        if (currentEnd != currentStart)
        {
            batch.AddQuad(currentStart.x_, currentStart.y_, currentEnd.x_ - currentStart.x_, currentEnd.y_ - currentStart.y_, 0, 0);
        }

        UIBatch::AddOrMerge(batch, batches);
    }

    // Text batch
    TextEffect textEffect = font_->IsSDFFont() ? TE_NONE : textEffect_;
    const Vector<SharedPtr<Texture2D> >& textures = face->GetTextures();
    for (unsigned n = 0; n < textures.Size() && n < pageGlyphLocations_.Size(); ++n)
    {
        // One batch per texture/page
        UIBatch pageBatch(this, BLEND_ALPHA, currentScissor, textures[n], &vertexData);

        const PODVector<GlyphLocation>& pageGlyphLocation = pageGlyphLocations_[n];

        switch (textEffect)
        {
        case TE_NONE:
            ConstructBatch(pageBatch, pageGlyphLocation, 0, 0);
            break;

        case TE_SHADOW:
            ConstructBatch(pageBatch, pageGlyphLocation, 1, 1, &effectColor_, effectDepthBias_);
            ConstructBatch(pageBatch, pageGlyphLocation, 0, 0);
            break;

        case TE_STROKE:
            ConstructBatch(pageBatch, pageGlyphLocation, -1, -1, &effectColor_, effectDepthBias_);
            ConstructBatch(pageBatch, pageGlyphLocation, 0, -1, &effectColor_, effectDepthBias_);
            ConstructBatch(pageBatch, pageGlyphLocation, 1, -1, &effectColor_, effectDepthBias_);
            ConstructBatch(pageBatch, pageGlyphLocation, -1, 0, &effectColor_, effectDepthBias_);
            ConstructBatch(pageBatch, pageGlyphLocation, 1, 0, &effectColor_, effectDepthBias_);
            ConstructBatch(pageBatch, pageGlyphLocation, -1, 1, &effectColor_, effectDepthBias_);
            ConstructBatch(pageBatch, pageGlyphLocation, 0, 1, &effectColor_, effectDepthBias_);
            ConstructBatch(pageBatch, pageGlyphLocation, 1, 1, &effectColor_, effectDepthBias_);
            ConstructBatch(pageBatch, pageGlyphLocation, 0, 0);
            break;
        }

        UIBatch::AddOrMerge(pageBatch, batches);
    }

    // Reset hovering for next frame
    hovering_ = false;
}