Exemple #1
0
bool StGLFontEntry::createTexture(StGLContext& theCtx) {
    const GLint aMaxSize = theCtx.getMaxTextureSize();

    GLint aGlyphsNb = 0;
    if(myFont->hasCJK()
    || myFont->hasKorean()) {
        // italic does not make sense for Chinese
        // limit overall number of glyphs in the single texture to 4k
        // (single font file might contain about 20k-50k glyphs)
        aGlyphsNb = stMin(4000, 2 * myFont->getGlyphsNumber() - GLint(myLastTileId) + 1);
    } else {
        // western might contain reg/bold/italic/bolditalic styles
        // limit overall number of glyphs in the single texture to 1k
        // (single font file might contain about 6k glyphs for different languages)
        aGlyphsNb = stMin(1000, 4 * myFont->getGlyphsNumber() - GLint(myLastTileId) + 1);
    }

    const GLsizei aTextureSizeX = getPowerOfTwo(aGlyphsNb * myTileSizeX, aMaxSize);
    const size_t  aTilesPerRow  = aTextureSizeX / myTileSizeX;
    GLsizei aTextureSizeY = stMin(getEvenNumber(GLint((aGlyphsNb / aTilesPerRow) + 1) * myTileSizeY), aMaxSize);
    if(!theCtx.arbNPTW) {
        aTextureSizeY = getPowerOfTwo(aTextureSizeY, aMaxSize);
    }

    stMemZero(&myLastTilePx, sizeof(myLastTilePx));
    myLastTilePx.bottom() = myTileSizeY;

    myTextures.add(new StGLTexture(theCtx.arbTexRG ? GL_R8 : GL_ALPHA));
    myFbos.add(new StGLFrameBuffer());
    StHandle<StGLTexture>&     aTexture = myTextures[myTextures.size() - 1];
    StHandle<StGLFrameBuffer>& aFbo     = myFbos    [myTextures.size() - 1];
    if(!aTexture->initTrash(theCtx, aTextureSizeX, aTextureSizeY)) {
        return false;
    }
    aTexture->bind(theCtx);
    theCtx.core11fwd->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    theCtx.core11fwd->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    aTexture->unbind(theCtx);

    // destruction of temporary FBO produces broken texture on Catalyst drivers for unknown reason
    //StGLFrameBuffer::clearTexture(theCtx, aTexture);
#if !defined(GL_ES_VERSION_2_0)
    if(theCtx.arbTexClear) {
        theCtx.core11fwd->glPixelStorei(GL_UNPACK_LSB_FIRST,  GL_FALSE);
        theCtx.core11fwd->glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
        theCtx.core11fwd->glPixelStorei(GL_UNPACK_ALIGNMENT,  1);
        const stUByte_t THE_BLACK = 0;
        theCtx.extAll->glClearTexImage(aTexture->getTextureId(), 0, theCtx.arbTexRG ? GL_RED : GL_ALPHA, GL_UNSIGNED_BYTE, &THE_BLACK);
    } else if(aFbo->init(theCtx, aTexture, false)) {
        aFbo->clearTexture(theCtx);
    } else {
        ST_ERROR_LOG("Fail to bind " + (theCtx.arbTexRG ? "GL_R8" : "GL_ALPHA8") + " texture to FBO!");
    }
#else
    (void )aFbo;
#endif

    return true;
}
Exemple #2
0
    /**
     * Create context.
     */
    bool create(const StString& theFile) {
        if(myFormat == NULL) {
            return false;
        }

    #if !defined(ST_LIBAV_FORK)
        avformat_alloc_output_context2(&Context, myFormat, NULL, theFile.toCString());
    #else
        Context = avformat_alloc_context();
        if(Context == NULL) {
            return false;
        }

        Context->oformat = myFormat;
        if(Context->oformat->priv_data_size > 0) {
            Context->priv_data = av_mallocz(Context->oformat->priv_data_size);
            if(!Context->priv_data) {
                //goto nomem;
            }
            if(Context->oformat->priv_class) {
                *(const AVClass**)Context->priv_data = Context->oformat->priv_class;
                //av_opt_set_defaults(aCtxOut->priv_data);
            }
        } else {
            Context->priv_data = NULL;
        }

        const size_t aStrLen = stMin(theFile.Size + 1, size_t(1024));
        stMemCpy(Context->filename, theFile.toCString(), aStrLen);
        Context->filename[1023] = '\0';
    #endif
        return Context != NULL;
    }
