void STDRenderer::beginSDFont(float contrast, float offset, const Color& outlineColor, float outlineOffset) { if (_alpha) { drawBatch(); _shaderFlags &= ~UberShaderProgram::SEPARATE_ALPHA; _alpha = 0; } unsigned int shaderFlags = _shaderFlags; shaderFlags |= UberShaderProgram::SDF; if (outlineOffset < offset) shaderFlags |= UberShaderProgram::SDF_OUTLINE; if (_shaderFlags != shaderFlags) { drawBatch(); } _shaderFlags = shaderFlags; ShaderProgram* prog = _uberShader->getShaderProgram(_shaderFlags)->program; setShader(prog); Vector4 c; c = Vector4(outlineColor.getRedF(), outlineColor.getGreenF(), outlineColor.getBlueF(), outlineColor.getAlphaF()); _driver->setUniform("sdf_outline_color", &c, 1); c = Vector4(offset, contrast, outlineOffset, contrast); _driver->setUniform("sdf_params", &c, 1); }
void STDRenderer::end() { drawBatch(); if (_previous) _previous->begin(0); }
void STDRenderer::setTexture(spNativeTexture base, spNativeTexture alpha, bool basePremultiplied) { if (base == 0 || base->getHandle() == 0) base = white; unsigned int shaderFlags = _shaderFlags; if (basePremultiplied) shaderFlags &= ~UberShaderProgram::ALPHA_PREMULTIPLY; else shaderFlags |= UberShaderProgram::ALPHA_PREMULTIPLY; if (alpha) shaderFlags |= UberShaderProgram::SEPARATE_ALPHA; else shaderFlags &= ~UberShaderProgram::SEPARATE_ALPHA; //##ifdef OX_DEBUG #if 0 if (_base != base) { OX_ASSERT(_alpha != alpha); } else { OX_ASSERT(_alpha == alpha); } #endif //OX_DEBUG //no reason to check changed alpha because it is in pair with base if (_base != base || /*_alpha != alpha || */_shaderFlags != shaderFlags) { drawBatch(); } _shaderFlags = shaderFlags; _base = base; _alpha = alpha; }
void STDRenderer::setBlendMode(blend_mode blend) { if (_blend != blend) { drawBatch(); switch (blend) { case blend_disabled: _driver->setState(IVideoDriver::STATE_BLEND, 0); break; case blend_premultiplied_alpha: _driver->setBlendFunc(IVideoDriver::BT_ONE, IVideoDriver::BT_ONE_MINUS_SRC_ALPHA); break; case blend_alpha: _driver->setBlendFunc(IVideoDriver::BT_SRC_ALPHA, IVideoDriver::BT_ONE_MINUS_SRC_ALPHA); break; case blend_add: _driver->setBlendFunc(IVideoDriver::BT_ONE, IVideoDriver::BT_ONE); break; //case blend_sub: //_driver->setBlendFunc(IVideoDriver::BT_ONE, IVideoDriver::BT_ONE); //glBlendEquation(GL_FUNC_REVERSE_SUBTRACT); // break; default: OX_ASSERT(!"unknown blend"); } if (_blend == blend_disabled) { _driver->setState(IVideoDriver::STATE_BLEND, 1); } _blend = blend; } }
void STDRenderer::endSDFont() { drawBatch(); _shaderFlags &= ~(UberShaderProgram::SDF | UberShaderProgram::SDF_OUTLINE); ShaderProgram* prog = _uberShader->getShaderProgram(_shaderFlags)->program; setShader(prog); }
void STDRenderer::setUberShaderProgram(UberShaderProgram* pr) { if (_uberShader != pr) { drawBatch(); } _uberShader = pr; }
void STDRenderer::drawElement(const spNativeTexture& texture, unsigned int color, const RectF& src, const RectF& dest) { if (_base != texture) { drawBatch(); _base = texture; } vertexPCT2 v[4]; fillQuadT(v, src, dest, _transform, color); addVertices(v, sizeof(v)); }
void STDRenderer::beginElementRendering(bool basePremultiplied) { if (_alpha) { drawBatch(); _shaderFlags &= ~UberShaderProgram::SEPARATE_ALPHA; _alpha = 0; } unsigned int shaderFlags = _shaderFlags; if (basePremultiplied) shaderFlags &= ~UberShaderProgram::ALPHA_PREMULTIPLY; else shaderFlags |= UberShaderProgram::ALPHA_PREMULTIPLY; if (_shaderFlags != shaderFlags) { drawBatch(); } }
void STDRenderer::setTexture(const spNativeTexture& base_, bool basePremultiplied) { spNativeTexture base = base_; if (base == 0 || base->getHandle() == 0) base = white; unsigned int shaderFlags = _shaderFlags; if (basePremultiplied) shaderFlags &= ~UberShaderProgram::ALPHA_PREMULTIPLY; else shaderFlags |= UberShaderProgram::ALPHA_PREMULTIPLY; shaderFlags &= ~UberShaderProgram::SEPARATE_ALPHA; if (_base != base || _shaderFlags != shaderFlags) drawBatch(); _shaderFlags = shaderFlags; _base = base; _alpha = 0; }
void draw() { s_gdev->enableBlending(true); s_gdev->setBlendMode( BLEND_OVER ); s_gdev->setShader( SHADER_QUAD_UI ); if ( s_gdev->getDeviceID() != GDEV_OPENGL_1_3 ) { drawBatch(); } int curLayer = 255; if (s_rectIndex > 0) { curLayer = MIN(curLayer, s_rectPool[0].layer); } if (s_textIndex > 0) { curLayer = MIN(curLayer, s_textPool[0].layer); } s32 r=0, t=0; while (r < s_rectIndex || t < s_textIndex) { int nextLayerRect = 255; int nextLayerText = 255; for (; r < s_rectIndex; r++) { const DrawRectBuf& rect = s_rectPool[r]; if (rect.layer > curLayer) { nextLayerRect = rect.layer; break; } const Quad quad= { { rect.x, rect.y }, { rect.x + rect.w, rect.y + rect.h }, { rect.u, 1.0f-rect.v }, { rect.u+rect.du, 1.0f-(rect.v+rect.dv) }, rect.color }; s_gdev->setShaderResource( rect.texture, s_textureHash ); s_gdev->drawQuad( quad ); } for (; t < s_textIndex; t++) { const DrawTextBuf& text = s_textPool[t]; if (text.layer > curLayer) { nextLayerText = text.layer; break; } TextSystem::setColor( text.color ); TextSystem::setFont( text.font ); TextSystem::print( text.x, text.y, text.msg ); } curLayer = MIN(nextLayerRect, nextLayerText); }; clearDraw(); s_gdev->enableBlending(false); }
void STDRenderer::_checkDrawBatch() { if (_vertices.size() / sizeof(_vdecl->size) >= maxVertices) drawBatch(); }
void STDRenderer::setVertexDeclaration(const VertexDeclaration* decl) { if (_vdecl != decl) drawBatch(); _vdecl = decl; }
STDRenderer::~STDRenderer() { drawBatch(); }
ofRectangle ofxFontStash::drawMultiLineColumn( string & text, float size, float x, float y, float maxW, int &numLines, bool dontDraw, int maxLines, bool giveBackNewLinedText, bool* wordsWereTruncated){ ofRectangle totalArea = ofRectangle(x,y,0,0); if(wordsWereTruncated){ *wordsWereTruncated = false; } if (stash != NULL){ numLines = 0; if(!dontDraw){ glPushMatrix(); glTranslatef(x, y, 0.0f); } //ofLine(0, 0, maxW, 0); vector<string>splitLines; ofRectangle r; //ofUTF8Ptr start = ofUTF8::beginPtr(text); ofUTF8Ptr iter = ofUTF8::beginPtr(text); ofUTF8Ptr lineStart = iter; ofUTF8Ptr lastSpace; ofUTF8Ptr stop = ofUTF8::endPtr(text); string thisLine = ""; bool foundSpace = false; bool foundNewLine = false; while(iter < stop) { ofUniChar c = ofUTF8::getNext(iter); // get the next unichar and iterate if ( ofUnicode::isSpace(c) ){ foundSpace = true; lastSpace = iter; } if ( ofTextConverter::toUTF8(c) == "\n" ){ foundNewLine = true; } thisLine += ofTextConverter::toUTF8(c); r = getBBox(thisLine.c_str(), size, 0,0); if ( r.width > maxW || foundNewLine ) { //we went too far, lets jump back to our closest space if(foundNewLine){ if (thisLine == "\n"){ //if the whole line is only \n, replace with a space to avoid weird things thisLine = " "; }else{ //otherwise remove the "\n" thisLine = thisLine.substr(0, thisLine.length()-1); } splitLines.push_back(thisLine); }else{ if (foundSpace){ //cout << "## foundSpace! (" << thisLine << ")" << endl; string finalLine = walkAndFill(lineStart, iter, lastSpace); splitLines.push_back(finalLine); iter = lastSpace; }else{ //cout << "## no Space! (" << thisLine << ")" << endl; splitLines.push_back(thisLine); if(wordsWereTruncated){ *wordsWereTruncated = true; } } } //reset counter vars lineStart = iter; r.width = 0; thisLine = ""; foundSpace = foundNewLine = false; }else{ if(iter == stop){ //last line! string finalLine = walkAndFill(lineStart, iter, stop); splitLines.push_back(finalLine); break; } } } if(!dontDraw) beginBatch(); numLines = splitLines.size(); int linesToDraw = 0; if (maxLines > 0 ){ linesToDraw = MIN(splitLines.size(), maxLines); numLines = splitLines.size(); } for(int i = 0; i < linesToDraw; i++){ float yy = lineHeight * OFX_FONT_STASH_LINE_HEIGHT_MULT * size * i; if(!dontDraw){ ofPushMatrix(); ofTranslate(0, yy); drawBatch(splitLines[i], size, 0, 0 ); ofPopMatrix(); } #if OF_VERSION_MAJOR == 0 && OF_VERSION_MINOR == 8 totalArea = totalArea.getUnion( getBBox(splitLines[i], size, x, y + yy)); #else totalArea = getBBox(splitLines[i], size, x, y + yy); //TODO! #endif } if(!dontDraw){ endBatch(); glPopMatrix(); } //return through reference the edited text (with newLines!) if(giveBackNewLinedText){ text = ""; for (int i = 0; i < numLines; i++){ text += splitLines[i]; if (i != numLines-1) text += "\n"; } } }else{ ofLogError("ofxFontStash", "can't drawMultiLine() without having been setup first!"); } return totalArea; }
ofRectangle ofxFontStash::drawMultiLineColumn( string & _text, float size, float x, float y, float maxW, int &numLines, bool dontDraw, int maxLines, bool giveBackNewLinedText, bool* wordsWereTruncated){ string text = _text; if (!utf8::is_valid(text.begin(), text.end())){ text = LocaleToUtf8(text); } ofRectangle totalArea = ofRectangle(x,y,0,0); if(wordsWereTruncated){ *wordsWereTruncated = false; } if (stash != NULL){ numLines = 0; if(!dontDraw){ glPushMatrix(); glTranslatef(x, y, 0.0f); } //ofLine(0, 0, maxW, 0); vector<string>splitLines; ofRectangle r; const char * iter = text.c_str(); const char * lineStart = iter; const char * lastSpace; const char * stop = text.c_str() + text.length(); string thisLine = ""; bool foundSpace = false; bool foundNewLine = false; while(iter < stop) { unsigned int c = utf8::unchecked::next(iter); // get the next unichar and iterate if ( isSpace(c) ){ foundSpace = true; lastSpace = iter; } if ( toUTF8(c) == "\n" ){ foundNewLine = true; } thisLine += toUTF8(c); r = getBBox(thisLine.c_str(), size, 0,0); if ( r.width > maxW || foundNewLine ) { //we went too far, lets jump back to our closest space if(foundNewLine){ if (thisLine == "\n"){ //if the whole line is only \n, replace with a space to avoid weird things thisLine = " "; }else{ //otherwise remove the "\n" thisLine = thisLine.substr(0, thisLine.length()-1); } splitLines.push_back(thisLine); }else{ if (foundSpace){ string finalLine = walkAndFill(lineStart, iter, lastSpace); splitLines.push_back(finalLine); // Edge case where if max width is met and first character is space if(!(utf8::unchecked::next(lineStart) == 0x20)){ iter = lastSpace; } }else{ splitLines.push_back(thisLine); if(wordsWereTruncated){ *wordsWereTruncated = true; } } } //reset counter vars lineStart = iter; r.width = 0; thisLine = ""; foundSpace = foundNewLine = false; }else{ if(iter == stop){ //last line! string finalLine = walkAndFill(lineStart, iter, stop); splitLines.push_back(finalLine); break; } } } if(!dontDraw) beginBatch(); numLines = splitLines.size(); int linesToDraw = 0; if (maxLines > 0 ){ linesToDraw = MIN(splitLines.size(), maxLines); numLines = splitLines.size(); }else{ linesToDraw = splitLines.size(); } for(int i = 0; i < linesToDraw; i++){ float yy = lineHeight * OFX_FONT_STASH_LINE_HEIGHT_MULT * size * i; if(!dontDraw){ ofPushMatrix(); ofTranslate(0, yy); drawBatch(splitLines[i], size, 0, 0 ); ofPopMatrix(); } #if OF_VERSION_MAJOR == 0 && OF_VERSION_MINOR >= 8 totalArea = totalArea.getUnion( getBBox(splitLines[i], size, x, y + yy)); #else totalArea = getBBox(splitLines[i], size, x, y + yy); //TODO! #endif } if(!dontDraw){ endBatch(); glPopMatrix(); } //return through reference the edited text (with newLines!) if(giveBackNewLinedText){ text = ""; for (int i = 0; i < numLines; i++){ if (i < maxLines || maxLines == 0){ text += splitLines[i]; if (i != numLines-1) text += "\n"; } } } }else{ ofLogError("ofxFontStash") << "can't draw() without having been setup first!"; } return totalArea; }