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; }
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; }
// 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); }
/** * 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; }