예제 #1
0
 public static void ApplyGLTextureParameters(MDL0MaterialRefNode mr)
 {
     //GL.TexParameter(TextureTarget.Texture2D, (TextureParameterName)ExtTextureFilterAnisotropic.MaxTextureMaxAnisotropyExt, 1 << mr._maxAniso);
     GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureLodBias, mr.LODBias);
     GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)_magFilters[(int)mr.MagFilter]);
     GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)_minFilters[(int)mr.MinFilter]);
     GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)_wraps[(int)mr.UWrapMode]);
     GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)_wraps[(int)mr.VWrapMode]);
 }
        private void CreateRef()
        {
            if (_resource.Children.Count < 8)
            {
                MDL0MaterialRefNode node = new MDL0MaterialRefNode();
                _resource.AddChild(node);
                node.Default();
                _resource.SignalPropertyChange();

                if (node.Model.AutoMetalMaterials && ((MDL0MaterialNode)node.Parent).MetalMaterial != null)
                    ((MDL0MaterialNode)node.Parent).MetalMaterial.UpdateAsMetal();

                Nodes[Nodes.Count - 1].EnsureVisible();
                //TreeView.SelectedNode = Nodes[Nodes.Count - 1];
            }
        }
예제 #3
0
        internal unsafe void Prepare(MDL0MaterialRefNode mRef, int shaderProgramHandle, string palette = null)
        {
            string plt = !String.IsNullOrEmpty(palette) ? palette : mRef.Palette;

            if (!String.IsNullOrEmpty(plt))
            {
                if (_palette == null || _palette.Name != plt)
                {
                    SetPalette(mRef.RootNode.FindChild("Palettes(NW4R)/" + plt, true) as PLT0Node);
                }
            }
            else if (_palette != null)
            {
                SetPalette(null);
            }

            if (Texture != null)
            {
                Texture.Bind(mRef.Index, shaderProgramHandle);
            }
            else
            {
                Load(mRef.Index, shaderProgramHandle);
            }

            ApplyGLTextureParameters(mRef);

            if (shaderProgramHandle <= 0)
            {
                float *p = stackalloc float[4];
                p[0] = p[1] = p[2] = p[3] = 1.0f;
                if (Selected && !ObjOnly)
                {
                    p[0] = -1.0f;
                }

                GL.Light(LightName.Light0, LightParameter.Specular, p);
                GL.Light(LightName.Light0, LightParameter.Diffuse, p);
            }
        }
