void EntityLODComponent::UpdateLODLevel(int newLevel) { if (m_iCurrentLevel==newLevel) { return; } // change the mesh and the animation config used int oldLevel = m_iCurrentLevel; VLODLevelInfo &newLODInfo = GetLevelInfo(newLevel); m_iCurrentLevel=newLevel; m_pOwner->SetMesh(newLODInfo.m_spMesh); m_pOwner->SetAnimConfig(newLODInfo.m_spAnimConfig); // synchronize animation tracks of both LODs if (oldLevel>=0 && oldLevel<m_iLevelCount) { VLODLevelInfo &oldLODInfo = GetLevelInfo(oldLevel); IVisAnimResultGenerator_cl* oldLODAnimInput = oldLODInfo.m_spAnimConfig->GetFinalResult()->GetSkeletalAnimInput(); float currAnimTime = 0.0f; if ( oldLODAnimInput->IsOfType( V_RUNTIME_CLASS(VisSkeletalAnimControl_cl) ) ) { VisSkeletalAnimControl_cl* oldLODAanimController = static_cast< VisSkeletalAnimControl_cl* >( oldLODAnimInput ); currAnimTime = oldLODAanimController->GetCurrentSequenceTime(); } IVisAnimResultGenerator_cl* newLODAnimInput = newLODInfo.m_spAnimConfig->GetFinalResult()->GetSkeletalAnimInput(); if ( newLODAnimInput->IsOfType( V_RUNTIME_CLASS(VisSkeletalAnimControl_cl) ) ) { VisSkeletalAnimControl_cl* newLODAanimController = static_cast< VisSkeletalAnimControl_cl* >( newLODAnimInput ); newLODAanimController->SetCurrentSequenceTime( currAnimTime ); } } }
bool EntityLODComponent::ParseXMLNode(TiXmlElement *pLODNode) { if (!pLODNode) return false; // first count the number of elements TiXmlElement* pElement; // load constraints TiXmlNode *pFirstNode = pLODNode->FirstChild("LODLevel"); if (!pFirstNode) return false; int iCount = 0; // iterate through all sub-nodes and count them for (pElement=pFirstNode->ToElement(); pElement!=NULL; pElement=pElement->NextSiblingElement("LODLevel")) iCount++; AllocateLevels(iCount); // iterate again and parse iCount = 0; for (pElement=pFirstNode->ToElement(); pElement!=NULL; pElement=pElement->NextSiblingElement("LODLevel")) GetLevelInfo(iCount++).ParseXMLNode(pElement); return true; }
gl::Error TextureGL::setCompressedSubImage(GLenum target, size_t level, const gl::Box &area, GLenum format, const gl::PixelUnpackState &unpack, size_t imageSize, const uint8_t *pixels) { ASSERT(CompatibleTextureTarget(mState.mTarget, target)); nativegl::CompressedTexSubImageFormat compressedTexSubImageFormat = nativegl::GetCompressedSubTexImageFormat(mFunctions, mWorkarounds, format); mStateManager->bindTexture(mState.mTarget, mTextureID); if (UseTexImage2D(mState.mTarget)) { ASSERT(area.z == 0 && area.depth == 1); mFunctions->compressedTexSubImage2D( target, static_cast<GLint>(level), area.x, area.y, area.width, area.height, compressedTexSubImageFormat.format, static_cast<GLsizei>(imageSize), pixels); } else if (UseTexImage3D(mState.mTarget)) { mFunctions->compressedTexSubImage3D(target, static_cast<GLint>(level), area.x, area.y, area.z, area.width, area.height, area.depth, compressedTexSubImageFormat.format, static_cast<GLsizei>(imageSize), pixels); } else { UNREACHABLE(); } ASSERT(!mLevelInfo[level].lumaWorkaround.enabled && !GetLevelInfo(format, compressedTexSubImageFormat.format).lumaWorkaround.enabled); return gl::Error(GL_NO_ERROR); }
gl::Error TextureGL::setCompressedImage(GLenum target, size_t level, GLenum internalFormat, const gl::Extents &size, const gl::PixelUnpackState &unpack, size_t imageSize, const uint8_t *pixels) { ASSERT(CompatibleTextureTarget(mState.mTarget, target)); nativegl::CompressedTexImageFormat compressedTexImageFormat = nativegl::GetCompressedTexImageFormat(mFunctions, mWorkarounds, internalFormat); mStateManager->bindTexture(mState.mTarget, mTextureID); if (UseTexImage2D(mState.mTarget)) { ASSERT(size.depth == 1); mFunctions->compressedTexImage2D(target, static_cast<GLint>(level), compressedTexImageFormat.internalFormat, size.width, size.height, 0, static_cast<GLsizei>(imageSize), pixels); } else if (UseTexImage3D(mState.mTarget)) { mFunctions->compressedTexImage3D( target, static_cast<GLint>(level), compressedTexImageFormat.internalFormat, size.width, size.height, size.depth, 0, static_cast<GLsizei>(imageSize), pixels); } else { UNREACHABLE(); } mLevelInfo[level] = GetLevelInfo(internalFormat, compressedTexImageFormat.internalFormat); ASSERT(!mLevelInfo[level].lumaWorkaround.enabled); return gl::Error(GL_NO_ERROR); }
// init level-info subsystem void LoadLevelsList(void) { CPrintF(TRANSV("Reading levels directory...\n")); // list the levels directory with subdirs CDynamicStackArray<CTFileName> afnmDir; MakeDirList(afnmDir, CTString("Levels\\"), CTString("*.wld"), DLI_RECURSIVE|DLI_SEARCHCD); // for each file in the directory for (INDEX i=0; i<afnmDir.Count(); i++) { CTFileName fnm = afnmDir[i]; CPrintF(TRANSV(" file '%s' : "), (const char *)fnm); // try to load its info, and if valid CLevelInfo li; if (GetLevelInfo(li, fnm)) { CPrintF(TRANSV("'%s' spawn=0x%08x\n"), (const char *) li.li_strName, li.li_ulSpawnFlags); // create new info for that file CLevelInfo *pliNew = new CLevelInfo; *pliNew = li; // add it to list of all levels _lhAllLevels.AddTail(pliNew->li_lnNode); } else { CPrintF(TRANSV("invalid level\n")); } } // sort the list _lhAllLevels.Sort(qsort_CompareLevels, _offsetof(CLevelInfo, li_lnNode)); }
void EntityLODComponent::SetAnimConfigs( VisAnimConfigPtr* arrAnimConfig, int lodsCount ) { for ( int i = 0; i < lodsCount; ++i ) { VLODLevelInfo& lodInfo = GetLevelInfo( i ); if ( lodInfo.m_spMesh != NULL ) { // create a new final result for this config lodInfo.m_spAnimConfig = arrAnimConfig[i]; lodInfo.m_spFinalSkeletalResult = arrAnimConfig[i]->GetFinalResult(); } if ( i == m_iCurrentLevel ) { // make the animation play m_pOwner->SetMesh( lodInfo.m_spMesh ); m_pOwner->SetAnimConfig( lodInfo.m_spAnimConfig ); } } }
gl::Error TextureGL::copyImage(GLenum target, size_t level, const gl::Rectangle &sourceArea, GLenum internalFormat, const gl::Framebuffer *source) { nativegl::CopyTexImageImageFormat copyTexImageFormat = nativegl::GetCopyTexImageImageFormat( mFunctions, mWorkarounds, internalFormat, source->getImplementationColorReadType()); LevelInfoGL levelInfo = GetLevelInfo(internalFormat, copyTexImageFormat.internalFormat); if (levelInfo.lumaWorkaround.enabled) { gl::Error error = mBlitter->copyImageToLUMAWorkaroundTexture( mTextureID, mState.mTarget, target, levelInfo.sourceFormat, level, sourceArea, copyTexImageFormat.internalFormat, source); if (error.isError()) { return error; } } else { const FramebufferGL *sourceFramebufferGL = GetImplAs<FramebufferGL>(source); mStateManager->bindTexture(mState.mTarget, mTextureID); mStateManager->bindFramebuffer(GL_READ_FRAMEBUFFER, sourceFramebufferGL->getFramebufferID()); if (UseTexImage2D(mState.mTarget)) { mFunctions->copyTexImage2D(target, static_cast<GLint>(level), copyTexImageFormat.internalFormat, sourceArea.x, sourceArea.y, sourceArea.width, sourceArea.height, 0); } else { UNREACHABLE(); } } mLevelInfo[level] = levelInfo; return gl::Error(GL_NO_ERROR); }
gl::Error TextureGL::setSubImage(GLenum target, size_t level, const gl::Box &area, GLenum format, GLenum type, const gl::PixelUnpackState &unpack, const uint8_t *pixels) { ASSERT(CompatibleTextureTarget(mState.mTarget, target)); nativegl::TexSubImageFormat texSubImageFormat = nativegl::GetTexSubImageFormat(mFunctions, mWorkarounds, format, type); mStateManager->bindTexture(mState.mTarget, mTextureID); if (mWorkarounds.unpackOverlappingRowsSeparatelyUnpackBuffer && unpack.pixelBuffer.get() && unpack.rowLength != 0 && unpack.rowLength < area.width) { ANGLE_TRY(setSubImageRowByRowWorkaround(target, level, area, format, type, unpack, pixels)); } else if (UseTexImage2D(mState.mTarget)) { ASSERT(area.z == 0 && area.depth == 1); mFunctions->texSubImage2D(target, static_cast<GLint>(level), area.x, area.y, area.width, area.height, texSubImageFormat.format, texSubImageFormat.type, pixels); } else if (UseTexImage3D(mState.mTarget)) { mFunctions->texSubImage3D(target, static_cast<GLint>(level), area.x, area.y, area.z, area.width, area.height, area.depth, texSubImageFormat.format, texSubImageFormat.type, pixels); } else { UNREACHABLE(); } ASSERT(mLevelInfo[level].lumaWorkaround.enabled == GetLevelInfo(format, texSubImageFormat.format).lumaWorkaround.enabled); return gl::Error(GL_NO_ERROR); }