Пример #1
0
StGLTextureQueue::StGLTextureQueue(const size_t theQueueSizeMax)
: myDataFront(NULL),
  myDataSnap(NULL),
  myDataBack(NULL),
  myQueueSize(0),
  myQueueSizeMax(theQueueSizeMax),
  mySwapFBCount(0),
  myCurrSrcFormat(ST_V_SRC_MONO),
  myCurrPts(0.0),
  myNewShotEvent(false),
  myIsInUpdTexture(false),
  myIsReadyToSwap(false),
  myToCompress(false),
  myHasStream(false) {
    ST_DEBUG_ASSERT(myQueueSizeMax >= 2);

    // we create 'empty' queue
    myDataFront = new StGLTextureData();
    StGLTextureData* iter = myDataFront;
    for(size_t i = 1; i < myQueueSizeMax; ++i) {
        iter->setNext(new StGLTextureData());
        iter = iter->getNext();
    }
    iter->setNext(myDataFront); // data in loop
    myDataBack = myDataFront;
}
Пример #2
0
bool StGLMesh::computeNormals(size_t theDelta) {
    ST_DEBUG_ASSERT(theDelta > 0);
    myNormals.initArray(myVertices.size());
    if(myVertices.isEmpty()) {
        return false;
    }

    // iterate over each triangle
    // for each node we compute summary of normals for all triangles where this node used
    // normals are NOT normalized per triangle - this allows to interpolate result normal
    // with respect to each triangle dimensions
    GLuint aV1, aV2, aV3;
    StGLVec3 aNorm;
    if(myIndices.size() >= 3) {
        size_t aLimit = myIndices.size() - 3;
        for(size_t anIndexId = 0; anIndexId <= aLimit; anIndexId += theDelta) {
            aV1 = myIndices[anIndexId];
            aV2 = myIndices[anIndexId + 1];
            aV3 = myIndices[anIndexId + 2];
            const StGLVec3& aVert1 = myVertices[aV1];
            const StGLVec3& aVert2 = myVertices[aV2];
            const StGLVec3& aVert3 = myVertices[aV3];
            aNorm = StGLVec3::cross(aVert2 - aVert1, aVert3 - aVert1);
            myNormals.changeValue(aV1) += aNorm;
            myNormals.changeValue(aV2) += aNorm;
            myNormals.changeValue(aV3) += aNorm;
        }
    } else if(myVertices.size() >= 3) {
        size_t aLimit = myVertices.size() - 3;
        for(size_t aVertId = 0; aVertId <= aLimit; aVertId += theDelta) {
            aV1 = GLuint(aVertId);
            aV2 = GLuint(aVertId + 1);
            aV3 = GLuint(aVertId + 2);
            const StGLVec3& aVert1 = myVertices[aV1];
            const StGLVec3& aVert2 = myVertices[aV2];
            const StGLVec3& aVert3 = myVertices[aV3];
            aNorm = StGLVec3::cross(aVert2 - aVert1, aVert3 - aVert1);
            myNormals.changeValue(aV1) += aNorm;
            myNormals.changeValue(aV2) += aNorm;
            myNormals.changeValue(aV3) += aNorm;
        }
    } else {
        return false;
    }

    // normalize normals (important for OpenGL)
    for(size_t aNormId = 0; aNormId < myNormals.size(); ++aNormId) {
        myNormals.changeValue(aNormId).normalize();
    }
    return true;
}
Пример #3
0
// this function called ONLY from plugin thread
bool StGLTextureQueue::stglUpdateStTextures(StGLContext& theCtx) {
    int aSwapState = swapFBOnReady(theCtx);
    if(aSwapState == SWAPONREADY_WAITLIM) {
        return false;
    }

    if(!myMutexPop.tryLock()) {
        return aSwapState == SWAPONREADY_SWAPPED;
    }

    // do we already in update cycle?
    if(!myIsInUpdTexture) {
        // check event from video thread
        if(!isEmpty()) {
            myIsInUpdTexture = true;
        }
    } else if(isEmpty()) {
        // if we in texture update sequence - check queue not emptied!
        myIsInUpdTexture = false;
    }

    // still nothing to update? so return
    if(!myIsInUpdTexture) {
        myMutexPop.unlock();
        return aSwapState == SWAPONREADY_SWAPPED;
    }

    if(!theCtx.isBound()
    || myDataFront->fillTexture(theCtx, myQTexture)) {
        myIsReadyToSwap = true;
        myMutexSize.lock();
            myCurrPts   = myDataFront->getPTS();
            myDataSnap  = myDataFront; myNewShotEvent.set();
            if(myToCompress) {
                myDataFront->reset();
            }
            myDataFront = myDataFront->getNext();
            ST_DEBUG_ASSERT(myQueueSize != 0); // critical error!
            --myQueueSize;
        myMutexSize.unlock();
        myIsInUpdTexture = false;
    }
    myMutexPop.unlock();

    // try early swap
    const bool isAlreadySwapped = (aSwapState == SWAPONREADY_SWAPPED);
    aSwapState = swapFBOnReady(theCtx);
    return (aSwapState == SWAPONREADY_SWAPPED || isAlreadySwapped);
}
Пример #4
0
/**
 * Return color conversion shader part from StImage definition.
 */
static inline StGLImageProgram::FragToRgb getColorShader(const StImage::ImgColorModel theColorModel,
                                                         const StImage::ImgColorScale theColorScale) {
    switch(theColorModel) {
        case StImage::ImgColor_RGB:  return StGLImageProgram::FragToRgb_FromRgb;
        case StImage::ImgColor_RGBA: return StGLImageProgram::FragToRgb_FromRgba;
        case StImage::ImgColor_GRAY: return StGLImageProgram::FragToRgb_FromGray;
        case StImage::ImgColor_YUV: {
            switch(theColorScale) {
                case StImage::ImgScale_Mpeg9:  return StGLImageProgram::FragToRgb_FromYuv9Mpeg;
                case StImage::ImgScale_Mpeg10: return StGLImageProgram::FragToRgb_FromYuv10Mpeg;
                case StImage::ImgScale_Jpeg9:  return StGLImageProgram::FragToRgb_FromYuv9Full;
                case StImage::ImgScale_Jpeg10: return StGLImageProgram::FragToRgb_FromYuv10Full;
                case StImage::ImgScale_Mpeg:   return StGLImageProgram::FragToRgb_FromYuvMpeg;
                case StImage::ImgScale_Full:   return StGLImageProgram::FragToRgb_FromYuvFull;
            }
            return StGLImageProgram::FragToRgb_FromYuvFull;
        }
        default: {
            ST_DEBUG_LOG("No GLSL shader for this color model = " + theColorModel);
            ST_DEBUG_ASSERT(false);
        }
    }
    return StGLImageProgram::FragToRgb_FromRgb;
}