예제 #4
0
        public string GenerateVertexShaderCode(TKContext ctx)
        {
            tempShader = "";
            tabs       = 0;

            uint lightMask = 0;

            if (UsableMaterialNode.LightChannels > 0)
            {
                lightMask |= (uint)UsableMaterialNode._chan1._color.Lights | (uint)UsableMaterialNode._chan1._alpha.Lights;
            }
            if (UsableMaterialNode.LightChannels > 1)
            {
                lightMask |= (uint)UsableMaterialNode._chan2._color.Lights | (uint)UsableMaterialNode._chan2._alpha.Lights;
            }

            w("//Vertex Shader\n");

            // A few required defines and ones that will make our lives a lot easier
            if (ctx.bSupportsGLSLBinding || ctx.bSupportsGLSLUBO)
            {
                w("#version 330 compatibility\n");
                if (ctx.bSupportsGLSLBinding)
                {
                    w("#extension GL_ARB_shading_language_420pack : enable\n");
                }
                //if (ctx.bSupportsGLSLUBO)
                //    w("#extension GL_ARB_uniform_buffer_object : enable\n");
            }
            else
            {
                w("#version 120\n");
            }

            if (ctx.bSupportsGLSLATTRBind)
            {
                w("#extension GL_ARB_explicit_attrib_location : enable\n");
            }

            // Silly differences
            w("#define float2 vec2\n");
            w("#define float3 vec3\n");
            w("#define float4 vec4\n");

            // cg to glsl function translation
            w("#define frac(x) fract(x)\n");
            w("#define saturate(x) clamp(x, 0.0f, 1.0f)\n");
            w("#define lerp(x, y, z) mix(x, y, z)\n");

            //// uniforms
            //if (ctx.bSupportsGLSLUBO)
            //    w("layout(std140) uniform VSBlock\n{\n");

            //w("{0}float4 " + I_POSNORMALMATRIX + "[6];\n", WriteLocation(ctx));
            //w("{0}float4 " + I_PROJECTION + "[4];\n", WriteLocation(ctx));
            w("{0}float4 " + I_MATERIALS + "[4];\n", WriteLocation(ctx));
            w("{0}float4 " + I_LIGHTS + "[40];\n", WriteLocation(ctx));

            //Tex effect matrices
            w("{0}float4 " + I_TEXMATRICES + "[24];\n", WriteLocation(ctx)); // also using tex matrices

            w("{0}float4 " + I_TRANSFORMMATRICES + "[64];\n", WriteLocation(ctx));
            //w("{0}float4 " + I_NORMALMATRICES + "[32];\n", WriteLocation(ctx));
            //w("{0}float4 " + I_POSTTRANSFORMMATRICES + "[64];\n", WriteLocation(ctx));
            //w("{0}float4 " + I_DEPTHPARAMS + ";\n", WriteLocation(ctx));

            //if (ctx.bSupportsGLSLUBO) w("};\n");

            GenerateVSOutputStruct();

            if (_normalNode != null)
            {
                w("float3 rawnorm0 = gl_Normal;\n");
            }

            //if (ctx.bSupportsGLSLATTRBind)
            //{
            //    if (_vertexFormat.HasPosMatrix)
            //        Write("layout(location = {0}) ATTRIN float fposmtx;\n", SHADER_POSMTX_ATTRIB);
            //    //if (components & VB_HAS_NRM1)
            //    //    Write("layout(location = {0}) ATTRIN float3 rawnorm1;\n", SHADER_NORM1_ATTRIB);
            //    //if (components & VB_HAS_NRM2)
            //    //    Write("layout(location = {0}) ATTRIN float3 rawnorm2;\n", SHADER_NORM2_ATTRIB);
            //}
            //else
            //{
            //    if (_vertexFormat.HasPosMatrix)
            //        Write("ATTRIN float fposmtx; // ATTR{0},\n", SHADER_POSMTX_ATTRIB);
            //    //if (components & VB_HAS_NRM1)
            //    //    Write("ATTRIN float3 rawnorm1; // ATTR%d,\n", SHADER_NORM1_ATTRIB);
            //    //if (components & VB_HAS_NRM2)
            //    //    Write("ATTRIN float3 rawnorm2; // ATTR%d,\n", SHADER_NORM2_ATTRIB);
            //}

            if (_colorSet[0] != null)
            {
                w("float4 color0 = gl_Color;\n");
            }
            if (_colorSet[1] != null)
            {
                w("float4 color1 = gl_SecondaryColor;\n");
            }

            for (int i = 0; i < 8; i++)
            {
                bool hastexmtx = _arrayFlags.GetHasTexMatrix(i);
                if (_uvSet[i] != null || hastexmtx)
                {
                    w("float{1} tex{0} = gl_MultiTexCoord{0}.xy{2};\n", i, hastexmtx ? 3 : 2, hastexmtx ? "z" : "");
                }
            }

            w("float4 rawpos = gl_Vertex;\n");
            w("void main()\n{\n");
            w("VS_OUTPUT o;\n");

            // transforms
            //if (_vertexFormat.HasPosMatrix)
            //{
            //    w("int posmtx = int(fposmtx);\n");

            //    w("float4 pos = float4(dot(" + I_TRANSFORMMATRICES + "[posmtx], rawpos), dot(" + I_TRANSFORMMATRICES + "[posmtx+1], rawpos), dot(" + I_TRANSFORMMATRICES + "[posmtx+2], rawpos), 1);\n");

            //    if (_normalNode != null)
            //    {
            //        w("int normidx = posmtx >= 32 ? (posmtx-32) : posmtx;\n");
            //        w("float3 N0 = " + I_NORMALMATRICES + "[normidx].xyz, N1 = " + I_NORMALMATRICES + "[normidx+1].xyz, N2 = " + I_NORMALMATRICES + "[normidx+2].xyz;\n");
            //    }

            //    if (_normalNode != null)
            //        w("float3 _norm0 = normalize(float3(dot(N0, rawnorm0), dot(N1, rawnorm0), dot(N2, rawnorm0)));\n");
            //    //if (components & VB_HAS_NRM1)
            //    //    w("float3 _norm1 = float3(dot(N0, rawnorm1), dot(N1, rawnorm1), dot(N2, rawnorm1));\n");
            //    //if (components & VB_HAS_NRM2)
            //    //    w("float3 _norm2 = float3(dot(N0, rawnorm2), dot(N1, rawnorm2), dot(N2, rawnorm2));\n");
            //}
            //else
            //{
            //    w("float4 pos = float4(dot(" + I_POSNORMALMATRIX + "[0], rawpos), dot(" + I_POSNORMALMATRIX + "[1], rawpos), dot(" + I_POSNORMALMATRIX + "[2], rawpos), 1.0f);\n");
            //    if (_normalNode != null)
            //        w("float3 _norm0 = normalize(float3(dot(" + I_POSNORMALMATRIX + "[3].xyz, rawnorm0), dot(" + I_POSNORMALMATRIX + "[4].xyz, rawnorm0), dot(" + I_POSNORMALMATRIX + "[5].xyz, rawnorm0)));\n");
            //    //if (components & VB_HAS_NRM1)
            //    //    w("float3 _norm1 = float3(dot("+I_POSNORMALMATRIX+"[3].xyz, rawnorm1), dot("+I_POSNORMALMATRIX+"[4].xyz, rawnorm1), dot("+I_POSNORMALMATRIX+"[5].xyz, rawnorm1));\n");
            //    //if (components & VB_HAS_NRM2)
            //    //    w("float3 _norm2 = float3(dot("+I_POSNORMALMATRIX+"[3].xyz, rawnorm2), dot("+I_POSNORMALMATRIX+"[4].xyz, rawnorm2), dot("+I_POSNORMALMATRIX+"[5].xyz, rawnorm2));\n");
            //}

            w("float4 pos = gl_ModelViewProjectionMatrix * rawpos;\n");
            if (_normalNode != null)
            {
                w("float3 _norm0 = rawnorm0;\n");
            }

            if (_normalNode == null)
            {
                w("float3 _norm0 = float3(0.0f, 0.0f, 0.0f);\n");
            }

            w("o.pos = pos;\n");//float4(dot("+I_PROJECTION+"[0], pos), dot("+I_PROJECTION+"[1], pos), dot("+I_PROJECTION+"[2], pos), dot("+I_PROJECTION+"[3], pos));\n");

            w("float4 mat, lacc;\nfloat3 ldir, h;\nfloat dist, dist2, attn;\n");

            if (UsableMaterialNode.LightChannels == 0)
            {
                if (_colorSet[0] != null)
                {
                    w("o.colors_0 = color0;\n");
                }
                else
                {
                    w("o.colors_0 = float4(1.0f, 1.0f, 1.0f, 1.0f);\n");
                }
            }

            // TODO: This probably isn't necessary if pixel lighting is enabled.
            tempShader += GenerateLightingShader(I_MATERIALS, I_LIGHTS, "color", "o.colors_");

            if (UsableMaterialNode.LightChannels < 2)
            {
                if (_colorSet[1] != null)
                {
                    w("o.colors_1 = color1;\n");
                }
                else
                {
                    w("o.colors_1 = o.colors_0;\n");
                }
            }

            // transform texcoords
            w("float4 coord = float4(0.0f, 0.0f, 1.0f, 1.0f);\n");
            for (int i = 0; i < UsableMaterialNode.Children.Count; i++)
            {
                MDL0MaterialRefNode texgen = UsableMaterialNode.Children[i] as MDL0MaterialRefNode;

                w("{\n");
                w("//Texgen " + i + "\n");
                switch (texgen.Coordinates)
                {
                case TexSourceRow.Geometry:
                    _assert_(texgen.InputForm == TexInputForm.AB11);
                    w("coord = rawpos;\n");     // pos.w is 1
                    break;

                case TexSourceRow.Normals:
                    if (_normalNode != null)
                    {
                        _assert_(texgen.InputForm == TexInputForm.ABC1);
                        w("coord = float4(rawnorm0.xyz, 1.0f);\n");
                    }
                    break;

                case TexSourceRow.Colors:
                    _assert_(texgen.Type == TexTexgenType.Color0 || texgen.Type == TexTexgenType.Color1);
                    break;

                case TexSourceRow.BinormalsT:
                //if (components & VB_HAS_NRM1)
                //{
                //      _assert_(texgen.InputForm == TexInputForm.ABC1);
                //    Write("coord = float4(rawnorm1.xyz, 1.0f);\n");
                //}
                //break;
                case TexSourceRow.BinormalsB:
                //if (components & VB_HAS_NRM2)
                //{
                //    _assert_(texgen.InputForm == TexInputForm.ABC1);
                //    Write("coord = float4(rawnorm2.xyz, 1.0f);\n");
                //}
                //break;
                default:
                    _assert_(texgen.Coordinates <= TexSourceRow.TexCoord7);
                    int c = texgen.Coordinates - TexSourceRow.TexCoord0;
                    if (_uvSet[c] != null)
                    {
                        w("coord = float4(tex{0}.x, tex{0}.y, 1.0f, 1.0f);\n", c);
                    }
                    break;
                }

                // first transformation
                switch (texgen.Type)
                {
                case TexTexgenType.EmbossMap:     // calculate tex coords into bump map
                    //if (components & (VB_HAS_NRM1|VB_HAS_NRM2))
                    //{
                    //    // transform the light dir into tangent space
                    //    Write("ldir = normalize("+I_LIGHTS+"[{0} + 3].xyz - pos.xyz);\n", texgen.EmbossLight);
                    //    Write("o.tex{0}.xyz = o.tex{1}.xyz + float3(dot(ldir, _norm1), dot(ldir, _norm2), 0.0f);\n", i, texgen.EmbossSource);
                    //}
                    //else
                    //{
                    //    //_assert_(0); // should have normals
                    //    Write("o.tex{0}.xyz = o.tex{1}.xyz;\n", i, texgen.EmbossSource);
                    //}

                    break;

                case TexTexgenType.Color0:
                case TexTexgenType.Color1:
                    _assert_(texgen.Coordinates == TexSourceRow.Colors);
                    w("o.tex{0}.xyz = float3(o.colors_{1}.x, o.colors_{1}.y, 1);\n", i, ((int)texgen.Type - (int)TexTexgenType.Color0).ToString());
                    break;

                case TexTexgenType.Regular:
                default:
                    if (_arrayFlags.GetHasTexMatrix(i))
                    {
                        w("int tmp = int(tex{0}.z);\n", i);
                        if (texgen.Projection == TexProjection.STQ)
                        {
                            w("o.tex{0}.xyz = float3(dot(coord, " + I_TRANSFORMMATRICES + "[tmp]), dot(coord, " + I_TRANSFORMMATRICES + "[tmp+1]), dot(coord, " + I_TRANSFORMMATRICES + "[tmp+2]));\n", i);
                        }
                        else
                        {
                            w("o.tex{0}.xyz = float3(dot(coord, " + I_TRANSFORMMATRICES + "[tmp]), dot(coord, " + I_TRANSFORMMATRICES + "[tmp+1]), 1);\n", i);
                            w("o.tex{0}.z = 1.0f", 1);
                        }
                    }
                    else
                    {
                        if (texgen.Projection == TexProjection.STQ)
                        {
                            w("o.tex{0}.xyz = float3(dot(coord, " + I_TEXMATRICES + "[{1}]), dot(coord, " + I_TEXMATRICES + "[{2}]), dot(coord, " + I_TEXMATRICES + "[{3}]));\n", i, 3 * i, 3 * i + 1, 3 * i + 2);
                        }
                        else
                        {
                            w("o.tex{0}.xyz = float3(dot(coord, " + I_TEXMATRICES + "[{1}]), dot(coord, " + I_TEXMATRICES + "[{2}]), 1);\n", i, 3 * i, 3 * i + 1);
                        }
                    }
                    break;
                }

                //Dual tex trans always enabled?
                if (texgen.Type == TexTexgenType.Regular)
                {
                    // only works for regular tex gen types?
                    //int postidx = texgen.DualTexFlags.DualMtx;
                    //w("float4 P0 = " + I_POSTTRANSFORMMATRICES + "[{0}];\n"+
                    //  "float4 P1 = " + I_POSTTRANSFORMMATRICES + "[{1}];\n"+
                    //  "float4 P2 = " + I_POSTTRANSFORMMATRICES + "[{2}];\n",
                    //  postidx&0x3f, (postidx+1)&0x3f, (postidx+2)&0x3f);

                    if (texgen.Normalize)
                    {
                        w("o.tex{0}.xyz = normalize(o.tex{0}.xyz);\n", i);
                    }

                    // multiply by postmatrix
                    //w("o.tex{0}.xyz = float3(dot(P0.xyz, o.tex{0}.xyz) + P0.w, dot(P1.xyz, o.tex{0}.xyz) + P1.w, dot(P2.xyz, o.tex{0}.xyz) + P2.w);\n", i);
                }

                w("}\n");
            }

            // clipPos/w needs to be done in pixel shader, not here
            if (UsableMaterialNode.Children.Count < 7)
            {
                w("o.clipPos = float4(pos.x,pos.y,o.pos.z,o.pos.w);\n");
            }
            else
            {
                w("o.tex0.w = pos.x;\n");
                w("o.tex1.w = pos.y;\n");
                w("o.tex2.w = o.pos.z;\n");
                w("o.tex3.w = o.pos.w;\n");
            }

            //if(g_ActiveConfig.bEnablePixelLighting && ctx.bSupportsPixelLighting)
            //{
            if (UsableMaterialNode.Children.Count < 7)
            {
                w("o.Normal = float4(_norm0.x,_norm0.y,_norm0.z,pos.z);\n");
            }
            else
            {
                w("o.tex4.w = _norm0.x;\n");
                w("o.tex5.w = _norm0.y;\n");
                w("o.tex6.w = _norm0.z;\n");
                if (UsableMaterialNode.Children.Count < 8)
                {
                    w("o.tex7 = pos.xyzz;\n");
                }
                else
                {
                    w("o.tex7.w = pos.z;\n");
                }
            }
            if (_colorSet[0] != null)
            {
                w("o.colors_0 = color0;\n");
            }

            if (_colorSet[1] != null)
            {
                w("o.colors_1 = color1;\n");
            }
            //}

            //write the true depth value, if the game uses depth textures pixel shaders will override with the correct values
            //if not early z culling will improve speed

            // this results in a scale from -1..0 to -1..1 after perspective
            // divide
            //w("o.pos.z = o.pos.w + o.pos.z * 2.0f;\n");

            // Sonic Unleashed puts its final rendering at the near or
            // far plane of the viewing frustrum(actually box, they use
            // orthogonal projection for that), and we end up putting it
            // just beyond, and the rendering gets clipped away. (The
            // primitive gets dropped)
            //w("o.pos.z = o.pos.z * 1048575.0f/1048576.0f;\n");

            // the next steps of the OGL pipeline are:
            // (x_c,y_c,z_c,w_c) = o.pos  //switch to OGL spec terminology
            // clipping to -w_c <= (x_c,y_c,z_c) <= w_c
            // (x_d,y_d,z_d) = (x_c,y_c,z_c)/w_c//perspective divide
            // z_w = (f-n)/2*z_d + (n+f)/2
            // z_w now contains the value to go to the 0..1 depth buffer

            //trying to get the correct semantic while not using glDepthRange
            //seems to get rather complicated

            // Bit ugly here
            // Will look better when we bind uniforms in GLSL 1.3
            // clipPos/w needs to be done in pixel shader, not here

            if (UsableMaterialNode.Children.Count < 7)
            {
                for (uint i = 0; i < UsableMaterialNode.Children.Count; i++)
                {
                    w("gl_TexCoord[{0}].xyz = o.tex{0};\n", i);
                }
                w("gl_TexCoord[{0}] = o.clipPos;\n", UsableMaterialNode.Children.Count);
                //if(g_ActiveConfig.bEnablePixelLighting && ctx.bSupportsPixelLighting)
                w("gl_TexCoord[{0}] = o.Normal;\n", UsableMaterialNode.Children.Count + 1);
            }
            else
            {
                // clip position is in w of first 4 texcoords
                //if (g_ActiveConfig.bEnablePixelLighting && ctx.bSupportsPixelLighting)
                //{
                for (int i = 0; i < 8; i++)
                {
                    w("gl_TexCoord[{0}] = o.tex{0};\n", i);
                }
                //}
                //else
                //{
                //    for (unsigned int i = 0; i < xfregs.numTexGen.numTexGens; ++i)
                //        Write("  gl_TexCoord[%d]%s = o.tex%d;\n", i, i < 4 ? ".xyzw" : ".xyz" , i);
                //}
            }
            w("gl_FrontColor = o.colors_0;\n");
            w("gl_FrontSecondaryColor = o.colors_1;\n");
            w("gl_Position = o.pos;\n");
            w("}\n");

            return(tempShader);
        }
