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]; } }
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); } }
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); }
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); }
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; } }
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; }
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); } }
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(); }
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(); }