#include "STDMaterial.h" #include "VisualStyle.h" #include "Sprite.h" #include "TextField.h" #include "text_utils/Node.h" #include "ColorRectSprite.h" #include "RenderState.h" #include "STDRenderer.h" #include "MaskedRenderer.h" #include "MaskedSprite.h" #include "ClipRectActor.h" #include "core/oxygine.h" #include "res/ResFont.h" namespace oxygine { STDMaterial* STDMaterial::instance = 0; void Material::render(Actor* parent, const RenderState& parentRS) { RenderState rs; if (!parent->internalRender(rs, parentRS)) return; Actor* actor = parent->getFirstChild().get(); while (actor) { OX_ASSERT(actor->getParent()); actor->render(rs); actor = actor->getNextSibling().get(); } } void STDMaterial::setViewProj(const Matrix& vp) { _renderer->setViewProjTransform(vp); } void STDMaterial::render(ClipRectActor* actor, const RenderState& parentRS) { //Material::render(actor, parentRS); //return; Material::setCurrent(this); RenderState rs = parentRS; const RectF* parentClippedRect = parentRS.clip; RectF clippedRect = *parentClippedRect; rs.clip = &clippedRect; Rect scissorRect(0, 0, 0, 0); bool scissorEnabled = _renderer->getDriver()->getScissorRect(scissorRect); bool vis = true; if (actor->getClipping()) { _renderer->drawBatch(); RectF ss_rect = getActorTransformedDestRect(actor, actor->getTransform() * parentRS.transform); clippedRect.clip(ss_rect); if (!clippedRect.isEmpty()) { Rect gl_rect = Rect( int(clippedRect.pos.x + 0.01f), int(clippedRect.pos.y + 0.01f), int(clippedRect.size.x + 0.01f), int(clippedRect.size.y + 0.01f)); if (!_renderer->getDriver()->getRenderTarget()->getHandle()) { Point vp_size = core::getDisplaySize(); gl_rect.pos.y = vp_size.y - gl_rect.getBottom(); } _renderer->getDriver()->setScissorRect(&gl_rect); } else { vis = false; } } if (vis) actor->Actor::render(rs); if (actor->getClipping()) { _renderer->drawBatch(); _renderer->getDriver()->setScissorRect(scissorEnabled ? &scissorRect : 0); } } void STDMaterial::render(MaskedSprite* sprite, const RenderState& parentRS) { Material::setCurrent(this); spSprite mask = sprite->getMask(); if (mask && mask->getAnimFrame().getDiffuse().base) { Transform t = mask->computeGlobalTransform(); RectF maskDest = mask->getDestRect(); RectF maskSrc = mask->getSrcRect(); const Diffuse& df = mask->getAnimFrame().getDiffuse(); bool useR = sprite->getUseRChannel(); bool rchannel = useR ? true : (df.alpha ? true : false); spNativeTexture msk = useR ? df.base : (df.alpha ? df.alpha : df.base); STDRenderer* original = _renderer; _renderer->drawBatch(); MaskedRenderer mr(msk, maskSrc, maskDest, t, rchannel, original->getDriver()); mr.begin(_renderer); _renderer = &mr; RenderState rs = parentRS; sprite->Sprite::render(rs); mr.end(); _renderer = original; } else { sprite->Sprite::render(parentRS); } } void STDMaterial::doRender(Sprite* sprite, const RenderState& rs) { Material::setCurrent(rs.material); const AnimationFrame& frame = sprite->getAnimFrame(); const Diffuse& df = frame.getDiffuse(); const spNativeTexture& base = df.base; #ifdef EMSCRIPTEN _renderer->setTexture(df.base, df.alpha, df.premultiplied);//preload if (base && base->getHandle()) #else if (base) #endif { _renderer->setBlendMode(sprite->getBlendMode()); #ifndef EMSCRIPTEN _renderer->setTexture(df.base, df.alpha, df.premultiplied);//preload #endif _renderer->setTransform(rs.transform); _renderer->draw(rs.getFinalColor(sprite->getColor()), frame.getSrcRect(), sprite->getDestRect()); } } void STDMaterial::doRender(TextField* tf, const RenderState& rs) { float scale = sqrtf(rs.transform.a * rs.transform.a + rs.transform.c * rs.transform.c); text::Node* root = tf->getRootNode(scale); if (!root) return; Material::setCurrent(this); text::DrawContext dc; dc.primary = rs.getFinalColor(tf->getColor()).premultiplied(); dc.color = tf->getStyle().color * dc.primary; dc.renderer = _renderer; _renderer->setBlendMode(tf->getBlendMode()); _renderer->setTransform(rs.transform); int sdfSize; if (tf->getFont()->isSDF(sdfSize)) { if (tf->getFontSize()) scale = scale * tf->getFontSize() / sdfSize; float contrast = 3.0f + scale * 8.0f; float offset = tf->getWeight(); float outline = tf->getWeight() - tf->getOutline(); _renderer->beginSDFont(contrast, offset, tf->getOutlineColor(), outline); root->draw(dc); _renderer->endSDFont(); } else { _renderer->beginElementRendering(true); root->draw(dc); } } void STDMaterial::doRender(ColorRectSprite* sprite, const RenderState& rs) { Material::setCurrent(this); _renderer->setBlendMode(sprite->getBlendMode()); _renderer->setTexture(STDRenderer::white); _renderer->setTransform(rs.transform); _renderer->draw(rs.getFinalColor(sprite->getColor()), RectF(0, 0, 1, 1), sprite->getDestRect()); } void STDMaterial::doRender(ProgressBar*, const RenderState& rs) { } void STDMaterial::apply(Material* prev) { _renderer->begin(0); _renderer->setUberShaderProgram(&STDRenderer::uberShader); } void STDMaterial::finish() { if (!_renderer) return; _renderer->end(); } }