예제 #5
0
        public static unsafe void PMD2MDL0(MDL0Node model)
        {
            model._version = 9;
            model._isImport = true;
            Collada._importOptions = BrawlLib.Properties.Settings.Default.ColladaImportOptions;
            Collada._importOptions._forceCCW = true;
            Collada._importOptions._fltVerts = true;
            Collada._importOptions._fltNrms = true;
            Collada._importOptions._fltUVs = true;

            model.InitGroups();

            List<MDL0BoneNode> BoneCache = new List<MDL0BoneNode>();

            int index = 0;
            if (!String.IsNullOrWhiteSpace(_header._modelNameEnglish))
                model.Name = _header._modelNameEnglish;
            else
                model.Name = _header._modelName;

            if (!String.IsNullOrWhiteSpace(_header._commentEnglish))
                MessageBox.Show(_header._commentEnglish);
            else
                MessageBox.Show(_header._comment);

            ModelBone parent = null;
            foreach (ModelBone b in _bones)
            {
                MDL0BoneNode bone = new MDL0BoneNode();

                if (!String.IsNullOrWhiteSpace(b._boneNameEnglish))
                    bone._name = b._boneNameEnglish;
                else
                    bone._name = b._boneName;

                bone._entryIndex = index++;

                if (b._parentBoneIndex != ushort.MaxValue)
                {
                    parent = _bones[b._parentBoneIndex];
                    foreach (MDL0BoneNode v in model._boneGroup._children)
                        AssignParent(v, b, bone, parent);
                }
                else
                {
                    bone.Parent = model._boneGroup;
                    bone._bindState._scale = new Vector3(1.0f);
                    bone._bindState._translate = new Vector3(b._wPos[0], b._wPos[1], b._wPos[2]);
                    bone._bindState.CalcTransforms();
                    bone.RecalcBindState();
                }

                BoneCache.Add(bone);
            }

            MDL0ShaderNode texSpa = null, tex = null, colorSpa = null, color = null;

            index = 0;
            foreach (ModelMaterial m in _materials)
            {
                MDL0MaterialNode mn = new MDL0MaterialNode();
                mn.Name = "Material" + index++;

                MDL0MaterialRefNode texRef = null;
                MDL0MaterialRefNode spaRef = null;

                if (!String.IsNullOrEmpty(m._textureFileName))
                    if (m._textureFileName.Contains('*'))
                    {
                        string[] names = m._textureFileName.Split('*');
                        if (!String.IsNullOrEmpty(names[0]))
                        {
                            texRef = new MDL0MaterialRefNode();
                            texRef.Name = names[0].Substring(0, names[0].IndexOf('.'));
                        }
                        if (!String.IsNullOrEmpty(names[1]))
                        {
                            spaRef = new MDL0MaterialRefNode();
                            spaRef.Name = names[1].Substring(0, names[1].IndexOf('.'));
                            spaRef.MapMode = MDL0MaterialRefNode.MappingMethod.EnvCamera;
                            spaRef.UWrapMode = MDL0MaterialRefNode.WrapMode.Clamp;
                            spaRef.VWrapMode = MDL0MaterialRefNode.WrapMode.Clamp;
                            spaRef.Projection = Wii.Graphics.TexProjection.STQ;
                            spaRef.InputForm = Wii.Graphics.TexInputForm.ABC1;
                            spaRef.Coordinates = Wii.Graphics.TexSourceRow.Normals;
                            spaRef.Normalize = true;
                        }
                    }
                    else
                    {
                        texRef = new MDL0MaterialRefNode();
                        texRef.Name = m._textureFileName.Substring(0, m._textureFileName.IndexOf('.'));
                        texRef.Coordinates = Wii.Graphics.TexSourceRow.TexCoord0;
                    }

                if (texRef != null)
                {
                    (texRef._texture = model.FindOrCreateTexture(texRef.Name))._references.Add(texRef);
                    texRef._parent = mn;
                    mn._children.Add(texRef);
                }
                if (spaRef != null)
                {
                    (spaRef._texture = model.FindOrCreateTexture(spaRef.Name))._references.Add(spaRef);
                    spaRef._parent = mn;
                    mn._children.Add(spaRef);
                }

                mn._chan1._matColor = new RGBAPixel((byte)(m._diffuseColor[0] * 255), (byte)(m._diffuseColor[1] * 255), (byte)(m._diffuseColor[2] * 255), 255);
                mn._chan1.ColorMaterialSource = GXColorSrc.Register;

                if (texRef != null && spaRef != null)
                {
                    if (texSpa == null)
                    {
                        MDL0ShaderNode n = TexSpaShader;
                        n._parent = model._shadGroup;
                        model._shadList.Add(n);
                        texSpa = n;
                    }
                    mn.ShaderNode = texSpa;
                }
                else if (texRef != null)
                {
                    if (tex == null)
                    {
                        MDL0ShaderNode n = TexShader;
                        n._parent = model._shadGroup;
                        model._shadList.Add(n);
                        tex = n;
                    }
                    mn.ShaderNode = tex;
                }
                else if (spaRef != null)
                {
                    if (colorSpa == null)
                    {
                        MDL0ShaderNode n = ColorSpaShader;
                        n._parent = model._shadGroup;
                        model._shadList.Add(n);
                        colorSpa = n;
                    }
                    mn.ShaderNode = colorSpa;
                }
                else
                {
                    if (color == null)
                    {
                        MDL0ShaderNode n = ColorShader;
                        n._parent = model._shadGroup;
                        model._shadList.Add(n);
                        color = n;
                    }
                    mn.ShaderNode = color;
                }

                mn._parent = model._matGroup;
                model._matList.Add(mn);
            }

            model._numFaces = 0;
            model._numFacepoints = 0;

            int x = 0;
            int offset = 0;
            foreach (ModelMaterial m in _materials)
            {
                PrimitiveManager manager = new PrimitiveManager() { _pointCount = (int)m._faceVertCount };
                MDL0ObjectNode p = new MDL0ObjectNode() { _manager = manager, _opaMaterial = (MDL0MaterialNode)model._matList[x] };
                p._opaMaterial._objects.Add(p);
                p._manager._vertices = new List<Vertex3>();
                p.Name = "polygon" + x++;
                p._parent = model._objGroup;

                model._numFaces += p._numFaces = manager._faceCount = manager._pointCount / 3;
                model._numFacepoints += p._numFacepoints = manager._pointCount;

                p._manager._indices = new UnsafeBuffer((int)m._faceVertCount * 2);
                p._manager._faceData[0] = new UnsafeBuffer((int)m._faceVertCount * 12);
                p._manager._faceData[1] = new UnsafeBuffer((int)m._faceVertCount * 12);
                p._manager._faceData[4] = new UnsafeBuffer((int)m._faceVertCount * 8);

                p._manager._dirty[0] = true;
                p._manager._dirty[1] = true;
                p._manager._dirty[4] = true;

                ushort* Indices = (ushort*)p._manager._indices.Address;
                Vector3* Vertices = (Vector3*)p._manager._faceData[0].Address;
                Vector3* Normals = (Vector3*)p._manager._faceData[1].Address;
                Vector2* UVs = (Vector2*)p._manager._faceData[4].Address;

                manager._triangles = new NewPrimitive((int)m._faceVertCount, BeginMode.Triangles);
                uint[] pTriarr = manager._triangles._indices;
                uint pTri = 0;

                index = 0;
                List<int> usedVertices = new List<int>();
                List<int> vertexIndices = new List<int>();
                for (int s = offset, l = 0; l < (int)m._faceVertCount; l++, s++)
                {
                    ushort i = _faceIndices[s];
                    ModelVertex mv = _vertices[i];
                    ushort j = 0;
                    if (!usedVertices.Contains(i))
                    {
                        Influence inf;
                        BoneWeight weight1 = null, weight2 = null;

                        float weight = ((float)mv._boneWeight / 100.0f).Clamp(0.0f, 1.0f);

                        if (weight > 0.0f && weight < 1.0f)
                        {
                            weight1 = new BoneWeight(BoneCache[mv._boneIndex[0]], weight);
                            weight2 = new BoneWeight(BoneCache[mv._boneIndex[1]], 1.0f - weight);
                        }
                        else if (weight == 0.0f)
                            weight1 = new BoneWeight(BoneCache[mv._boneIndex[1]]);
                        else
                            weight1 = new BoneWeight(BoneCache[mv._boneIndex[0]]);

                        if (weight2 != null)
                            inf = new Influence(new List<BoneWeight> { weight1, weight2 });
                        else
                            inf = new Influence(new List<BoneWeight> { weight1 });

                        Vector3 t = new Vector3();
                        Vertex3 v;
                        t._x = mv._position[0];
                        t._y = mv._position[1];
                        t._z = mv._position[2];
                        if (inf._weights.Count > 1)
                        {
                            inf = model._influences.FindOrCreate(inf, true);
                            inf.CalcMatrix();
                            v = new Vertex3(t, inf);
                        }
                        else
                        {
                            MDL0BoneNode bone = inf._weights[0].Bone;
                            v = new Vertex3(t * bone._inverseBindMatrix, bone);
                        }

                        p._manager._vertices.Add(v);
                        vertexIndices.Add(usedVertices.Count);
                        usedVertices.Add(i);
                        j = (ushort)(usedVertices.Count - 1);
                    }
                    else
                        j = (ushort)vertexIndices[usedVertices.IndexOf(i)];

                    *Indices++ = j;
                    pTriarr[pTri++] = (uint)l;
                    *Vertices++ = p._manager._vertices[j]._position;
                    *Normals++ = mv._normal;
                    *UVs++ = mv._texCoord;
                }
                model._objList.Add(p);
                offset += (int)m._faceVertCount;
            }

            //Check each polygon to see if it can be rigged to a single influence
            if (model._objList != null && model._objList.Count != 0)
                foreach (MDL0ObjectNode p in model._objList)
                {
                    IMatrixNode node = null;
                    bool singlebind = true;

                    foreach (Vertex3 v in p._manager._vertices)
                        if (v._matrixNode != null)
                        {
                            if (node == null)
                                node = v._matrixNode;

                            if (v._matrixNode != node)
                            {
                                singlebind = false;
                                break;
                            }
                        }

                    if (singlebind && p._matrixNode == null)
                    {
                        //Increase reference count ahead of time for rebuild
                        if (p._manager._vertices[0]._matrixNode != null)
                            p._manager._vertices[0]._matrixNode.ReferenceCount++;

                        foreach (Vertex3 v in p._manager._vertices)
                            if (v._matrixNode != null)
                                v._matrixNode.ReferenceCount--;

                        p._nodeId = -2; //Continued on polygon rebuild
                    }
                }

            //foreach (MDL0ObjectNode p in model._objList)
            //    foreach (MDL0MaterialNode m in model._matList)
            //    {
            //        MDL0MaterialNode m2 = p.OpaMaterialNode;

            //        if (m2 == null || m2.ShaderNode != m.ShaderNode || m2.Children.Count != m.Children.Count)
            //            continue;

            //        for (int i = 0; i < m.Children.Count; i++)
            //            if (m2.Children[i].Name != m.Children[i].Name)
            //                continue;

            //        p.OpaMaterialNode = m;
            //        break;
            //    }
            //for (int i = 0; i < model._matList.Count; i++)
            //    if (((MDL0MaterialNode)model._matList[i])._objects.Count == 0)
            //        model._matList.RemoveAt(i--);

            model.CleanGroups();
            model.BuildFromScratch(null);
        }
