long CObjectManager::loadObjectTable() { char * path = "Data/Objects/ObjectTable.dat"; std::fstream objectTable; objectTable.open(path, std::ios::in); struct entry { long type; char* path; }; entry curEntry; std::string etype; std::string epath; while (!objectTable.eof()) { if (objectTable.get() == '{') { char* tmp = (char*)malloc(1024); objectTable.getline(tmp, 1024); int counter = 0; for (int it = 0; tmp[it] != ';' && tmp[it] != '}'; ++it) { if (tmp[it] == ' ') { continue; } etype.push_back(tmp[it]); counter = it; } for (int it = counter + 2; tmp[it] != ';' && tmp[it] != '}'; ++it) { if (tmp[it] == ' ') { continue; } epath.push_back(tmp[it]); } curEntry.type = getTypeFromString(etype.c_str()); curEntry.path = const_cast<char*>(epath.c_str()); CObject* obj; switch (curEntry.type) { case EMaterial: { CMaterial mat = loadMatFromFile(curEntry.path); obj = new CMaterial(mat.getName(), mat.getTexture(), mat.getCollision(), mat.getWalkspeed()); obj->registerObj(mat.getName()); m_ObjectMap.insert(std::pair<std::string, CObject*>(obj->getID(), obj)); }break; } etype.clear(); epath.clear(); } } objectTable.close(); return 0; }
CMaterial(const CMaterial& that) { for(auto it = mTextures.begin(); it != mTextures.end(); ++it) { delete it->second; it->second = nullptr; mTextures[it->first] = that.getTexture(it->first); } mOptions = that.mOptions; }
// ************************************************************************************************* void makeInstanceTransparent(UInstance &inst, uint8 opacity, bool disableZWrite) { UShape shape= inst.getShape(); if(shape.empty()) return; uint numMats= shape.getNumMaterials(); if(numMats==0) return; if(numMats!=inst.getNumMaterials()) return; // instance transparent or not? if (opacity == 255) { // reset default shape opacity / transparency inst.setOpacity(shape.getDefaultOpacity()); inst.setTransparency(shape.getDefaultTransparency()); inst.setBypassLODOpacityFlag(false); } else { // Will have some blend material => sure not to be rendered in Opaque pass inst.setOpacity(false); inst.setTransparency(true); inst.setBypassLODOpacityFlag(true); // these flags prevails over the current lods flags for multi-lod objects } // set all materials for (uint32 j = 0; j < numMats; ++j) { NL3D::UInstanceMaterial matInst = inst.getMaterial(j); NL3D::UMaterial matShape= shape.getMaterial(j); // disalbe zwrite? if(disableZWrite) matInst.setZWrite(false); else matInst.setZWrite(matShape.getZWrite()); // if no more transparent if (opacity == 255) { // reset to default matInst.setBlend(matShape.getBlend()); matInst.setBlendFunc((NL3D::UInstanceMaterial::TBlend)matShape.getSrcBlend(), (NL3D::UInstanceMaterial::TBlend)matShape.getDstBlend()); // if orginal material is opaque or additif and has no alpha test, then ensure restore last tex env if needed CMaterial *destInternalMat = matInst.getObjectPtr(); if (!matShape.getBlend() && !matShape.getAlphaTest()) { if (destInternalMat->getShader() == CMaterial::Normal) { CMaterial *srcInternalMat = matShape.getObjectPtr(); uint numTex = 0; for (;numTex < 4 && srcInternalMat->getTexture(numTex) != NULL; ++numTex) {} if (numTex > 0) { if (srcInternalMat->getTexEnvMode(numTex - 1) != destInternalMat->getTexEnvMode(numTex - 1)) { destInternalMat->setTexEnvMode(numTex - 1, srcInternalMat->getTexEnvMode(numTex - 1)); } } } } if (destInternalMat->getShader() == CMaterial::Normal) { // if !lighted, restore color if (!destInternalMat->isLighted()) { CMaterial *srcInternalMat = matShape.getObjectPtr(); // restore alpha in color CRGBA color = destInternalMat->getColor(); color.A = srcInternalMat->getColor().A; destInternalMat->setColor(color); } } } else { // Enable blend matInst.setBlend(true); // If default is ???/one or , then use a srcalpha/one (eg: for Diamond-like weapons) if(matShape.getBlend() && (sint32)matShape.getDstBlend()==(sint32)NL3D::UInstanceMaterial::one) matInst.setBlendFunc(NL3D::UInstanceMaterial::srcalpha, NL3D::UInstanceMaterial::one); // else use a standard srcalpha/invsrcalpha else matInst.setBlendFunc(NL3D::UInstanceMaterial::srcalpha, NL3D::UInstanceMaterial::invsrcalpha); // if orginal material is opaque or additif and has no alpha test, then ensure that the alpha output is 'diffuse' CMaterial *internalMat = matInst.getObjectPtr(); if (!matShape.getBlend() && !matShape.getAlphaTest()) { if (internalMat->getShader() == CMaterial::Normal) { uint numTex = 0; for (;numTex < 4 && internalMat->getTexture(numTex) != NULL; ++numTex) {} if (numTex > 0) { internalMat->texEnvOpAlpha(numTex - 1, CMaterial::Replace); // if material is unlighted, then use the constant at this stage to set the alpha internalMat->texEnvArg0Alpha(numTex - 1, CMaterial::Diffuse, CMaterial::SrcAlpha); } } } if (internalMat->getShader() == CMaterial::Normal) { if (!internalMat->isLighted()) { // replace alpha in color CRGBA color = internalMat->getColor(); color.A = opacity; internalMat->setColor(color); } } } // suppose that default opacity is always 255 if (matInst.isLighted()) { matInst.setOpacity(opacity); } matInst.setAlphaTestThreshold(matShape.getAlphaTestThreshold()*((float)opacity)/255.0f); } }
bool CRenderSystem::prepareMaterial(/*const */CMaterial& material, float fOpacity) // 由于使用了自动注册纹理的机制,很遗憾的导致不能用“const” { CTextureMgr& TM = GetTextureMgr(); for (size_t i=0;i<8;++i) { if (material.uTexture[i]==-1) { material.uTexture[i] = TM.RegisterTexture(material.getTexture(i)); } // ---- SetTexture(i, material.uTexture[i]); // ---- if (material.uTexture[i]==0) { break; } } if (material.uShader==-1) { material.uShader = GetShaderMgr().registerItem(material.getShader()); } // ---- SetLightingEnabled(material.bLightingEnabled); SetCullingMode((CullingMode)material.uCull); // ---- SetAlphaTestFunc(material.bAlphaTest, (CompareFunction)material.nAlphaTestCompare, material.uAlphaTestValue); SetBlendFunc(material.bBlend, (SceneBlendOperation)material.nBlendOP, (SceneBlendFactor)material.nBlendSrc, (SceneBlendFactor)material.nBlendDest); SetDepthBufferFunc(material.bDepthTest,material.bDepthWrite); // ---- if (0==material.uShader) { for (size_t i=0;i<8;++i) { CMaterial::TextureOP& texOP = material.textureOP[i]; SetTextureColorOP(i, (TextureBlendOperation)texOP.nColorOP, (TextureBlendSource)texOP.nColorSrc1, (TextureBlendSource)texOP.nColorSrc2); SetTextureColorOP(i, (TextureBlendOperation)texOP.nAlphaOP, (TextureBlendSource)texOP.nAlphaSrc1, (TextureBlendSource)texOP.nAlphaSrc2); if (TBOP_DISABLE == texOP.nColorOP) { break; } } } else { CShader* pShader = GetShaderMgr().getSharedShader(); if (pShader) { // for Terrain pShader->setVec2D("g_fScaleUV",material.vUVScale); } SetShader(material.uShader); } return true; /* if (material.bLightingEnabled) { SetMaterial(material.vAmbient,material.vDiffuse); } if (0==material.uShader) { //SetSamplerAddressUV(0,ADDRESS_WRAP,ADDRESS_WRAP); if (material.vTexAnim.lengthSquared()>0.0f) { Matrix matTex=Matrix::UNIT; float fTime = (float)GetGlobalTimer().GetTime(); matTex._13=fTime*material.vTexAnim.x; matTex._23=fTime*material.vTexAnim.y; setTextureMatrix(0, TTF_COUNT3, matTex); } Color32 cFactor = material.cEmissive; if (material.m_fOpacity<0.0f) { fOpacity = (float)(rand()%255)/255.0f; } else { fOpacity *= material.m_fOpacity; } if (material.uDiffuse) { SetTexture(0, material.uDiffuse); cFactor.a=(unsigned char)(cFactor.a*fOpacity); SetTextureFactor(cFactor); if (material.bLightingEnabled) { SetTextureColorOP(0, TBOP_MODULATE, TBS_TEXTURE, TBS_DIFFUSE); } else { SetTextureColorOP(0, TBOP_MODULATE, TBS_TEXTURE, TBS_TFACTOR); } if(material.bBlend||material.m_fOpacity<1.0f) { SetBlendFunc(true, BLENDOP_ADD, SBF_SOURCE_ALPHA, SBF_ONE_MINUS_SOURCE_ALPHA); } if (material.m_fOpacity<1.0f) { SetTextureAlphaOP(0, TBOP_MODULATE, TBS_TEXTURE, TBS_TFACTOR); } else if (material.bAlphaTest||material.bBlend) { SetTextureAlphaOP(0, TBOP_SOURCE1, TBS_TEXTURE); } else { SetTextureAlphaOP(0, TBOP_DISABLE); } ////////////////////////////////////////////////////////////////////////// if (material.uSpecular) { SetTexture(1, material.uSpecular); SetTextureColorOP(0, TBOP_MODULATE, TBS_TEXTURE, TBS_DIFFUSE); setResultARGToTemp(1,true); SetTextureColorOP(1, TBOP_MODULATE_X2, TBS_TEXTURE, TBS_SPECULAR); SetTextureColorOP(2, TBOP_ADD, TBS_CURRENT, TBS_TEMP); SetTexCoordIndex(0,0); SetTexCoordIndex(1,0); SetTexCoordIndex(2,0); } else if (material.uReflection) { SetTextureColorOP(1, TBOP_MODULATE_X2, TBS_CURRENT, TBS_TEXTURE); SetTexCoordIndex(1,TCI_CAMERASPACE_NORMAL|TCI_CAMERASPACE_POSITION); SetTexture(1, material.uReflection); } else if (material.uLightMap) { SetTextureColorOP(1, TBOP_MODULATE, TBS_CURRENT, TBS_TEXTURE); SetTexCoordIndex(1,1); SetTexture(1, material.uLightMap); } else if (material.uEmissive) { SetTextureColorOP(1, TBOP_ADD, TBS_CURRENT, TBS_TEXTURE); SetTexture(1, material.uEmissive); } else if(!material.bBlend&&material.m_fOpacity>=1.0f) { SetTextureColorOP(0, TBOP_MODULATE, TBS_TEXTURE, TBS_DIFFUSE); } } else { SetTextureFactor(cFactor); if (material.uSpecular) { //SetTexture(0, material.uSpecular); SetTextureColorOP(0, TBOP_SOURCE1, TBS_SPECULAR); SetTexCoordIndex(0,0); } else if(material.uReflection) { cFactor.r=(unsigned char)(cFactor.r*fOpacity); cFactor.g=(unsigned char)(cFactor.g*fOpacity); cFactor.b=(unsigned char)(cFactor.b*fOpacity); SetTextureFactor(cFactor); if (material.bBlend) { SetBlendFunc(true, BLENDOP_ADD, SBF_DEST_COLOUR, SBF_ONE); } SetTextureColorOP(0, TBOP_MODULATE, TBS_TEXTURE, TBS_TFACTOR); SetTextureAlphaOP(0, TBOP_DISABLE); SetTexCoordIndex(0,TCI_CAMERASPACE_NORMAL|TCI_CAMERASPACE_POSITION); SetTexture(0, material.uReflection); } else if (material.uLightMap) { if (material.bBlend) { SetBlendFunc(true, BLENDOP_ADD, SBF_DEST_COLOUR, SBF_ZERO); } SetTextureColorOP(0, TBOP_MODULATE, TBS_TEXTURE, TBS_TFACTOR); SetTextureAlphaOP(0, TBOP_DISABLE); SetTexture(0, material.uLightMap); } else if (material.uEmissive) { cFactor.r=(unsigned char)(cFactor.r*fOpacity); cFactor.g=(unsigned char)(cFactor.g*fOpacity); cFactor.b=(unsigned char)(cFactor.b*fOpacity); SetTextureFactor(cFactor); if (material.bBlend) { SetBlendFunc(true, BLENDOP_ADD, SBF_ONE, SBF_ONE); } SetTextureColorOP(0, TBOP_MODULATE, TBS_TEXTURE, TBS_TFACTOR); SetTextureAlphaOP(0, TBOP_DISABLE); SetTexture(0, material.uEmissive); } else if (material.uNormal) { CShader* pShader = GetShaderMgr().getSharedShader(); if (pShader) { static size_t s_uShaderID = GetShaderMgr().registerItem("EngineRes\\fx\\SpaceBump.fx"); pShader->setTexture("g_texNormal",material.uNormal); SetShader(s_uShaderID); } //SetBlendFunc(true, BLENDOP_ADD, SBF_DEST_COLOUR, SBF_ZERO); //SetTextureColorOP(0, TBOP_MODULATE, TBS_TEXTURE, TBS_TFACTOR); //SetTextureAlphaOP(0, TBOP_DISABLE); //SetTexture(0, uLightMap); } else { SetTextureColorOP(0,TBOP_SOURCE2); if (material.bBlend) { SetTextureAlphaOP(0,TBOP_SOURCE2); } else { SetTextureAlphaOP(0,TBOP_DISABLE); } //return false; } } } else { CShader* pShader = GetShaderMgr().getSharedShader(); if (pShader) { pShader->setTexture("g_texDiffuse",material.uDiffuse); pShader->setTexture("g_texLight",material.uLightMap); pShader->setTexture("g_texNormal",material.uNormal); //pShader->setTexture("g_texEnvironment",uEmissive); //pShader->setTexture("g_texEmissive",uEmissive); pShader->setTexture("g_texSpecular",material.uSpecular); // for Terrain pShader->setVec2D("g_fScaleUV",material.vUVScale); } SetShader(material.uShader); } return true;*/ }