Ejemplo n.º 1
0
        private void CreateShaderMaterials(Quake3Level q3lvl, SceneManager sm)
        {
            // NB this only works for the 'default' shaders for now
            // i.e. those that don't have a .shader script and thus default
            // to just texture + lightmap
            // TODO: pre-parse all .shader files and create lookup for next stage (use ROGL shader_file_t)

            // Material names are shadername#lightmapnumber
            // This is because I like to define materials up front completely
            // rather than combine lightmap and shader dynamically (it's
            // more generic). It results in more materials, but they're small
            // beer anyway. Texture duplication is prevented by infrastructure.
            // To do this I actually need to parse the faces since they have the
            // shader/lightmap combo (lightmap number is not in the shader since
            // it can be used with multiple lightmaps)
            string shaderName;
            int    face = q3lvl.Faces.Length;

            while (face-- > 0)
            {
                // Check to see if existing material
                // Format shader#lightmap
                int shadIdx = q3lvl.Faces[face].shader;

                shaderName = String.Format("{0}#{1}", q3lvl.Shaders[shadIdx].name, q3lvl.Faces[face].lmTexture);
                Material shadMat = sm.GetMaterial(shaderName);

                if (shadMat == null && !bspOptions.useLightmaps)
                {
                    // try the no-lightmap material
                    shaderName = String.Format("{0}#n", q3lvl.Shaders[shadIdx].name);
                    shadMat    = sm.GetMaterial(shaderName);
                }

                if (shadMat == null)
                {
                    // Colour layer
                    // NB no extension in Q3A(doh), have to try shader, .jpg, .tga
                    string tryName = q3lvl.Shaders[shadIdx].name;

                    // Try shader first
                    Quake3Shader shader = (Quake3Shader)Quake3ShaderManager.Instance.GetByName(tryName);

                    if (shader != null)
                    {
                        shadMat = shader.CreateAsMaterial(sm, q3lvl.Faces[face].lmTexture);
                    }
                    else
                    {
                        // No shader script, try default type texture
                        shadMat = sm.CreateMaterial(shaderName);
                        Pass shadPass = shadMat.GetTechnique(0).GetPass(0);

                        // Try jpg
                        TextureUnitState tex = shadPass.CreateTextureUnitState(tryName + ".jpg");
                        tex.Load();

                        if (tex.IsBlank)
                        {
                            // Try tga
                            tex.SetTextureName(tryName + ".tga");
                        }

                        // Set replace on all first layer textures for now
                        tex.SetColorOperation(LayerBlendOperation.Replace);
                        tex.TextureAddressing = TextureAddressing.Wrap;

                        // for ambient lighting
                        tex.ColorBlendMode.source2 = LayerBlendSource.Manual;

                        if (bspOptions.useLightmaps && q3lvl.Faces[face].lmTexture != -1)
                        {
                            // Add lightmap, additive blending
                            tex = shadPass.CreateTextureUnitState(String.Format("@lightmap{0}", q3lvl.Faces[face].lmTexture));

                            // Blend
                            tex.SetColorOperation(LayerBlendOperation.Modulate);

                            // Use 2nd texture co-ordinate set
                            tex.TextureCoordSet = 1;

                            // Clamp
                            tex.TextureAddressing = TextureAddressing.Clamp;
                        }

                        shadMat.CullingMode = CullingMode.None;
                        shadMat.Lighting    = false;
                    }
                }

                shadMat.Load();

                // Copy face data
                BspStaticFaceGroup dest = CopyShaderFaceData(q3lvl, face, shadMat, shadIdx);

                faceGroups[face] = dest;
            }
        }