예제 #6
0
        public void CheckMetals()
        {
            if (_autoMetal)
            {
                if (MessageBox.Show(null, "Are you sure you want to turn this on?\nAny existing metal materials will be modified.", "", MessageBoxButtons.YesNo) == DialogResult.Yes)
                {
                    if (_children == null) Populate();
                    for (int x = 0; x < _matList.Count; x++)
                    {
                        MDL0MaterialNode n = (MDL0MaterialNode)_matList[x];
                        if (!n.isMetal)
                        {
                            if (n.MetalMaterial == null)
                            {
                                MDL0MaterialNode node = new MDL0MaterialNode();
                                _matGroup.AddChild(node);
                                node._updating = true;
                                node.Name = n.Name + "_ExtMtl";
                                node._ssc = 4;
                                node.New = true;

                                for (int i = 0; i <= n.Children.Count; i++)
                                {
                                    MDL0MaterialRefNode mr = new MDL0MaterialRefNode();
                                    node.AddChild(mr);
                                    mr.Texture = "metal00";
                                    mr._index1 = mr._index2 = i;
                                    mr.SignalPropertyChange();
                                    if (i == n.Children.Count || ((MDL0MaterialRefNode)n.Children[i]).HasTextureMatrix)
                                    {
                                        mr._minFltr = 5;
                                        mr._magFltr = 1;
                                        mr._lodBias = -2;

                                        mr.HasTextureMatrix = true;
                                        node.Rebuild(true);

                                        mr._projection = (int)TexProjection.STQ;
                                        mr._inputForm = (int)TexInputForm.ABC1;
                                        mr._texGenType = (int)TexTexgenType.Regular;
                                        mr._sourceRow = (int)TexSourceRow.Normals;
                                        mr._embossSource = 4;
                                        mr._embossLight = 2;
                                        mr.Normalize = true;

                                        mr.MapMode = (MDL0MaterialRefNode.MappingMethod)1;

                                        mr.getTexMtxVal();

                                        break;
                                    }
                                }

                                node._chan1 = new LightChannel(63, new RGBAPixel(128, 128, 128, 255), new RGBAPixel(255, 255, 255, 255), 0, 0, node);
                                node.C1ColorEnabled = true;
                                node.C1ColorDiffuseFunction = GXDiffuseFn.Clamped;
                                node.C1ColorAttenuation = GXAttnFn.Spotlight;
                                node.C1AlphaEnabled = true;
                                node.C1AlphaDiffuseFunction = GXDiffuseFn.Clamped;
                                node.C1AlphaAttenuation = GXAttnFn.Spotlight;

                                node._chan2 = new LightChannel(63, new RGBAPixel(255, 255, 255, 255), new RGBAPixel(), 0, 0, node);
                                node.C2ColorEnabled = true;
                                node.C2ColorDiffuseFunction = GXDiffuseFn.Disabled;
                                node.C2ColorAttenuation = GXAttnFn.Specular;
                                node.C2AlphaDiffuseFunction = GXDiffuseFn.Disabled;
                                node.C2AlphaAttenuation = GXAttnFn.Specular;

                                node._lSet = n._lSet;
                                node._fSet = n._fSet;

                                node._cull = n._cull;
                                node._numLights = 2;
                                node.ZCompareLoc = false;
                                node._normMapRefLight1 =
                                node._normMapRefLight2 =
                                node._normMapRefLight3 =
                                node._normMapRefLight4 = -1;

                                node.SignalPropertyChange();
                            }
                        }
                    }
                    foreach (MDL0MaterialNode node in _matList)
                    {
                        if (!node.isMetal)
                            continue;

                        if (node.ShaderNode != null)
                        {
                            if (node.ShaderNode._autoMetal && node.ShaderNode.texCount == node.Children.Count)
                            {
                                node._updating = false;
                                continue;
                            }
                            else
                            {
                                if (node.ShaderNode._stages == 4)
                                {
                                    foreach (MDL0MaterialNode y in node.ShaderNode._materials)
                                        if (!y.isMetal || y.Children.Count != node.Children.Count)
                                            goto Next;
                                    node.ShaderNode.DefaultAsMetal(node.Children.Count);
                                    continue;
                                }
                            }
                        }
                    Next:
                        bool found = false;
                        foreach (MDL0ShaderNode s in _shadGroup.Children)
                        {
                            if (s._autoMetal && s.texCount == node.Children.Count)
                            {
                                node.ShaderNode = s;
                                found = true;
                            }
                            else
                            {
                                if (s._stages == 4)
                                {
                                    foreach (MDL0MaterialNode y in s._materials)
                                        if (!y.isMetal || y.Children.Count != node.Children.Count)
                                            goto NotFound;
                                    node.ShaderNode = s;
                                    found = true;
                                    goto End;
                                NotFound:
                                    continue;
                                }
                            }
                        }
                    End:
                        if (!found)
                        {
                            MDL0ShaderNode shader = new MDL0ShaderNode();
                            _shadGroup.AddChild(shader);
                            shader.DefaultAsMetal(node.Children.Count);
                            node.ShaderNode = shader;
                        }
                    }
                    foreach (MDL0MaterialNode m in _matList)
                        m._updating = false;
                }
                else
                    _autoMetal = false;
            }
        }