void StGLStereoFrameBuffer::setVPDimensions(StGLContext&  theCtx,
                                            const GLsizei theSizeX,
                                            const GLsizei theSizeY) {
    GLsizei aVPSizeX = stMin(theSizeX, getSizeX());
    GLsizei aVPSizeY = stMin(theSizeY, getSizeY());
    if(aVPSizeX != myViewPortX
    || aVPSizeY != myViewPortY) {
        GLfloat aDX = GLfloat(aVPSizeX) / GLfloat(getSizeX());
        GLfloat aDY = GLfloat(aVPSizeY) / GLfloat(getSizeY());
        StArray<StGLVec2> aTCoords(4);
        aTCoords[0] = StGLVec2(aDX,  0.0f);
        aTCoords[1] = StGLVec2(aDX,  aDY);
        aTCoords[2] = StGLVec2(0.0f, 0.0f);
        aTCoords[3] = StGLVec2(0.0f, aDY);
        myTexCoordBuf.init(theCtx, aTCoords);
        myViewPortX = aVPSizeX;
        myViewPortY = aVPSizeY;
    }
}
void StGLFrameTextures::increaseSize(StGLContext&      theCtx,
                                     StGLFrameTexture& theTexture,
                                     const GLsizei     theTextureSizeX,
                                     const GLsizei     theTextureSizeY) {
    // test existing size / new size
    /// TODO (Kirill Gavrilov#8) we can automatically reduce texture size here
    if((theTexture.getSizeX() < theTextureSizeX) ||
       (theTexture.getSizeY() < theTextureSizeY) ||
       !theTexture.isValid()) {
        ST_DEBUG_LOG("Requested texture size (" + theTextureSizeX + 'x' + theTextureSizeY
                   + ") larger than current texture size(" + theTexture.getSizeX() + 'x' + theTexture.getSizeY() + ')');
        const GLsizei anOriginalSizeX = theTexture.getSizeX();
        const GLsizei anOriginalSizeY = theTexture.getSizeY();

        const GLint aMaxTexDim = theCtx.getMaxTextureSize();
        GLsizei aNewSizeX = stMin(theTextureSizeX, GLsizei(aMaxTexDim));
        GLsizei aNewSizeY = stMin(theTextureSizeY, GLsizei(aMaxTexDim));
        if(!theCtx.arbNPTW) {
            aNewSizeX = getPowerOfTwo(theTextureSizeX, GLsizei(aMaxTexDim));
            aNewSizeY = getPowerOfTwo(theTextureSizeY, GLsizei(aMaxTexDim));
        }
        if((aNewSizeY != anOriginalSizeY)
        || (aNewSizeX != anOriginalSizeX)) {
            if(!theTexture.initTrash(theCtx, aNewSizeX, aNewSizeY)) {
                theTexture.initTrash(theCtx,
                                     (anOriginalSizeX > 0) ? anOriginalSizeX : 512,
                                     (anOriginalSizeY > 0) ? anOriginalSizeY : 512);
                ST_DEBUG_LOG("FAILED to Increase the texture size to (" + aNewSizeX + 'x' +  aNewSizeY + ")!");
            } else {
                ST_DEBUG_LOG("Increase the texture size to (" + aNewSizeX + 'x' +  aNewSizeY + ") success!");
            }
        } else {
            ST_DEBUG_LOG("Not possible to Increase the texture size!");
        }
    }
}
Exemple #5
0
bool StGLScrollArea::doScroll(const int  theDelta,
                              const bool theIsFling) {
    if(!theIsFling) {
        myDragYDelta = 0.0;
        myFlingTimer.stop();
    }
    if(!isScrollable()) {
        return false;
    }

    StGLWidget* aContent = myChildren.getStart();
    const int aMinLim = 0;
    const int aMaxLim = getRectPx().height() - aContent->getRectPx().height();
    const int aTopOld = aContent->getRectPx().top();
    const int aTopNew = stMax(stMin(aMinLim, aTopOld + theDelta), aMaxLim);
    const int aDelta  = aTopNew - aTopOld;
    if(aDelta == 0) {
        if(theIsFling) {
            myFlingTimer.stop();
        }
        return false;
    }

    aContent->changeRectPx().top()    += aDelta;
    aContent->changeRectPx().bottom() += aDelta;

    if(myIsLeftClick) {
        if(!theIsFling) {
            myDragYCumul += aDelta;
            if(std::abs(myDragYCumul) > myRoot->getClickThreshold()
            && !myHasDragged) {
                setClickedWithChildren(myChildren, ST_MOUSE_LEFT, false);
                myHasDragged = true;
            }
        } else {
            myDragYCumul = 0;
        }
    }

    myIsResized = true;
    return true;
}
Exemple #6
0
bool StPlayList::walkToNext(const bool theToForce) {
    StMutexAuto anAutoLock(myMutex);
    if(myCurrent == NULL
    || (myToLoopSingle && !theToForce)) {
        return false;
    } else if(myIsShuffle && myItemsCount >= 3) {
        StPlayItem* aPrev = myCurrent;
        if(!myStackNext.empty()) {
            myCurrent = myStackNext.front();
            myStackNext.pop_front();
        } else {
            if((myPlayedCount >= (myItemsCount - 1)) || (myPlayedCount == 0)) {
                // reset the playback counter
            #ifdef _WIN32
                FILETIME aTime;
                GetSystemTimeAsFileTime(&aTime);
                myRandGen.setSeed(aTime.dwLowDateTime);
            #else
                timeval aTime;
                gettimeofday(&aTime, NULL);
                myRandGen.setSeed(aTime.tv_usec);
            #endif
                myPlayedCount = 0;
                myCurrent->setPlayedFlag(!myCurrent->getPlayedFlag());
                ST_DEBUG_LOG("Restart the shuffle");
            }

            // determine next random position
            const size_t aCurrPos  = myCurrent->getPosition();
            bool         aCurrFlag = myCurrent->getPlayedFlag();
            StPlayItem*  aNextItem = myCurrent;
            const size_t aNextPos  = stMin(size_t(myRandGen.next() * myItemsCount), myItemsCount - 1);
            if(aNextPos > aCurrPos) {
                // forward direction
                for(size_t aNextDiff = aNextPos - aCurrPos; aNextItem != NULL && aNextDiff != 0; --aNextDiff) {
                    aNextItem = aNextItem->getNext();
                }
            } else {
                // backward direction
                for(size_t aNextDiff = aCurrPos - aNextPos; aNextItem != NULL && aNextDiff != 0; --aNextDiff) {
                    aNextItem = aNextItem->getPrev();
                }
            }
            if(aCurrFlag == aNextItem->getPlayedFlag()) {
                // find nearest position not yet played - prefer item farther from current one
                StPlayItem* aNextItem1 = aNextPos > aCurrPos ? aNextItem->getNext() : aNextItem->getPrev();
                StPlayItem* aNextItem2 = aNextPos > aCurrPos ? aNextItem->getPrev() : aNextItem->getNext();
                for(; aNextItem1 != NULL || aNextItem2 != NULL;) {
                    if(aNextItem1 != NULL) {
                        if(aCurrFlag != aNextItem1->getPlayedFlag()) {
                            aNextItem = aNextItem1;
                            break;
                        }
                        aNextItem1 = aNextPos > aCurrPos ? aNextItem1->getNext() : aNextItem1->getPrev();
                    }
                    if(aNextItem2 != NULL) {
                        if(aCurrFlag != aNextItem2->getPlayedFlag()) {
                            aNextItem = aNextItem2;
                            break;
                        }
                        aNextItem2 = aNextPos > aCurrPos ? aNextItem2->getPrev() : aNextItem2->getNext();
                    }
                }
                if(aCurrFlag == aNextItem->getPlayedFlag()) {
                    // something wrong!
                    ST_DEBUG_LOG("Disaster - next shuffle position not found!");
                    aCurrFlag     = !aCurrFlag;
                    myPlayedCount = 0;
                }
            }

            ST_DEBUG_LOG(aCurrPos + " -> " + aNextItem->getPosition());
            ++myPlayedCount;

            aNextItem->setPlayedFlag(aCurrFlag);
            myCurrent = aNextItem;
        }

        if(aPrev != myCurrent
        && aPrev != NULL) {
            myStackPrev.push_back(aPrev);
            if(myStackPrev.size() > THE_UNDO_LIMIT) {
                myStackPrev.pop_front();
            }
        }

        const size_t anItemId = myCurrent->getPosition();
        anAutoLock.unlock();
        signals.onPositionChange(anItemId);
        return true;
    } else if(myCurrent != myLast) {
        myCurrent = myCurrent->getNext();
        const size_t anItemId = myCurrent->getPosition();
        anAutoLock.unlock();
        signals.onPositionChange(anItemId);
        return true;
    } else if(myIsLoopFlag) {
        return walkToFirst();
    }
    return false;
}