void FTextureManager::AddHiresTextures (int wadnum) { int firsttx = Wads.GetFirstLump(wadnum); int lasttx = Wads.GetLastLump(wadnum); char name[9]; TArray<FTextureID> tlist; if (firsttx == -1 || lasttx == -1) { return; } name[8] = 0; for (;firsttx <= lasttx; ++firsttx) { if (Wads.GetLumpNamespace(firsttx) == ns_hires) { Wads.GetLumpName (name, firsttx); if (Wads.CheckNumForName (name, ns_hires) == firsttx) { tlist.Clear(); int amount = ListTextures(name, tlist); if (amount == 0) { // A texture with this name does not yet exist FTexture * newtex = FTexture::CreateTexture (firsttx, FTexture::TEX_Any); if (newtex != NULL) { newtex->UseType=FTexture::TEX_Override; AddTexture(newtex); } } else { for(unsigned int i = 0; i < tlist.Size(); i++) { FTexture * newtex = FTexture::CreateTexture (firsttx, FTexture::TEX_Any); if (newtex != NULL) { FTexture * oldtex = Textures[tlist[i].GetIndex()].Texture; // Replace the entire texture and adjust the scaling and offset factors. newtex->bWorldPanning = true; newtex->SetScaledSize(oldtex->GetScaledWidth(), oldtex->GetScaledHeight()); newtex->LeftOffset = FixedMul(oldtex->GetScaledLeftOffset(), newtex->xScale); newtex->TopOffset = FixedMul(oldtex->GetScaledTopOffset(), newtex->yScale); ReplaceTexture(tlist[i], newtex, true); } } } //StartScreen->Progress(); } } } }
void FTextureManager::ParseCameraTexture(FScanner &sc) { const BITFIELD texflags = TEXMAN_Overridable | TEXMAN_TryAny | TEXMAN_ShortNameOnly; int width, height; int fitwidth, fitheight; FString picname; sc.MustGetString (); picname = sc.String; sc.MustGetNumber (); width = sc.Number; sc.MustGetNumber (); height = sc.Number; FTextureID picnum = CheckForTexture (picname, FTexture::TEX_Flat, texflags); FTexture *viewer = new FCanvasTexture (picname, width, height); if (picnum.Exists()) { FTexture *oldtex = Texture(picnum); fitwidth = oldtex->GetScaledWidth (); fitheight = oldtex->GetScaledHeight (); viewer->UseType = oldtex->UseType; ReplaceTexture (picnum, viewer, true); } else { fitwidth = width; fitheight = height; // [GRB] No need for oldtex viewer->UseType = FTexture::TEX_Wall; AddTexture (viewer); } if (sc.GetString()) { if (sc.Compare ("fit")) { sc.MustGetNumber (); fitwidth = sc.Number; sc.MustGetNumber (); fitheight = sc.Number; } else { sc.UnGet (); } } if (sc.GetString()) { if (sc.Compare("WorldPanning")) { viewer->bWorldPanning = true; } else { sc.UnGet(); } } viewer->SetScaledSize(fitwidth, fitheight); }
void FTextureManager::ParseWarp(FScanner &sc) { const BITFIELD texflags = TEXMAN_Overridable | TEXMAN_TryAny | TEXMAN_ShortNameOnly; bool isflat = false; bool type2 = sc.Compare ("warp2"); // [GRB] sc.MustGetString (); if (sc.Compare ("flat")) { isflat = true; sc.MustGetString (); } else if (sc.Compare ("texture")) { isflat = false; sc.MustGetString (); } else { sc.ScriptError (NULL); } FTextureID picnum = CheckForTexture (sc.String, isflat ? FTexture::TEX_Flat : FTexture::TEX_Wall, texflags); if (picnum.isValid()) { FTexture *warper = Texture(picnum); // don't warp a texture more than once if (!warper->bWarped) { if (type2) warper = new FWarp2Texture (warper); else warper = new FWarpTexture (warper); ReplaceTexture (picnum, warper, false); } if (sc.CheckFloat()) { static_cast<FWarpTexture*>(warper)->SetSpeed(float(sc.Float)); } // No decals on warping textures, by default. // Warping information is taken from the last warp // definition for this texture. warper->bNoDecals = true; if (sc.GetString ()) { if (sc.Compare ("allowdecals")) { warper->bNoDecals = false; } else { sc.UnGet (); } } } }
ReplaceTexture CScutAniGroup::getTextureByTile(CScutTile* pTile) { assert(pTile); if (pTile) { assert(pTile->m_tt.imgIndex > -1 && pTile->m_tt.imgIndex < this->m_vTexture.size()); if (pTile->m_tt.imgIndex > -1 && pTile->m_tt.imgIndex < this->m_vTexture.size()) { return this->m_vTexture[pTile->m_tt.imgIndex]; } } return ReplaceTexture(); }
void FTextureManager::InitAnimated (void) { const BITFIELD texflags = TEXMAN_Overridable; // I think better not! This is only for old ANIMATED definitions that // don't know about ZDoom's more flexible texture system. // | FTextureManager::TEXMAN_TryAny; int lumpnum = Wads.CheckNumForName ("ANIMATED"); if (lumpnum != -1) { FMemLump animatedlump = Wads.ReadLump (lumpnum); int animatedlen = Wads.LumpLength(lumpnum); const char *animdefs = (const char *)animatedlump.GetMem(); const char *anim_p; FTextureID pic1, pic2; int animtype; DWORD animspeed; // Init animation animtype = FAnimDef::ANIM_Forward; for (anim_p = animdefs; *anim_p != -1; anim_p += 23) { // make sure the current chunk of data is inside the lump boundaries. if (anim_p + 22 >= animdefs + animatedlen) { I_Error("Tried to read past end of ANIMATED lump."); } if (*anim_p /* .istexture */ & 1) { // different episode ? if (!(pic1 = CheckForTexture (anim_p + 10 /* .startname */, FTexture::TEX_Wall, texflags)).Exists() || !(pic2 = CheckForTexture (anim_p + 1 /* .endname */, FTexture::TEX_Wall, texflags)).Exists()) continue; // [RH] Bit 1 set means allow decals on walls with this texture Texture(pic2)->bNoDecals = Texture(pic1)->bNoDecals = !(*anim_p & 2); } else { if (!(pic1 = CheckForTexture (anim_p + 10 /* .startname */, FTexture::TEX_Flat, texflags)).Exists() || !(pic2 = CheckForTexture (anim_p + 1 /* .startname */, FTexture::TEX_Flat, texflags)).Exists()) continue; } FTexture *tex1 = Texture(pic1); FTexture *tex2 = Texture(pic2); animspeed = (BYTE(anim_p[19]) << 0) | (BYTE(anim_p[20]) << 8) | (BYTE(anim_p[21]) << 16) | (BYTE(anim_p[22]) << 24); // SMMU-style swirly hack? Don't apply on already-warping texture if (animspeed > 65535 && tex1 != NULL && !tex1->bWarped) { FTexture *warper = new FWarp2Texture (tex1); ReplaceTexture (pic1, warper, false); } // These tests were not really relevant for swirling textures, or even potentially // harmful, so they have been moved to the else block. else { if (tex1->UseType != tex2->UseType) { // not the same type - continue; } if (debuganimated) { Printf("Defining animation '%s' (texture %d, lump %d, file %d) to '%s' (texture %d, lump %d, file %d)\n", tex1->Name, pic1.GetIndex(), tex1->GetSourceLump(), Wads.GetLumpFile(tex1->GetSourceLump()), tex2->Name, pic2.GetIndex(), tex2->GetSourceLump(), Wads.GetLumpFile(tex2->GetSourceLump())); } if (pic1 == pic2) { // This animation only has one frame. Skip it. (Doom aborted instead.) Printf ("Animation %s in ANIMATED has only one frame\n", anim_p + 10); continue; } // [RH] Allow for backward animations as well as forward. else if (pic1 > pic2) { swapvalues (pic1, pic2); animtype = FAnimDef::ANIM_Backward; } // Speed is stored as tics, but we want ms so scale accordingly. AddSimpleAnim (pic1, pic2 - pic1 + 1, animtype, Scale (animspeed, 1000, 35)); } } } }
bool CScutAniGroup::Load(const char* sprName) { if (NULL == sprName) { return false; } string spr = sprName; if (spr.size() == 0) { return false; } if (this->m_sprName.size() > 0) { return this->m_sprName == spr; } this->m_sprName = sprName; spr += ".spr"; spr = SPRITE_FILE_DIR + spr; spr = CFileHelper::getPath(spr.c_str()); char cMode[3] = {'r', 'b', 0}; unsigned long uSize = 0; unsigned char* pBuf = (unsigned char*)CFileHelper::getFileData(spr.c_str(), cMode, &uSize); CSpriteFileStream fileSpr; if (fileSpr.Write((const char*)pBuf, uSize) == 0) { delete[] pBuf; return false; } delete[] pBuf; fileSpr.SetPosition(0); int tableSize = fileSpr.ReadByte(); this->m_vTileTable.assign(tableSize, ScutTileTable()); for (int i = 0; i < tableSize; i++) { ScutTileTable& tt = this->m_vTileTable[i]; tt.imgIndex = fileSpr.ReadByte(); tt.clip.origin.x = fileSpr.ReadShort(); tt.clip.origin.y = fileSpr.ReadShort(); tt.clip.size.width = fileSpr.ReadShort(); tt.clip.size.height = fileSpr.ReadShort(); } double pixcelFactor = 1.0; int imgSize = fileSpr.ReadByte(); CCTexture2D* pTex = NULL; this->m_vTexture.assign(imgSize, ReplaceTexture()); string texFile; for (int j = 0; j < imgSize; j++) { ReplaceTexture& texture = this->m_vTexture[j]; fileSpr.ReadUTF(texFile); texFile = SPRITE_IMAGE_DIR + texFile; texFile = CFileHelper::getPath(texFile.c_str()); pTex = CCTextureCache::sharedTextureCache()->addImage(texFile.c_str()); assert(pTex != NULL); CC_SAFE_RETAIN(pTex); texture.pTex = pTex; texture.replaceIndex = fileSpr.ReadByte(); texture.dFactor = (double)pTex->getContentSizeInPixels().width / (double)fileSpr.ReadShort(); // 取第一张图片的缩放比例作为动画整体的估计值 if (0 == j) { pixcelFactor = texture.dFactor; } } this->caculateTileTableTextureCoord(); CScutAniData* pAniData = NULL; CScutFrame* pFrame = NULL; CScutTile* pTile = NULL; int aniSize = fileSpr.ReadByte(); this->m_vAniData.assign(aniSize, pAniData); for (int m = 0; m < aniSize; m++) { pAniData = new CScutAniData; this->m_vAniData[m] = pAniData; pAniData->m_tContentSize.width = fileSpr.ReadShort() * pixcelFactor; pAniData->m_tContentSize.height = fileSpr.ReadShort() * pixcelFactor; pAniData->m_anchorX = fileSpr.ReadShort(); pAniData->m_anchorY = fileSpr.ReadShort(); pAniData->m_type = fileSpr.ReadByte(); int frameSize = fileSpr.ReadByte(); pAniData->m_vFrame.assign(frameSize, pFrame); for (int n = 0; n < frameSize; n++) { pFrame = new CScutFrame; pAniData->m_vFrame[n] = pFrame; pFrame->m_duration = fileSpr.ReadShort(); int tileSize = fileSpr.ReadByte(); pFrame->m_vTiles.assign(tileSize, pTile); for (int tl = 0; tl < tileSize; tl++) { float fx = fileSpr.ReadShort(); float fy = fileSpr.ReadShort(); int flipXY = fileSpr.ReadByte(); float rotation = fileSpr.ReadShort(); float scale = fileSpr.ReadFloat(); int tableIndex = fileSpr.ReadShort(); assert(tableIndex > -1 && tableIndex < this->m_vTileTable.size()); if (tableIndex > -1 && tableIndex < this->m_vTileTable.size()) { pTile = new CScutTile(this->m_vTileTable[tableIndex]); assert(pTile->m_tt.imgIndex > -1 && pTile->m_tt.imgIndex < m_vTexture.size()); // 根据每个tile所属的图片精确计算缩放因子 double factor = this->m_vTexture[pTile->m_tt.imgIndex].dFactor; pFrame->m_vTiles[tl] = pTile; pFrame->setScutAniGroup(this); pTile->m_frameX = fx * factor; pTile->m_frameY = fy * factor; pTile->m_flipX = (flipXY & CScutTile::FLIP_X) > 0; pTile->m_flipY = (flipXY & CScutTile::FLIP_Y) > 0; pTile->m_rotation = rotation; pTile->m_scale = scale; pTile->caculateTileVertices(pAniData->m_anchorX * factor, pAniData->m_anchorY * factor); } } } } return true; }
void FTextureManager::ParseWarp(FScanner &sc) { const BITFIELD texflags = TEXMAN_Overridable | TEXMAN_TryAny; bool isflat = false; bool type2 = sc.Compare ("warp2"); // [GRB] sc.MustGetString (); if (sc.Compare ("flat")) { isflat = true; sc.MustGetString (); } else if (sc.Compare ("texture")) { isflat = false; sc.MustGetString (); } else { sc.ScriptError (NULL); } FTextureID picnum = CheckForTexture (sc.String, isflat ? FTexture::TEX_Flat : FTexture::TEX_Wall, texflags); if (picnum.isValid()) { FTexture *warper = Texture(picnum); if (warper->Name.IsEmpty()) { // long texture name: We cannot do warps on these due to the way the texture manager implements warping as a texture replacement. sc.ScriptError ("You cannot use \"warp\" for long texture names."); } // don't warp a texture more than once if (!warper->bWarped) { warper = new FWarpTexture (warper, type2? 2:1); ReplaceTexture (picnum, warper, false); } if (sc.CheckFloat()) { static_cast<FWarpTexture*>(warper)->SetSpeed(float(sc.Float)); } // No decals on warping textures, by default. // Warping information is taken from the last warp // definition for this texture. warper->bNoDecals = true; if (sc.GetString ()) { if (sc.Compare ("allowdecals")) { warper->bNoDecals = false; } else { sc.UnGet (); } } } }
void TextureBlitTest::setupContent() { static const Ogre::String ColorTextureName = "VTests_TextureBlit_color_texture"; static const Ogre::String DepthTextureName = "VTests_TextureBlit_depth_texture"; static const int TextureSize = 8; mViewport->setBackgroundColour(ColourValue(0.8,0.8,0.8)); /// TEST COLOUR m_colorTexture = Ogre::TextureManager::getSingleton().createManual( ColorTextureName, Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, Ogre::TEX_TYPE_2D, TextureSize, TextureSize, 0, Ogre::PF_BYTE_RGB, Ogre::TU_DYNAMIC_WRITE_ONLY_DISCARDABLE); Ogre::PixelBox pb(ColorImage.width, ColorImage.height, 1, Ogre::PF_BYTE_RGB, (void *)ColorImage.pixel_data); Ogre::HardwarePixelBufferSharedPtr buffer = m_colorTexture->getBuffer(); buffer->blitFromMemory(pb); // Get the material Ogre::MaterialPtr matColourPtr = Ogre::MaterialManager::getSingleton().getByName("Examples/OgreDance"); ReplaceTexture(matColourPtr, ColorTextureName); // create a standard plane entity Entity* ent = mSceneMgr->createEntity("Plane_color", SceneManager::PT_PLANE); // attach it to a node, scale it, and position appropriately SceneNode* node = mSceneMgr->getRootSceneNode()->createChildSceneNode(); node->setPosition(-30.0, 0.0, 0.0); node->setScale(0.25, 0.25, 0.25); node->attachObject(ent); ent->setMaterial(matColourPtr); // give it the material we prepared /// TEST DEPTH m_depthTexture = Ogre::TextureManager::getSingleton().createManual( DepthTextureName, Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, Ogre::TEX_TYPE_2D, TextureSize, TextureSize, 0, Ogre::PF_DEPTH, Ogre::TU_DYNAMIC_WRITE_ONLY_DISCARDABLE); Ogre::PixelBox dpb(DepthImage.width, DepthImage.height, 1, Ogre::PF_DEPTH, (void *)DepthImage.pixel_data); Ogre::HardwarePixelBufferSharedPtr dbuffer = m_depthTexture->getBuffer(); dbuffer->blitFromMemory(dpb); // Get the material Ogre::MaterialPtr matDepthPtr = Ogre::MaterialManager::getSingleton().getByName("Examples/OgreParade"); ReplaceTexture(matDepthPtr, DepthTextureName); // create a standard plane entity Entity* depthEnt = mSceneMgr->createEntity("Plane_depth", SceneManager::PT_PLANE); // attach it to a node, scale it, and position appropriately SceneNode* depthNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); depthNode->setPosition(30.0, 0.0, 0.0); depthNode->setScale(0.25, 0.25, 0.25); depthNode->attachObject(depthEnt); depthEnt->setMaterial(matDepthPtr); // give it the material we prepared mCamera->setPosition(0,0,125); mCamera->setDirection(0,0,-1); }