예제 #7
0
        internal unsafe void Prepare(GLContext ctx, MDL0MaterialRefNode mRef)
        {
            if (_context == null)
            {
                _context = ctx;
            }

            if (palette == null && mRef.PaletteNode != null)
            {
                palette = mRef.RootNode.FindChild("Palettes(NW4R)/" + mRef.Palette, true) as PLT0Node;
            }

            try
            {
                if (Texture != null)
                {
                    Texture.Bind(mRef.Index, (int)((MDL0MaterialNode)mRef.Parent).ShaderNode.programHandle);
                }
                else
                {
                    Load(mRef.Index, (int)((MDL0MaterialNode)mRef.Parent).ShaderNode.programHandle, palette);
                }
            }
            catch { }

            int filter = 0;

            switch (mRef.MagFilter)
            {
            case MDL0MaterialRefNode.TextureMagFilter.Nearest:
                filter = (int)GLTextureFilter.NEAREST; break;

            case MDL0MaterialRefNode.TextureMagFilter.Linear:
                filter = (int)GLTextureFilter.LINEAR; break;
            }
            _context.glTexParameter(GLTextureTarget.Texture2D, GLTextureParameter.MagFilter, filter);
            switch (mRef.MinFilter)
            {
            case MDL0MaterialRefNode.TextureMinFilter.Nearest:
                filter = (int)GLTextureFilter.NEAREST; break;

            case MDL0MaterialRefNode.TextureMinFilter.Linear:
                filter = (int)GLTextureFilter.LINEAR; break;

            case MDL0MaterialRefNode.TextureMinFilter.Nearest_Mipmap_Nearest:
                filter = (int)GLTextureFilter.NEAREST_MIPMAP_NEAREST; break;

            case MDL0MaterialRefNode.TextureMinFilter.Nearest_Mipmap_Linear:
                filter = (int)GLTextureFilter.NEAREST_MIPMAP_LINEAR; break;

            case MDL0MaterialRefNode.TextureMinFilter.Linear_Mipmap_Nearest:
                filter = (int)GLTextureFilter.LINEAR_MIPMAP_NEAREST; break;

            case MDL0MaterialRefNode.TextureMinFilter.Linear_Mipmap_Linear:
                filter = (int)GLTextureFilter.LINEAR_MIPMAP_LINEAR; break;
            }
            _context.glTexParameter(GLTextureTarget.Texture2D, GLTextureParameter.MinFilter, filter);
            _context.glTexParameter(GLTextureTarget.Texture2D, GLTextureParameter.LODBias, mRef.LODBias);

            //_context.glTexParameter(GLTextureTarget.Texture2D, GLTextureParameter.BaseLevel, 0);

            float *p = stackalloc float[4];

            p[0] = p[1] = p[2] = p[3] = 1.0f;
            if (Selected && !ObjOnly)
            {
                p[0] = -1.0f;
            }

            _context.glLight(GLLightTarget.Light0, GLLightParameter.SPECULAR, p);
            _context.glLight(GLLightTarget.Light0, GLLightParameter.DIFFUSE, p);
        }
        public void UpdateAsMetal()
        {
            if (!isMetal)
                return;

            _updating = true;
            if (ShaderNode != null && ShaderNode._autoMetal && ShaderNode.texCount == Children.Count)
            {
                //ShaderNode.DefaultAsMetal(Children.Count);
            }
            else
            {
                bool found = false;
                foreach (MDL0ShaderNode s in Model._shadGroup.Children)
                {
                    if (s._autoMetal && s.texCount == Children.Count)
                    {
                        ShaderNode = s;
                        found = true;
                    }
                    else
                    {
                        if (s._stages == 4)
                        {
                            foreach (MDL0MaterialNode y in s._materials)
                                if (!y.isMetal || y.Children.Count != Children.Count)
                                    goto NotFound;
                            ShaderNode = s;
                            found = true;
                            goto End;
                        NotFound:
                            continue;
                        }
                    }
                }
            End:
                if (!found)
                {
                    MDL0ShaderNode shader = new MDL0ShaderNode();
                    Model._shadGroup.AddChild(shader);
                    shader.DefaultAsMetal(Children.Count);
                    ShaderNode = shader;
                }
            }

            if (MetalMaterial != null)
            {
                Name = MetalMaterial.Name + "_ExtMtl";
                _ssc = 4;

                if (Children.Count - 1 != MetalMaterial.Children.Count)
                {
                    //Remove all children
                    for (int i = 0; i < Children.Count; i++)
                    {
                        ((MDL0MaterialRefNode)Children[i]).TextureNode = null;
                        ((MDL0MaterialRefNode)Children[i]).PaletteNode = null;
                        RemoveChild(Children[i--]);
                    }

                    //Start over
                    for (int i = 0; i <= MetalMaterial.Children.Count; i++)
                    {
                        MDL0MaterialRefNode mr = new MDL0MaterialRefNode();

                        AddChild(mr);
                        mr.Texture = "metal00";
                        mr._index1 = mr._index2 = i;

                        mr._texFlags.TexScale = new Vector2(1);
                        mr._bindState._scale = new Vector3(1);
                        mr._texMatrix.TexMtx = Matrix43.Identity;
                        mr._texMatrix.SCNCamera = -1;
                        mr._texMatrix.SCNLight = -1;
                        mr._texMatrix.Identity = 1;

                        if (i == MetalMaterial.Children.Count)
                        {
                            mr._minFltr = 5;
                            mr._magFltr = 1;
                            mr._lodBias = -2;
                            mr.HasTextureMatrix = true;
                            mr._projection = (int)TexProjection.STQ;
                            mr._inputForm = (int)TexInputForm.ABC1;
                            mr._sourceRow = (int)TexSourceRow.Normals;
                            mr.Normalize = true;
                            mr.MapMode = (MDL0MaterialRefNode.MappingMethod)1;
                        }
                        else
                        {
                            mr._projection = (int)TexProjection.ST;
                            mr._inputForm = (int)TexInputForm.AB11;
                            mr._sourceRow = (int)TexSourceRow.TexCoord0 + i;
                            mr.Normalize = false;
                            mr.MapMode = (MDL0MaterialRefNode.MappingMethod)0;
                        }

                        mr._texGenType = (int)TexTexgenType.Regular;
                        mr._embossSource = 4;
                        mr._embossLight = 2;

                        mr.getTexMtxVal();
                    }

                    _chan1 = new LightChannel(63, new RGBAPixel(128, 128, 128, 255), new RGBAPixel(255, 255, 255, 255), 0, 0, this);
                    C1ColorEnabled = true;
                    C1ColorDiffuseFunction = GXDiffuseFn.Clamped;
                    C1ColorAttenuation = GXAttnFn.Spotlight;
                    C1AlphaEnabled = true;
                    C1AlphaDiffuseFunction = GXDiffuseFn.Clamped;
                    C1AlphaAttenuation = GXAttnFn.Spotlight;

                    _chan2 = new LightChannel(63, new RGBAPixel(255, 255, 255, 255), new RGBAPixel(), 0, 0, this);
                    C2ColorEnabled = true;
                    C2ColorDiffuseFunction = GXDiffuseFn.Disabled;
                    C2ColorAttenuation = GXAttnFn.Specular;
                    C2AlphaDiffuseFunction = GXDiffuseFn.Disabled;
                    C2AlphaAttenuation = GXAttnFn.Specular;

                    _lSet = MetalMaterial._lSet;
                    _fSet = MetalMaterial._fSet;

                    _cull = MetalMaterial._cull;
                    _numLights = 2;
                    ZCompareLoc = false;
                    _normMapRefLight1 =
                    _normMapRefLight2 =
                    _normMapRefLight3 =
                    _normMapRefLight4 = -1;

                    SignalPropertyChange();
                }
            }
            _updating = false;
        }
