// ------------------------------------------------------------------------------------------------ void LWOImporter::LoadLWO2TextureBlock(LE_NCONST IFF::SubChunkHeader* head, unsigned int size ) { ai_assert(!mSurfaces->empty()); LWO::Surface& surf = mSurfaces->back(); LWO::Texture tex; // load the texture header LoadLWO2TextureHeader(head->length,tex); size -= head->length + 6; // now get the exact type of the texture switch (head->type) { case AI_LWO_PROC: LoadLWO2Procedural(size,tex); break; case AI_LWO_GRAD: LoadLWO2Gradient(size,tex); break; case AI_LWO_IMAP: LoadLWO2ImageMap(size,tex); } // get the destination channel TextureList* listRef = NULL; switch (tex.type) { case AI_LWO_COLR: listRef = &surf.mColorTextures;break; case AI_LWO_DIFF: listRef = &surf.mDiffuseTextures;break; case AI_LWO_SPEC: listRef = &surf.mSpecularTextures;break; case AI_LWO_GLOS: listRef = &surf.mGlossinessTextures;break; case AI_LWO_BUMP: listRef = &surf.mBumpTextures;break; case AI_LWO_TRAN: listRef = &surf.mOpacityTextures;break; case AI_LWO_REFL: listRef = &surf.mReflectionTextures;break; default: DefaultLogger::get()->warn("LWO2: Encountered unknown texture type"); return; } // now attach the texture to the parent surface - sort by ordinal string for (TextureList::iterator it = listRef->begin();it != listRef->end(); ++it) { if (::strcmp(tex.ordinal.c_str(),(*it).ordinal.c_str()) < 0) { listRef->insert(it,tex); return; } } listRef->push_back(tex); }
//--------------------------------------------------------------------- void CompositorManager::freePooledTextures(bool onlyIfUnreferenced) { if (onlyIfUnreferenced) { for (TexturesByDef::iterator i = mTexturesByDef.begin(); i != mTexturesByDef.end(); ++i) { TextureList* texList = i->second; for (TextureList::iterator j = texList->begin(); j != texList->end();) { // if the resource system, plus this class, are the only ones to have a reference.. // NOTE: any material references will stop this texture getting freed (e.g. compositor demo) // until this routine is called again after the material no longer references the texture if (j->useCount() == ResourceGroupManager::RESOURCE_SYSTEM_NUM_REFERENCE_COUNTS + 1) { TextureManager::getSingleton().remove((*j)->getHandle()); j = texList->erase(j); } else ++j; } } for (ChainTexturesByDef::iterator i = mChainTexturesByDef.begin(); i != mChainTexturesByDef.end(); ++i) { TextureDefMap& texMap = i->second; for (TextureDefMap::iterator j = texMap.begin(); j != texMap.end();) { const TexturePtr& tex = j->second; if (tex.useCount() == ResourceGroupManager::RESOURCE_SYSTEM_NUM_REFERENCE_COUNTS + 1) { TextureManager::getSingleton().remove(tex->getHandle()); texMap.erase(j++); } else ++j; } } } else { // destroy all for (TexturesByDef::iterator i = mTexturesByDef.begin(); i != mTexturesByDef.end(); ++i) { OGRE_DELETE_T(i->second, TextureList, MEMCATEGORY_GENERAL); } mTexturesByDef.clear(); mChainTexturesByDef.clear(); } }
void GL_GetSkyColor(float *r, float *g, float *b) { int skyTex; if ((level.flags & LEVEL_SWAPSKIES) || (sky2texture == sky1texture)) { skyTex = sky1texture; } else { skyTex = sky2texture; } textureList.GetTexture(skyTex, true); textureList.GetAverageColor(r, g, b); }
TextureMap* ReadTexture(TiXmlElement *element) { const char* texName = element->Attribute("texture"); if ( texName == NULL ) return NULL; Texture *tex = NULL; if ( COMPARE(texName,"checkerboard") ) { TextureChecker *ctex = new TextureChecker; tex = ctex; printf(" Texture: Checker Board\n"); for ( TiXmlElement *child = element->FirstChildElement(); child!=NULL; child = child->NextSiblingElement() ) { if ( COMPARE( child->Value(), "color1" ) ) { Color c(0,0,0); ReadColor( child, c ); ctex->SetColor1(c); printf(" color1 %f %f %f\n",c.r,c.g,c.b); } else if ( COMPARE( child->Value(), "color2" ) ) { Color c(0,0,0); ReadColor( child, c ); ctex->SetColor2(c); printf(" color2 %f %f %f\n",c.r,c.g,c.b); } } textureList.Append( tex, texName ); } else { printf(" Texture: File \"%s\"",texName); tex = textureList.Find( texName ); if ( tex == NULL ) { TextureFile *ftex = new TextureFile; tex = ftex; ftex->SetName(texName); if ( ! ftex->Load() ) { printf(" -- Error loading file!"); delete tex; tex = NULL; } else { textureList.Append( tex, texName ); } } printf("\n"); } TextureMap *map = new TextureMap(tex); LoadTransform(map,element,1); return map; }
void WaterNode::Handle(RenderingEventArg arg){ if (waterShader != NULL){ Vector<2, int> dim(400,300); reflectionFbo = new FrameBuffer(dim, 1, false); arg.renderer.BindFrameBuffer(reflectionFbo); waterShader->SetTexture("reflection", reflectionFbo->GetTexAttachment(0)); if (normaldudvmap != NULL) waterShader->SetTexture("normaldudvmap", (ITexture2DPtr)normaldudvmap); waterShader->Load(); TextureList texs = waterShader->GetTextures(); for (unsigned int i = 0; i < texs.size(); ++i) arg.renderer.LoadTexture(texs[i].get()); }else if (surface != NULL) arg.renderer.LoadTexture(surface); }
GameResources::GameResources(AppService& appService) { Sound& sound = appService.getSound(); Console& console = appService.getConsole(); TextureManager& textureManager = appService.getTextureManager(); console.printLine("\n===Initializing game resources==="); console.printLine("\n...Weapon initialization"); Weapon::initialize(sound, textureManager); console.printLine("...Building water-list"); Water::initialize(sound, appService.getTextureManager()); console.printLine("...Loading game sounds"); roundStartSound = sound.loadSample("sound/game/round-start.wav"); gameOverSound = sound.loadSample("sound/game/game-over.wav"); console.printLine(Format("...Loading block meta data: {0}") << D6_FILE_BLOCK_META); blockMeta = Block::loadMeta(D6_FILE_BLOCK_META); console.printLine(Format("...Loading block textures: {0}") << D6_TEXTURE_BLOCK_PATH); blockTextures = textureManager.load(D6_TEXTURE_BLOCK_PATH, TextureFilter::LINEAR, true); console.printLine(Format("...Loading background textures: {0}") << D6_TEXTURE_BCG_PATH); bcgTextures = textureManager.load(D6_TEXTURE_BCG_PATH, TextureFilter::LINEAR, true); console.printLine(Format("...Loading explosion textures: {0}") << D6_TEXTURE_EXPL_PATH); explosionTextures = textureManager.load(D6_TEXTURE_EXPL_PATH, TextureFilter::NEAREST, true); console.printLine(Format("...Loading bonus textures: {0}") << D6_TEXTURE_EXPL_PATH); bonusTextures = textureManager.load(D6_TEXTURE_BONUS_PATH, TextureFilter::LINEAR, true); console.printLine(Format("...Loading elevator textures: {0}") << D6_TEXTURE_ELEVATOR_PATH); elevatorTextures = textureManager.load(D6_TEXTURE_ELEVATOR_PATH, TextureFilter::LINEAR, true); console.printLine(Format("...Loading fire textures: {0}") << D6_TEXTURE_FIRE_PATH); for (const FireType& fireType : FireType::values()) { TextureList texture = textureManager.load(Format("{0}{1,3|0}/") << D6_TEXTURE_FIRE_PATH << fireType.getId(), TextureFilter::LINEAR, true); fireTextures[fireType.getId()] = texture; glBindTexture(GL_TEXTURE_2D, texture.at(2).getId()); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); } console.printLine("\n...Bonus initialization"); BonusType::initialize(bonusTextures); }
TextureAtlas::TextureAtlas(const char* path, float scale, TextureList regions) : TextureAtlas(path, scale) { regions_.reserve(regions.size()); for (auto&& p : regions) { add_region(std::get<0>(p), std::get<1>(p), std::get<2>(p), std::get<3>(p)); } }
void sendToShader( GLuint shaderProgram ) { auto numTextures = diffuseTextures.size(); for( int i = 0; i != numTextures; i++ ) { glActiveTexture( GL_TEXTURE0 + i ); std::stringstream stream; stream << "diffuse" << i; std::string uniformName = stream.str(); glBindTexture( GL_TEXTURE_2D, diffuseTextures[ i ]->id ); glUniform1i( glGetUniformLocation( shaderProgram, uniformName.c_str() ), i ); } }
TextureAtlas::TextureAtlas(const char* id, const DataMap& data, float scale, TextureList regions) : TextureAtlas(id, data, scale) { regions_.reserve(regions.size()); for (auto&& p : regions) { add_region(std::get<0>(p), std::get<1>(p), std::get<2>(p), std::get<3>(p)); } }
void TextureManager::reloadTextures() { m_collectionMap.clear(); m_texturesCaseSensitive.clear(); m_texturesCaseInsensitive.clear(); m_texturesByName.clear(); m_texturesByUsage.clear(); typedef std::pair<TextureMap::iterator, bool> InsertResult; for (size_t i = 0; i < m_collections.size(); i++) { TextureCollection* collection = m_collections[i]; const TextureList textures = collection->textures(); for (size_t j = 0; j < textures.size(); j++) { Texture* texture = textures[j]; m_collectionMap[texture] = collection; InsertResult result = m_texturesCaseSensitive.insert(TextureMapEntry(texture->name(), texture)); if (!result.second) { // texture with this name already existed result.first->second->setOverridden(true); m_texturesCaseSensitive.erase(result.first); m_texturesCaseSensitive.insert(TextureMapEntry(texture->name(), texture)); } m_texturesCaseInsensitive[Utility::toLower(texture->name())] = texture; texture->setOverridden(false); } } TextureMap::iterator it, end; for (it = m_texturesCaseSensitive.begin(), end = m_texturesCaseSensitive.end(); it != end; ++it) { Texture* texture = it->second; m_texturesByName.push_back(texture); m_texturesByUsage.push_back(texture); } std::sort(m_texturesByName.begin(), m_texturesByName.end(), CompareTexturesByName()); }
//--------------------------------------------------------------------- TexturePtr CompositorManager::getPooledTexture(const String& name, const String& localName, size_t w, size_t h, PixelFormat f, uint aa, const String& aaHint, bool srgb, CompositorManager::UniqueTextureSet& texturesAssigned, CompositorInstance* inst, CompositionTechnique::TextureScope scope) { if (scope == CompositionTechnique::TS_GLOBAL) { OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS, "Global scope texture can not be pooled.", "CompositorManager::getPooledTexture"); } TextureDef def(w, h, f, aa, aaHint, srgb); if (scope == CompositionTechnique::TS_CHAIN) { StringPair pair = std::make_pair(inst->getCompositor()->getName(), localName); TextureDefMap& defMap = mChainTexturesByDef[pair]; TextureDefMap::iterator it = defMap.find(def); if (it != defMap.end()) { return it->second; } // ok, we need to create a new one TexturePtr newTex = TextureManager::getSingleton().createManual( name, ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME, TEX_TYPE_2D, (uint)w, (uint)h, 0, f, TU_RENDERTARGET, 0, srgb, aa, aaHint); defMap.insert(TextureDefMap::value_type(def, newTex)); return newTex; } TexturesByDef::iterator i = mTexturesByDef.find(def); if (i == mTexturesByDef.end()) { TextureList* texList = OGRE_NEW_T(TextureList, MEMCATEGORY_GENERAL); i = mTexturesByDef.insert(TexturesByDef::value_type(def, texList)).first; } CompositorInstance* previous = inst->getChain()->getPreviousInstance(inst); CompositorInstance* next = inst->getChain()->getNextInstance(inst); TexturePtr ret; TextureList* texList = i->second; // iterate over the existing textures and check if we can re-use for (TextureList::iterator t = texList->begin(); t != texList->end(); ++t) { TexturePtr& tex = *t; // check not already used if (texturesAssigned.find(tex.get()) == texturesAssigned.end()) { bool allowReuse = true; // ok, we didn't use this one already // however, there is an edge case where if we re-use a texture // which has an 'input previous' pass, and it is chained from another // compositor, we can end up trying to use the same texture for both // so, never allow a texture with an input previous pass to be // shared with its immediate predecessor in the chain if (isInputPreviousTarget(inst, localName)) { // Check whether this is also an input to the output target of previous // can't use CompositorInstance::mPreviousInstance, only set up // during compile if (previous && isInputToOutputTarget(previous, tex)) allowReuse = false; } // now check the other way around since we don't know what order they're bound in if (isInputToOutputTarget(inst, localName)) { if (next && isInputPreviousTarget(next, tex)) allowReuse = false; } if (allowReuse) { ret = tex; break; } } } if (ret.isNull()) { // ok, we need to create a new one ret = TextureManager::getSingleton().createManual( name, ResourceGroupManager::INTERNAL_RESOURCE_GROUP_NAME, TEX_TYPE_2D, (uint)w, (uint)h, 0, f, TU_RENDERTARGET, 0, srgb, aa, aaHint); texList->push_back(ret); } // record that we used this one in the requester's list texturesAssigned.insert(ret.get()); return ret; }
// ------------------------------------------------------------------------------------------------ bool LWOImporter::HandleTextures(aiMaterial* pcMat, const TextureList& in, aiTextureType type) { ai_assert(NULL != pcMat); unsigned int cur = 0, temp = 0; aiString s; bool ret = false; for (TextureList::const_iterator it = in.begin(), end = in.end();it != end;++it) { if (!(*it).enabled || !(*it).bCanUse) continue; ret = true; // Convert lightwave's mapping modes to ours. We let them // as they are, the GenUVcoords step will compute UV // channels if they're not there. aiTextureMapping mapping; switch ((*it).mapMode) { case LWO::Texture::Planar: mapping = aiTextureMapping_PLANE; break; case LWO::Texture::Cylindrical: mapping = aiTextureMapping_CYLINDER; break; case LWO::Texture::Spherical: mapping = aiTextureMapping_SPHERE; break; case LWO::Texture::Cubic: mapping = aiTextureMapping_BOX; break; case LWO::Texture::FrontProjection: DefaultLogger::get()->error("LWO2: Unsupported texture mapping: FrontProjection"); mapping = aiTextureMapping_OTHER; break; case LWO::Texture::UV: { if( UINT_MAX == (*it).mRealUVIndex ) { // We have no UV index for this texture, so we can't display it continue; } // add the UV source index temp = (*it).mRealUVIndex; pcMat->AddProperty<int>((int*)&temp,1,AI_MATKEY_UVWSRC(type,cur)); mapping = aiTextureMapping_UV; } break; default: ai_assert(false); }; if (mapping != aiTextureMapping_UV) { // Setup the main axis aiVector3D v; switch ((*it).majorAxis) { case Texture::AXIS_X: v = aiVector3D(1.f,0.f,0.f); break; case Texture::AXIS_Y: v = aiVector3D(0.f,1.f,0.f); break; default: // case Texture::AXIS_Z: v = aiVector3D(0.f,0.f,1.f); break; } pcMat->AddProperty(&v,1,AI_MATKEY_TEXMAP_AXIS(type,cur)); // Setup UV scalings for cylindric and spherical projections if (mapping == aiTextureMapping_CYLINDER || mapping == aiTextureMapping_SPHERE) { aiUVTransform trafo; trafo.mScaling.x = (*it).wrapAmountW; trafo.mScaling.y = (*it).wrapAmountH; BOOST_STATIC_ASSERT(sizeof(aiUVTransform)/sizeof(float) == 5); pcMat->AddProperty(&trafo,1,AI_MATKEY_UVTRANSFORM(type,cur)); } DefaultLogger::get()->debug("LWO2: Setting up non-UV mapping"); } // The older LWOB format does not use indirect references to clips. // The file name of a texture is directly specified in the tex chunk. if (mIsLWO2) { // find the corresponding clip (take the last one if multiple // share the same index) ClipList::iterator end = mClips.end(), candidate = end; temp = (*it).mClipIdx; for (ClipList::iterator clip = mClips.begin(); clip != end; ++clip) { if ((*clip).idx == temp) { candidate = clip; } } if (candidate == end) { DefaultLogger::get()->error("LWO2: Clip index is out of bounds"); temp = 0; // fixme: apparently some LWO files shipping with Doom3 don't // have clips at all ... check whether that's true or whether // it's a bug in the loader. s.Set("$texture.png"); //continue; } else { if (Clip::UNSUPPORTED == (*candidate).type) { DefaultLogger::get()->error("LWO2: Clip type is not supported"); continue; } AdjustTexturePath((*candidate).path); s.Set((*candidate).path); // Additional image settings int flags = 0; if ((*candidate).negate) { flags |= aiTextureFlags_Invert; } pcMat->AddProperty(&flags,1,AI_MATKEY_TEXFLAGS(type,cur)); } } else { std::string ss = (*it).mFileName; if (!ss.length()) { DefaultLogger::get()->error("LWOB: Empty file name"); continue; } AdjustTexturePath(ss); s.Set(ss); } pcMat->AddProperty(&s,AI_MATKEY_TEXTURE(type,cur)); // add the blend factor pcMat->AddProperty<float>(&(*it).mStrength,1,AI_MATKEY_TEXBLEND(type,cur)); // add the blend operation switch ((*it).blendType) { case LWO::Texture::Normal: case LWO::Texture::Multiply: temp = (unsigned int)aiTextureOp_Multiply; break; case LWO::Texture::Subtractive: case LWO::Texture::Difference: temp = (unsigned int)aiTextureOp_Subtract; break; case LWO::Texture::Divide: temp = (unsigned int)aiTextureOp_Divide; break; case LWO::Texture::Additive: temp = (unsigned int)aiTextureOp_Add; break; default: temp = (unsigned int)aiTextureOp_Multiply; DefaultLogger::get()->warn("LWO2: Unsupported texture blend mode: alpha or displacement"); } // Setup texture operation pcMat->AddProperty<int>((int*)&temp,1,AI_MATKEY_TEXOP(type,cur)); // setup the mapping mode pcMat->AddProperty<int>((int*)&mapping,1,AI_MATKEY_MAPPING(type,cur)); // add the u-wrapping temp = (unsigned int)GetMapMode((*it).wrapModeWidth); pcMat->AddProperty<int>((int*)&temp,1,AI_MATKEY_MAPPINGMODE_U(type,cur)); // add the v-wrapping temp = (unsigned int)GetMapMode((*it).wrapModeHeight); pcMat->AddProperty<int>((int*)&temp,1,AI_MATKEY_MAPPINGMODE_V(type,cur)); ++cur; } return ret; }
void GL_DrawSky() { float angle; FTexture *tex; bool drawBoth = false; int sky1tex, sky2tex; int s1p, s2p; drawBoth = !((level.flags & LEVEL_SWAPSKIES) || (sky2texture == sky1texture)); if ((level.flags & LEVEL_SWAPSKIES) || (sky2texture == sky1texture)) { sky1tex = sky2texture; s1p = sky2pos; sky2tex = sky1texture; s2p = sky1pos; } else { sky1tex = sky1texture; s1p = sky1pos; sky2tex = sky2texture; s2p = sky2pos; } glDepthMask(GL_FALSE); glDisable(GL_DEPTH_TEST); glDisable(GL_FOG); glDisable(GL_ALPHA_TEST); glPushMatrix(); angle = s2p * 1.f / (FRACUNIT * 2.f); glRotatef(-angle, 0.f, 1.f, 0.f); textureList.BindTexture(sky2tex, true); tex = TexMan(sky2tex); texw = tex->GetWidth(); texh = tex->GetHeight(); tx = ty = 1.f; yMult = 1.f; GL_RenderSkyHemisphere(SKYHEMI_UPPER); GL_RenderSkyHemisphere(SKYHEMI_LOWER); if (drawBoth) { angle = (s1p * 1.f / (FRACUNIT * 2.f)) - angle; glRotatef(-angle, 0.f, 1.f, 0.f); tex = TexMan(sky1tex); textureList.BindTexture(sky1tex, true); texw = tex->GetWidth(); texh = tex->GetHeight(); if (level.flags & LEVEL_DOUBLESKY && texh <= 128) { yMult = 2.f; } tx = ty = 1.f; GL_RenderSkyHemisphere(SKYHEMI_UPPER); GL_RenderSkyHemisphere(SKYHEMI_LOWER); } glPopMatrix(); glEnable(GL_DEPTH_TEST); glEnable(GL_ALPHA_TEST); glFogf(GL_FOG_MODE, GL_EXP); glDepthMask(GL_TRUE); if (gl_depthfog && !Player->fixedcolormap) { glEnable(GL_FOG); } }
int LoadScene(const char *filename) { TiXmlDocument doc(filename); if ( ! doc.LoadFile() ) { printf("Failed to load the file \"%s\"\n", filename); return 0; } TiXmlElement *xml = doc.FirstChildElement("xml"); if ( ! xml ) { printf("No \"xml\" tag found.\n"); return 0; } TiXmlElement *scene = xml->FirstChildElement("scene"); if ( ! scene ) { printf("No \"scene\" tag found.\n"); return 0; } TiXmlElement *cam = xml->FirstChildElement("camera"); if ( ! cam ) { printf("No \"camera\" tag found.\n"); return 0; } nodeMtlList.clear(); rootNode.Init(); materials.DeleteAll(); lights.DeleteAll(); objList.Clear(); textureList.Clear(); LoadScene( scene ); rootNode.ComputeChildBoundBox(); // Assign materials int numNodes = nodeMtlList.size(); for ( int i=0; i<numNodes; i++ ) { Material *mtl = materials.Find( nodeMtlList[i].mtlName ); if ( mtl ) nodeMtlList[i].node->SetMaterial(mtl); } nodeMtlList.clear(); // Load Camera camera.Init(); camera.dir += camera.pos; TiXmlElement *camChild = cam->FirstChildElement(); while ( camChild ) { if ( COMPARE( camChild->Value(), "position" ) ) ReadVector(camChild,camera.pos); else if ( COMPARE( camChild->Value(), "target" ) ) ReadVector(camChild,camera.dir); else if ( COMPARE( camChild->Value(), "up" ) ) ReadVector(camChild,camera.up); else if ( COMPARE( camChild->Value(), "fov" ) ) ReadFloat (camChild,camera.fov); else if ( COMPARE( camChild->Value(), "width" ) ) camChild->QueryIntAttribute("value", &camera.imgWidth); else if ( COMPARE( camChild->Value(), "height" ) ) camChild->QueryIntAttribute("value", &camera.imgHeight); camChild = camChild->NextSiblingElement(); } camera.dir -= camera.pos; camera.dir.Normalize(); Point3 x = camera.dir ^ camera.up; camera.up = (x ^ camera.dir).GetNormalized(); renderImage.Init( camera.imgWidth, camera.imgHeight ); return 1; }
double GraphicsEntity::Render( TextureList& out, float frameTime, AnimSpeed speed ) { if( !Active() ) return 0.; // Shouldn't happen; inactive doesn't collide with camera const size_t layCount = m_Layers.Size(); if( layCount == 0 ) return 0.; std::vector<GraphCompLoc> layers; RSKMAP_ITERATE( m_Layers ) layers.push_back( iter->first ); if( layCount > 1 ) { // // Basic loc value sorting to maintain layer consistency GraphCompLoc nll, naa; for( size_t lll = layCount-1; lll < layCount; --lll ) { nll = layers[lll]; for( size_t aaa = lll-1; aaa < layCount; --aaa ) { naa = layers[aaa]; if( naa < nll ) { layers[lll] = naa; layers[aaa] = nll; nll = naa; } } } if( m_HaveOffset && mp_Sort ) { // // At least one loc has an offset, so sort by loc offset size_t lll, aaa; GraphCompLoc mll; int ox, oy, oz, aox, aoy, aoz; for( lll = 0; lll < layCount; ++lll ) { nll = layers[lll]; const rsk::Vector3I& offset = m_Offsets[nll]; ox = offset.x; oy = offset.y; oz = offset.z; for( aaa = lll+1; aaa < layCount; ++aaa ) { naa = layers[aaa]; const rsk::Vector3I& offset = m_Offsets[naa]; aox = offset.x; aoy = offset.y; aoz = offset.z; mll = mp_Sort( nll, naa, ox, oy, oz, aox, aoy, aoz ); if( mll != nll ) { layers[lll] = mll; layers[aaa] = nll; nll = mll; ox = aox; oy = aoy; oz = aoz; } } } // for lll } // if have offset } // if layCount > 1 // // Commit the layers to be rendered for( size_t lll = layCount-1; lll < layCount; --lll ) out.push_back( m_Layers[ layers[lll] ]->Render(frameTime, speed) ); return m_Rotation; }