//------------------------------------------------------ void MaterialService::prepareMaterialInstance(MaterialPtr& mat, unsigned int idx, int tag) { if (tag < 0) // Should not be here if the polygon is sky textured OPDE_EXCEPT("Non-instanced material instance requested", "MaterialService::prepareMaterialInstance"); mat->setReceiveShadows(true); StringUtil::StrStreamType lightmapName; lightmapName << "@lightmap" << tag; Pass *shadPass = mat->getTechnique(0)->getPass(0); if (shadPass->getNumTextureUnitStates() <= 1) { // Lightmap texture is added here TextureUnitState* tex = shadPass->createTextureUnitState(lightmapName.str()); // Blend tex->setColourOperation(LBO_MODULATE); // Use 2nd texture co-ordinate set tex->setTextureCoordSet(1); // Clamp tex->setTextureAddressingMode(TextureUnitState::TAM_CLAMP); // Switch filtering off to see lmap pixels: TFO_NONE tex->setTextureFiltering(TFO_BILINEAR); } else { // There is a definition of the lightmapping pass already, we only update that definition TextureUnitState* tex = shadPass->getTextureUnitState(1); tex->setTextureName(lightmapName.str()); tex->setTextureCoordSet(1); } }
// --------------------------------------------------------------------- void MaterialService::createJorgeMaterial(const Ogre::String& resourceGroup) { std::string shaderName("@template0"); if (!MaterialManager::getSingleton().resourceExists(shaderName)) { MaterialPtr shadMat = MaterialManager::getSingleton().create(shaderName, resourceGroup); shadMat->setReceiveShadows(true); Pass *shadPass = shadMat->getTechnique(0)->getPass(0); shadPass->setAmbient(0.5, 0.5, 0.5); shadPass->setDiffuse(1, 1, 1, 1); shadPass->setSpecular(1, 1, 1, 1); // Texture unit state for the main texture... // jorge.png is compiled-in - see the RenderService::prepareHardcodedMedia TextureUnitState* tus = shadPass->createTextureUnitState("jorge.png"); // Set replace on all first layer textures for now tus->setTextureAddressingMode(TextureUnitState::TAM_WRAP); tus->setTextureCoordSet(0); tus->setTextureFiltering(TFO_BILINEAR); tus->setTextureUScale(1.0f); tus->setTextureVScale(1.0f); // No dynamic lighting shadMat->setLightingEnabled(false); shadMat->load(); addWorldMaterialTemplate(0, shadMat); // fixed at slot 0 } }
//----------------------------------------------------------------------- MaterialPtr Quake3Shader::createAsMaterial(int lightmapNumber) { String matName; StringUtil::StrStreamType str; String resourceGroup = ResourceGroupManager::getSingleton().getWorldResourceGroupName(); str << mName << "#" << lightmapNumber; matName = str.str(); MaterialPtr mat = MaterialManager::getSingleton().create(matName, resourceGroup); Ogre::Pass* ogrePass = mat->getTechnique(0)->getPass(0); LogManager::getSingleton().logMessage("Using Q3 shader " + mName, LML_CRITICAL); for (int p = 0; p < numPasses; ++p) { TextureUnitState* t; // Create basic texture if (pass[p].textureName == "$lightmap") { StringUtil::StrStreamType str2; str2 << "@lightmap" << lightmapNumber; t = ogrePass->createTextureUnitState(str2.str()); } // Animated texture support else if (pass[p].animNumFrames > 0) { Real sequenceTime = pass[p].animNumFrames / pass[p].animFps; /* Pre-load textures We need to know if each one was loaded OK since extensions may change for each Quake3 can still include alternate extension filenames e.g. jpg instead of tga Pain in the arse - have to check for each frame as letters<n>.tga for example is different per frame! */ for (unsigned int alt = 0; alt < pass[p].animNumFrames; ++alt) { if (!ResourceGroupManager::getSingleton().resourceExists( resourceGroup, pass[p].frames[alt])) { // Try alternate extension pass[p].frames[alt] = getAlternateName(pass[p].frames[alt]); if (!ResourceGroupManager::getSingleton().resourceExists( resourceGroup, pass[p].frames[alt])) { // stuffed - no texture continue; } } } t = ogrePass->createTextureUnitState(""); t->setAnimatedTextureName(pass[p].frames, pass[p].animNumFrames, sequenceTime); } else { // Quake3 can still include alternate extension filenames e.g. jpg instead of tga // Pain in the arse - have to check for failure if (!ResourceGroupManager::getSingleton().resourceExists( resourceGroup, pass[p].textureName)) { // Try alternate extension pass[p].textureName = getAlternateName(pass[p].textureName); if (!ResourceGroupManager::getSingleton().resourceExists( resourceGroup, pass[p].textureName)) { // stuffed - no texture continue; } } t = ogrePass->createTextureUnitState(pass[p].textureName); } // Blending if (p == 0) { // scene blend mat->setSceneBlending(pass[p].blendSrc, pass[p].blendDest); if (mat->isTransparent()) mat->setDepthWriteEnabled(false); t->setColourOperation(LBO_REPLACE); // Alpha mode ogrePass->setAlphaRejectSettings( pass[p].alphaFunc, pass[p].alphaVal); } else { if (pass[p].customBlend) { // Fallback for now t->setColourOperation(LBO_MODULATE); } else { // simple layer blend t->setColourOperation(pass[p].blend); } // Alpha mode, prefer 'most alphary' CompareFunction currFunc = ogrePass->getAlphaRejectFunction(); unsigned char currVal = ogrePass->getAlphaRejectValue(); if (pass[p].alphaFunc > currFunc || (pass[p].alphaFunc == currFunc && pass[p].alphaVal < currVal)) { ogrePass->setAlphaRejectSettings( pass[p].alphaFunc, pass[p].alphaVal); } } // Tex coords if (pass[p].texGen == TEXGEN_BASE) { t->setTextureCoordSet(0); } else if (pass[p].texGen == TEXGEN_LIGHTMAP) { t->setTextureCoordSet(1); } else if (pass[p].texGen == TEXGEN_ENVIRONMENT) { t->setEnvironmentMap(true, TextureUnitState::ENV_PLANAR); } // Tex mod // Scale t->setTextureUScale(pass[p].tcModScale[0]); t->setTextureVScale(pass[p].tcModScale[1]); // Procedural mods // Custom - don't use mod if generating environment // Because I do env a different way it look horrible if (pass[p].texGen != TEXGEN_ENVIRONMENT) { if (pass[p].tcModRotate) { t->setRotateAnimation(pass[p].tcModRotate); } if (pass[p].tcModScroll[0] || pass[p].tcModScroll[1]) { if (pass[p].tcModTurbOn) { // Turbulent scroll if (pass[p].tcModScroll[0]) { t->setTransformAnimation(TextureUnitState::TT_TRANSLATE_U, WFT_SINE, pass[p].tcModTurb[0], pass[p].tcModTurb[3], pass[p].tcModTurb[2], pass[p].tcModTurb[1]); } if (pass[p].tcModScroll[1]) { t->setTransformAnimation(TextureUnitState::TT_TRANSLATE_V, WFT_SINE, pass[p].tcModTurb[0], pass[p].tcModTurb[3], pass[p].tcModTurb[2], pass[p].tcModTurb[1]); } } else { // Constant scroll t->setScrollAnimation(pass[p].tcModScroll[0], pass[p].tcModScroll[1]); } } if (pass[p].tcModStretchWave != SHADER_FUNC_NONE) { WaveformType wft; switch(pass[p].tcModStretchWave) { case SHADER_FUNC_SIN: wft = WFT_SINE; break; case SHADER_FUNC_TRIANGLE: wft = WFT_TRIANGLE; break; case SHADER_FUNC_SQUARE: wft = WFT_SQUARE; break; case SHADER_FUNC_SAWTOOTH: wft = WFT_SAWTOOTH; break; case SHADER_FUNC_INVERSESAWTOOTH: wft = WFT_INVERSE_SAWTOOTH; break; default: break; } // Create wave-based stretcher t->setTransformAnimation(TextureUnitState::TT_SCALE_U, wft, pass[p].tcModStretchParams[3], pass[p].tcModStretchParams[0], pass[p].tcModStretchParams[2], pass[p].tcModStretchParams[1]); t->setTransformAnimation(TextureUnitState::TT_SCALE_V, wft, pass[p].tcModStretchParams[3], pass[p].tcModStretchParams[0], pass[p].tcModStretchParams[2], pass[p].tcModStretchParams[1]); } } // Address mode t->setTextureAddressingMode(pass[p].addressMode); //assert(!t->isBlank()); } // Do farbox (create new material) // Set culling mode and lighting to defaults mat->setCullingMode(CULL_NONE); mat->setManualCullingMode(cullMode); mat->setLightingEnabled(false); mat->load(); return mat; }
//----------------------------------------------------------------------- void MaterialService::createStandardMaterial(unsigned int idx, std::string matName, std::string textureName, std::string resourceGroup) { Image tex; bool loaded = false; // indicates we were successful finding the texture StringVectorPtr texnames = ResourceGroupManager::getSingleton().findResourceNames(resourceGroup, textureName + ".*"); if (texnames->size() <= 0) { // no results, try the localised version // prev. path + /language/filename String locresname = mConfigService->getLocalisedResourcePath(textureName); LOG_INFO("Specified resource (%s) was not found, trying localized version: %s", textureName.c_str(), locresname.c_str()); texnames = ResourceGroupManager::getSingleton().findResourceNames(resourceGroup, locresname + ".*"); } String txtfile; // Let's try the extensions from the extensions vector StringVector::iterator it = texnames->begin(); for (; it != texnames->end(); it++) { // Try loading every given try { tex.load((*it), resourceGroup); TextureManager::getSingleton().loadImage(textureName, resourceGroup, tex, TEX_TYPE_2D, 5, 1.0f); txtfile = (*it); loaded = true; break; // we got it! } catch (Ogre::Exception) { // Nothing. We are trying more extensions } } if (!loaded) LOG_ERROR("Image %s was not found, texture will be invalid!", textureName.c_str()); // Construct a material out of this texture. We'll just clone the material upstairs to enable lmap-txture combinations MaterialPtr shadMat = MaterialManager::getSingleton().create(matName, resourceGroup); shadMat->setReceiveShadows(true); Pass *shadPass = shadMat->getTechnique(0)->getPass(0); shadPass->setAmbient(0.5, 0.5, 0.5); shadPass->setDiffuse(1, 1, 1, 1); shadPass->setSpecular(1, 1, 1, 1); TextureUnitState* tus = createAnimatedTextureState(shadPass, txtfile, resourceGroup, 5); // Set replace on all first layer textures for now // tus->setColourOperation(LBO_REPLACE); tus->setTextureAddressingMode(TextureUnitState::TAM_WRAP); tus->setTextureCoordSet(0); tus->setTextureFiltering(TFO_BILINEAR); tus->setTextureUScale(1.0f); tus->setTextureVScale(1.0f); // tus->setTextureFiltering(TFO_NONE); // Set culling mode to none // shadMat->setCullingMode(CULL_ANTICLOCKWISE); // No dynamic lighting shadMat->setLightingEnabled(false); // DYNL: shadMat->load(); // standard size addWorldMaterialTemplate(idx, shadMat); }