예제 #9
0
        internal unsafe void Prepare(MDL0MaterialRefNode mRef, int shaderProgramHandle)
        {
            if (mRef.PaletteNode != null && palette == null)
            {
                palette = mRef.RootNode.FindChild("Palettes(NW4R)/" + mRef.Palette, true) as PLT0Node;
            }

            try
            {
                if (Texture != null)
                {
                    Texture.Bind(mRef.Index, shaderProgramHandle, _context);
                }
                else
                {
                    Load(mRef.Index, shaderProgramHandle, palette);
                }
            }
            catch { }

            int filter = 0;

            switch (mRef.MagFilter)
            {
            case MDL0MaterialRefNode.TextureMagFilter.Nearest:
                filter = (int)TextureMagFilter.Nearest; break;

            case MDL0MaterialRefNode.TextureMagFilter.Linear:
                filter = (int)TextureMagFilter.Linear; break;
            }
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, filter);
            switch (mRef.MinFilter)
            {
            case MDL0MaterialRefNode.TextureMinFilter.Nearest:
                filter = (int)TextureMinFilter.Nearest; break;

            case MDL0MaterialRefNode.TextureMinFilter.Linear:
                filter = (int)TextureMinFilter.Linear; break;

            case MDL0MaterialRefNode.TextureMinFilter.Nearest_Mipmap_Nearest:
                filter = (int)TextureMinFilter.NearestMipmapNearest; break;

            case MDL0MaterialRefNode.TextureMinFilter.Nearest_Mipmap_Linear:
                filter = (int)TextureMinFilter.NearestMipmapLinear; break;

            case MDL0MaterialRefNode.TextureMinFilter.Linear_Mipmap_Nearest:
                filter = (int)TextureMinFilter.LinearMipmapNearest; break;

            case MDL0MaterialRefNode.TextureMinFilter.Linear_Mipmap_Linear:
                filter = (int)TextureMinFilter.LinearMipmapLinear; break;
            }
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, filter);
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureLodBias, mRef.LODBias);

            switch ((int)mRef.UWrapMode)
            {
            case 0: GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.ClampToEdge); break;

            case 1: GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.Repeat); break;

            case 2: GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.MirroredRepeat); break;
            }

            switch ((int)mRef.VWrapMode)
            {
            case 0: GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.ClampToEdge); break;

            case 1: GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.Repeat); break;

            case 2: GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.MirroredRepeat); break;
            }

            float *p = stackalloc float[4];

            p[0] = p[1] = p[2] = p[3] = 1.0f;
            if (Selected && !ObjOnly)
            {
                p[0] = -1.0f;
            }

            GL.Light(LightName.Light0, LightParameter.Specular, p);
            GL.Light(LightName.Light0, LightParameter.Diffuse, p);
        }
        public MDL0Node ImportModel(string filePath)
        {
            MDL0Node model = new MDL0Node() { _name = Path.GetFileNameWithoutExtension(filePath) };
            model.InitGroups();
            if (_importOptions._setOrigPath)
                model._originalPath = filePath;

            //Parse the collada file and use the data to create an MDL0
            using (DecoderShell shell = DecoderShell.Import(filePath))
            try
            {
                model._version = _importOptions._modelVersion;

                Error = "There was a problem reading the model.";

                //Extract images, removing duplicates
                foreach (ImageEntry img in shell._images)
                {
                    string name;
                    MDL0TextureNode tex;

                    if (img._path != null)
                        name = Path.GetFileNameWithoutExtension(img._path);
                    else
                        name = img._name != null ? img._name : img._id;

                    tex = model.FindOrCreateTexture(name);
                    img._node = tex;
                }

                //Extract materials and create shaders
                int tempNo = -1;
                foreach (MaterialEntry mat in shell._materials)
                {
                    tempNo += 1;
                    MDL0MaterialNode matNode = new MDL0MaterialNode();

                    matNode._parent = model._matGroup;
                    matNode._name = mat._name != null ? mat._name : mat._id;

                    if (tempNo == 0)
                    {
                        MDL0ShaderNode shadNode = new MDL0ShaderNode();
                        shadNode._parent = model._shadGroup;
                        shadNode._name = "Shader" + tempNo;
                        model._shadList.Add(shadNode);
                    }
                    matNode.Shader = "Shader0";
                    matNode.ShaderNode = (MDL0ShaderNode)model._shadGroup.Children[0];

                    mat._node = matNode;
                    matNode._cull = _importOptions._culling;

                    //Find effect
                    if (mat._effect != null)
                        foreach (EffectEntry eff in shell._effects)
                            if (eff._id == mat._effect) //Attach textures and effects to material
                                if (eff._shader != null)
                                    foreach (LightEffectEntry l in eff._shader._effects)
                                        if (l._type == LightEffectType.diffuse && l._texture != null)
                                        {
                                            string path = l._texture;
                                            foreach (EffectNewParam p in eff._newParams)
                                                if (p._sid == l._texture)
                                                {
                                                    path = p._sampler2D._url;
                                                    if (!String.IsNullOrEmpty(p._sampler2D._source))
                                                    {
                                                        foreach (EffectNewParam p2 in eff._newParams)
                                                            if (p2._sid == p._sampler2D._source)
                                                                path = p2._path;
                                                    }
                                                }

                                            foreach (ImageEntry img in shell._images)
                                                if (img._id == path)
                                                {
                                                    MDL0MaterialRefNode mr = new MDL0MaterialRefNode();
                                                    (mr._texture = img._node as MDL0TextureNode)._references.Add(mr);
                                                    mr._name = mr._texture.Name;
                                                    matNode._children.Add(mr);
                                                    mr._parent = matNode;
                                                    mr._minFltr = mr._magFltr = 1;
                                                    mr._index1 = mr._index2 = mr.Index;
                                                    mr._uWrap = mr._vWrap = (int)_importOptions._wrap;
                                                    break;
                                                }
                                        }

                    matNode._numTextures = (byte)matNode.Children.Count;
                    model._matList.Add(matNode);
                }

                Say("Extracting scenes...");

                //Extract scenes
                foreach (SceneEntry scene in shell._scenes)
                {
                    //Parse joints first
                    NodeEntry[] joints = scene._nodes.Where(x => x._type == NodeType.JOINT).ToArray();
                    NodeEntry[] nodes = scene._nodes.Where(x => x._type != NodeType.JOINT).ToArray();
                    foreach (NodeEntry node in joints)
                        EnumNode(node, model._boneGroup, scene, model, shell);
                    foreach (NodeEntry node in nodes)
                        EnumNode(node, model._boneGroup, scene, model, shell);
                }

                //If there are no bones, rig all objects to a single bind.
                if (model._boneGroup._children.Count == 0)
                {
                    for (int i = 0; i < 2; i++)
                    {
                        MDL0BoneNode bone = new MDL0BoneNode();
                        bone.Scale = new Vector3(1);

                        bone._bindMatrix =
                        bone._inverseBindMatrix =
                        Matrix.Identity;

                        switch (i)
                        {
                            case 0:
                                bone._name = "TopN";
                                model._boneGroup._children.Add(bone);
                                bone._parent = model._boneGroup;
                                break;
                            case 1:
                                bone._name = "TransN";
                                model._boneGroup._children[0]._children.Add(bone);
                                bone._parent = model._boneGroup._children[0];
                                bone.ReferenceCount = model._objList.Count;
                                break;
                        }
                    }
                    if (model._objList != null && model._objList.Count != 0)
                        foreach (MDL0ObjectNode poly in model._objList)
                        {
                            poly._nodeId = 0;
                            poly.MatrixNode = (MDL0BoneNode)model._boneGroup._children[0]._children[0];
                        }
                }
                else
                {
                    //Check each polygon to see if it can be rigged to a single influence
                    if (model._objList != null && model._objList.Count != 0)
                        foreach (MDL0ObjectNode p in model._objList)
                        {
                            IMatrixNode node = null;
                            bool singlebind = true;

                            foreach (Vertex3 v in p._manager._vertices)
                                if (v._matrixNode != null)
                                {
                                    if (node == null)
                                        node = v._matrixNode;

                                    if (v._matrixNode != node)
                                    {
                                        singlebind = false;
                                        break;
                                    }
                                }

                            if (singlebind && p._matrixNode == null)
                            {
                                //Increase reference count ahead of time for rebuild
                                if (p._manager._vertices[0]._matrixNode != null)
                                    p._manager._vertices[0]._matrixNode.ReferenceCount++;

                                foreach (Vertex3 v in p._manager._vertices)
                                    if (v._matrixNode != null)
                                        v._matrixNode.ReferenceCount--;

                                p._nodeId = -2; //Continued on polygon rebuild
                            }
                        }
                }

                //Remove original color buffers if option set
                if (_importOptions._ignoreColors)
                {
                    if (model._objList != null && model._objList.Count != 0)
                        foreach (MDL0ObjectNode p in model._objList)
                            for (int x = 2; x < 4; x++)
                                if (p._manager._faceData[x] != null)
                                {
                                    p._manager._faceData[x].Dispose();
                                    p._manager._faceData[x] = null;
                                }
                }

                //Add color buffers if option set
                if (_importOptions._addClrs)
                {
                    RGBAPixel pixel = _importOptions._dfltClr;

                    //Add a color buffer to objects that don't have one
                    if (model._objList != null && model._objList.Count != 0)
                        foreach (MDL0ObjectNode p in model._objList)
                            if (p._manager._faceData[2] == null)
                            {
                                RGBAPixel* pIn = (RGBAPixel*)(p._manager._faceData[2] = new UnsafeBuffer(4 * p._manager._pointCount)).Address;
                                for (int i = 0; i < p._manager._pointCount; i++)
                                    *pIn++ = pixel;
                            }
                }

                //Apply defaults to materials
                if (model._matList != null)
                    foreach (MDL0MaterialNode p in model._matList)
                    {
                        if (_importOptions._mdlType == 0)
                        {
                            p._lSet = 20;
                            p._fSet = 4;
                            p._ssc = 3;

                            p.C1ColorEnabled = true;
                            p.C1AlphaMaterialSource = GXColorSrc.Vertex;
                            p.C1ColorMaterialSource = GXColorSrc.Vertex;
                            p.C1ColorDiffuseFunction = GXDiffuseFn.Clamped;
                            p.C1ColorAttenuation = GXAttnFn.Spotlight;
                            p.C1AlphaEnabled = true;
                            p.C1AlphaDiffuseFunction = GXDiffuseFn.Clamped;
                            p.C1AlphaAttenuation = GXAttnFn.Spotlight;

                            p.C2ColorDiffuseFunction = GXDiffuseFn.Disabled;
                            p.C2ColorAttenuation = GXAttnFn.None;
                            p.C2AlphaDiffuseFunction = GXDiffuseFn.Disabled;
                            p.C2AlphaAttenuation = GXAttnFn.None;
                        }
                        else
                        {
                            p._lSet = 0;
                            p._fSet = 0;
                            p._ssc = 1;

                            p._chan1.Color = new LightChannelControl(1795);
                            p._chan1.Alpha = new LightChannelControl(1795);
                            p._chan2.Color = new LightChannelControl(1795);
                            p._chan2.Alpha = new LightChannelControl(1795);
                        }
                    }

                //Set materials to use register color if option set
                if (_importOptions._useReg && model._objList != null)
                    foreach (MDL0ObjectNode p in model._objList)
                    {
                        MDL0MaterialNode m = p.OpaMaterialNode;
                        if (m != null && p._manager._faceData[2] == null && p._manager._faceData[3] == null)
                        {
                            m.C1MaterialColor = _importOptions._dfltClr;
                            m.C1ColorMaterialSource = GXColorSrc.Register;
                            m.C1AlphaMaterialSource = GXColorSrc.Register;
                        }
                    }

                //Remap materials if option set
                if (_importOptions._rmpMats && model._matList != null && model._objList != null)
                {
                    foreach (MDL0ObjectNode p in model._objList)
                        foreach (MDL0MaterialNode m in model._matList)
                            if (m.Children.Count > 0 &&
                                m.Children[0] != null &&
                                p.OpaMaterialNode != null &&
                                p.OpaMaterialNode.Children.Count > 0 &&
                                p.OpaMaterialNode.Children[0] != null &&
                                m.Children[0].Name == p.OpaMaterialNode.Children[0].Name &&
                                m.C1ColorMaterialSource == p.OpaMaterialNode.C1ColorMaterialSource)
                            {
                                p.OpaMaterialNode = m;
                                break;
                            }

                    //Remove unused materials
                    for (int i = 0; i < model._matList.Count; i++)
                        if (((MDL0MaterialNode)model._matList[i])._objects.Count == 0)
                            model._matList.RemoveAt(i--);
                }

                Error = "There was a problem writing the model.";

                //Clean the model and then build it!
                if (model != null)
                {
                    model.CleanGroups();
                    model.BuildFromScratch(this);
                }
            }
            catch (Exception x)
            {
                MessageBox.Show("Cannot continue importing this model.\n" + Error + "\n\nException:\n" + x.ToString());
                model = null;
                Close();
            }
            finally
            {
                //Clean up the mess we've made
                GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);
            }
            return model;
        }
        internal unsafe void Prepare(MDL0MaterialRefNode mRef, int shaderProgramHandle)
        {
            if (mRef.PaletteNode != null && palette == null)
                palette = mRef.RootNode.FindChild("Palettes(NW4R)/" + mRef.Palette, true) as PLT0Node;

            try
            {
                if (Texture != null)
                    Texture.Bind(mRef.Index, shaderProgramHandle, _context);
                else
                    Load(mRef.Index, shaderProgramHandle, palette);
            }
            catch { }

            int filter = 0;
            switch (mRef.MagFilter)
            {
                case MDL0MaterialRefNode.TextureMagFilter.Nearest:
                    filter = (int)TextureMagFilter.Nearest; break;
                case MDL0MaterialRefNode.TextureMagFilter.Linear:
                    filter = (int)TextureMagFilter.Linear; break;
            }
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, filter);
            switch (mRef.MinFilter)
            {
                case MDL0MaterialRefNode.TextureMinFilter.Nearest:
                    filter = (int)TextureMinFilter.Nearest; break;
                case MDL0MaterialRefNode.TextureMinFilter.Linear:
                    filter = (int)TextureMinFilter.Linear; break;
                case MDL0MaterialRefNode.TextureMinFilter.Nearest_Mipmap_Nearest:
                    filter = (int)TextureMinFilter.NearestMipmapNearest; break;
                case MDL0MaterialRefNode.TextureMinFilter.Nearest_Mipmap_Linear:
                    filter = (int)TextureMinFilter.NearestMipmapLinear; break;
                case MDL0MaterialRefNode.TextureMinFilter.Linear_Mipmap_Nearest:
                    filter = (int)TextureMinFilter.LinearMipmapNearest; break;
                case MDL0MaterialRefNode.TextureMinFilter.Linear_Mipmap_Linear:
                    filter = (int)TextureMinFilter.LinearMipmapLinear; break;
            }
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, filter);
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureLodBias, mRef.LODBias);

            switch ((int)mRef.UWrapMode)
            {
                case 0: GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.ClampToEdge); break;
                case 1: GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.Repeat); break;
                case 2: GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.MirroredRepeat); break;
            }

            switch ((int)mRef.VWrapMode)
            {
                case 0: GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.ClampToEdge); break;
                case 1: GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.Repeat); break;
                case 2: GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.MirroredRepeat); break;
            }

            float* p = stackalloc float[4];
            p[0] = p[1] = p[2] = p[3] = 1.0f;
            if (Selected && !ObjOnly)
                p[0] = -1.0f;

            GL.Light(LightName.Light0, LightParameter.Specular, p);
            GL.Light(LightName.Light0, LightParameter.Diffuse, p);
        }
        internal void ApplyTexture(MDL0MaterialRefNode texgen)
        {
            if (texgen != null)
            {
                int texId = texgen.TextureCoordId;
                texId = texId < 0 ? 0 : texId;
                if ((texId >= 0) && (_faceData[texId += 4] != null))
                {
                    byte* pData = (byte*)_graphicsBuffer.Address;
                    //int pData = 0;
                    for (int i = 0; i < texId; i++)
                        if (_faceData[i] != null)
                            if (i < 2)
                                pData += 12;
                            else if (i < 4)
                                pData += 4;
                            else
                                pData += 8;

                    GL.Enable(EnableCap.Texture2D);
                    GL.EnableClientState(ArrayCap.TextureCoordArray);
                    GL.TexCoordPointer(2, TexCoordPointerType.Float, _stride, (IntPtr)pData);
                    //GL.EnableVertexAttribArray(texId);
                    //GL.VertexAttribPointer(texId, 2, VertexAttribPointerType.Float, true, _stride, pData);
                    //GL.BindAttribLocation(_polygon.shaderProgramHandle, texId - 4, "tex" + (texId - 4));
                }
                else
                {
                    if (texId < 0)
                    {
                        switch (texId)
                        {
                            case -1: //Vertex coords
                            case -2: //Normal coords
                            case -3: //Color coords
                            case -4: //Binormal B coords
                            case -5: //Binormal T coords
                            default:
                                GL.DisableClientState(ArrayCap.TextureCoordArray);
                                GL.Disable(EnableCap.Texture2D);
                                break;
                        }
                    }
                    else
                    {
                        GL.DisableClientState(ArrayCap.TextureCoordArray);
                        GL.Disable(EnableCap.Texture2D);
                    }
                }
            }
            else
            {
                GL.DisableClientState(ArrayCap.TextureCoordArray);
                GL.Disable(EnableCap.Texture2D);
            }
        }
