/// <summary> /// /// </summary> /// <param name="mobj"></param> private void BindMOBJ(Shader shader, HSD_MOBJ mobj, out float wscale, out float hscale, out bool mirrorX, out bool mirrorY) { GL.Enable(EnableCap.Texture2D); GL.Enable(EnableCap.Blend); GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha); GL.Enable(EnableCap.AlphaTest); GL.AlphaFunc(AlphaFunction.Greater, 0f); wscale = 1; hscale = 1; mirrorX = false; mirrorY = false; if (mobj == null) return; var pp = mobj.PEDesc; if (pp != null) { GL.BlendFunc(GXTranslator.toBlendingFactor(pp.SrcFactor), GXTranslator.toBlendingFactor(pp.DstFactor)); GL.DepthFunc(GXTranslator.toDepthFunction(pp.DepthFunction)); GL.AlphaFunc(GXTranslator.toAlphaFunction(pp.AlphaComp0), pp.AlphaRef0 / 255f); //GL.AlphaFunc(GXTranslator.toAlphaFunction(pp.AlphaComp1), pp.AlphaRef1 / 255f); } var color = mobj.Material; if (color != null) { shader.SetVector4("ambientColor", color.AMB_R / 255f, color.AMB_G / 255f, color.AMB_B / 255f, color.AMB_A / 255f); shader.SetVector4("diffuseColor", color.DIF_R / 255f, color.DIF_G / 255f, color.DIF_B / 255f, color.DIF_A / 255f); shader.SetVector4("specularColor", color.SPC_R / 255f, color.SPC_G / 255f, color.SPC_B / 255f, color.SPC_A / 255f); shader.SetFloat("shinniness", color.Shininess); shader.SetFloat("alpha", color.Alpha); } shader.SetBoolToInt("enableTEX0", mobj.RenderFlags.HasFlag(RENDER_MODE.TEX0)); shader.SetBoolToInt("enableSpecular", mobj.RenderFlags.HasFlag(RENDER_MODE.SPECULAR)); shader.SetBoolToInt("enableDiffuse", mobj.RenderFlags.HasFlag(RENDER_MODE.DIFFUSE)); shader.SetBoolToInt("enableMaterial", mobj.RenderFlags.HasFlag(RENDER_MODE.DIFFSE_MAT)); shader.SetBoolToInt("useVertexColor", mobj.RenderFlags.HasFlag(RENDER_MODE.DIFFSE_VTX)); shader.SetInt("enableTexDiffuse", 0); shader.SetInt("texDiffuse", 0); shader.SetInt("difColorType", 0); shader.SetInt("difAlphaType", 0); shader.SetInt("diffuseCoordType", 0); shader.SetVector2("diffuseUVScale", 1, 1); // Bind Textures if (mobj.Textures != null) { foreach (var tex in mobj.Textures.List) { if (tex.ImageData == null) continue; if (!imageBufferTextureIndex.ContainsKey(tex.ImageData.ImageData)) { imageBufferTextureIndex.Add(tex.ImageData.ImageData, TextureManager.TextureCount); TextureManager.Add(tex.GetDecodedImageData(), tex.ImageData.Width, tex.ImageData.Height); } var texid = TextureManager.Get(imageBufferTextureIndex[tex.ImageData.ImageData]); GL.ActiveTexture(TextureUnit.Texture0); GL.BindTexture(TextureTarget.Texture2D, texid); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)GXTranslator.toWrapMode(tex.WrapS)); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)GXTranslator.toWrapMode(tex.WrapT)); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)GXTranslator.toMagFilter(tex.MagFilter)); wscale = tex.WScale; hscale = tex.HScale; mirrorX = tex.WrapS == GXWrapMode.MIRROR; mirrorY = tex.WrapT == GXWrapMode.MIRROR; int coordType = 0; if (tex.Flags.HasFlag(TOBJ_FLAGS.COORD_REFLECTION)) coordType = 1; shader.SetInt("enableTexDiffuse", 1); shader.SetInt("diffuseTex", 0); shader.SetInt("difColorType", 0); shader.SetInt("difAlphaType", 0); shader.SetInt("diffuseCoordType", coordType); shader.SetVector2("diffuseUVScale", wscale, hscale); break; } } }
/// <summary> /// Prepares DOBJ for rendering by loading relevant information into a cache /// </summary> private void LoadDOBJ(HSD_DOBJ dobj, JOBJManager jobjManager) { if(DOBJtoBuffer.ContainsKey(dobj)) { GL.DeleteBuffer(DOBJtoBuffer[dobj]); DOBJtoBuffer.Remove(dobj); } List<CachedPOBJ> pobjs = new List<CachedPOBJ>(); List<GX_Vertex> vertices = new List<GX_Vertex>(); int off = 0; foreach(var pobj in dobj.Pobj.List) { var dl = pobj.ToDisplayList(); vertices.AddRange(dl.Vertices); var pobjCache = new CachedPOBJ(); // build envelopes int eni = 0; foreach(var v in dl.Envelopes) { Vector4 b = new Vector4(); Vector4 w = new Vector4(); for(int i = 0; i < v.EnvelopeCount; i++) { if (i >= 4) break; w[i] = v.GetWeightAt(i); b[i] = jobjManager.IndexOf(v.GetJOBJAt(i)); } pobjCache.Weights[eni] = w; pobjCache.Envelopes[eni] = b; eni++; pobjCache.HasWeighting = v.EnvelopeCount > 0; } // load display list foreach (var v in dl.Primitives) { pobjCache.DisplayLists.Add(new CachedDL() { Offset = off, Count = v.Count, PrimType = GXTranslator.toPrimitiveType(v.PrimitiveType) }); off += v.Count; } pobjs.Add(pobjCache); } var arr = vertices.ToArray(); int buf; GL.GenBuffers(1, out buf); GL.BindBuffer(BufferTarget.ArrayBuffer, buf); GL.BufferData(BufferTarget.ArrayBuffer, arr.Length * GX_Vertex.Stride, arr, BufferUsageHint.StaticDraw); DOBJtoBuffer.Add(dobj, buf); DOBJtoPOBJCache.Add(dobj, pobjs); }