예제 #13
0
        private void lstTextures_SelectedValueChanged(object sender, EventArgs e)
        {
            if (_selectedTexture != null)
                _selectedTexture.Selected = false;

            if ((_selectedTexture = lstTextures.SelectedItem as MDL0TextureNode) != null)
            {
                _selectedTexture.Selected = true;

                overObjPnl.Invalidate();
                overTexPnl.Invalidate();

                if (_mainWindow.syncTexObjToolStripMenuItem.Checked)
                    _selectedTexture.ObjOnly = true;

                TargetTexRef = _selectedPolygon != null ? _selectedPolygon.UsableMaterialNode.FindChild(_selectedTexture.Name, true) as MDL0MaterialRefNode : null;
            }
            if (!_updating) _mainWindow.ModelPanel.Invalidate();
        }
예제 #14
0
 private void lstPolygons_SelectedValueChanged(object sender, EventArgs e)
 {
     _targetObject = _selectedPolygon = lstObjects.SelectedItem as MDL0ObjectNode;
     TargetTexRef = _selectedPolygon != null && _selectedTexture != null ? _selectedPolygon.UsableMaterialNode.FindChild(_selectedTexture.Name, true) as MDL0MaterialRefNode : null;
     _mainWindow.SelectedPolygonChanged(this, null);
     overObjPnl.Invalidate();
     overTexPnl.Invalidate();
 }