public virtual bool GottaRender(RenderInfo info) { return(false); }
public virtual void Render(RenderInfo info) { }
public override void Render(RenderInfo info) { BlendingFactorSrc[] blendsrc = { BlendingFactorSrc.Zero, BlendingFactorSrc.One, BlendingFactorSrc.One, BlendingFactorSrc.Zero, // um... BlendingFactorSrc.SrcAlpha, BlendingFactorSrc.OneMinusSrcAlpha, BlendingFactorSrc.DstAlpha, BlendingFactorSrc.OneMinusDstAlpha, BlendingFactorSrc.DstColor, BlendingFactorSrc.OneMinusDstColor }; BlendingFactorDest[] blenddst = { BlendingFactorDest.Zero, BlendingFactorDest.One, BlendingFactorDest.SrcColor, BlendingFactorDest.OneMinusSrcColor, BlendingFactorDest.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha, BlendingFactorDest.DstAlpha, BlendingFactorDest.OneMinusDstAlpha, BlendingFactorDest.DstColor, BlendingFactorDest.OneMinusDstColor }; LogicOp[] logicop = { LogicOp.Clear, LogicOp.And, LogicOp.AndReverse, LogicOp.Copy, LogicOp.AndInverted, LogicOp.Noop, LogicOp.Xor, LogicOp.Or, LogicOp.Nor, LogicOp.Equiv, LogicOp.Invert, LogicOp.OrReverse, LogicOp.CopyInverted, LogicOp.OrInverted, LogicOp.Nand, LogicOp.Set }; Matrix4[] lastmatrixtable = null; //GL.MatrixMode(MatrixMode.Projection); //GL.LoadIdentity(); //GL.Ortho(-1.0, 1.0, -1.0, 1.0, -10.5, 10.5); Console.WriteLine("Simple rendering: {0}", m_simpleRendering); foreach (Bmd.SceneGraphNode node in m_Model.SceneGraph) { if (node.NodeType != 0) continue; int shape = node.NodeID; if (node.MaterialID != 0xFFFF) { CullFaceMode[] cullmodes = { CullFaceMode.Front, CullFaceMode.Back, CullFaceMode.Front }; DepthFunction[] depthfuncs = { DepthFunction.Never, DepthFunction.Less, DepthFunction.Equal, DepthFunction.Lequal, DepthFunction.Greater, DepthFunction.Notequal, DepthFunction.Gequal, DepthFunction.Always }; Bmd.Material mat = m_Model.Materials[node.MaterialID]; if ((mat.DrawFlag == 4) ^ (info.Mode == RenderMode.Translucent)) continue; if (m_HasShaders) { // shader: handles multitexturing, color combination, alpha test GL.UseProgram(m_Shaders[node.MaterialID].Program); // do multitexturing int max_i = 8; if (m_simpleRendering) { max_i = 1; } for (int i = 0; i < max_i; i++) { if (mat.TexStages[i] == 0xFFFF) { GL.Disable(EnableCap.Texture2D); continue; } GL.ActiveTexture(TextureUnit.Texture0 + i); int loc = GL.GetUniformLocation(m_Shaders[node.MaterialID].Program, "texture" + i.ToString()); GL.Uniform1(loc, i); int texid = m_Textures[mat.TexStages[i]]; GL.Enable(EnableCap.Texture2D); GL.BindTexture(TextureTarget.Texture2D, texid); } } else { AlphaFunction[] alphafunc = { AlphaFunction.Never, AlphaFunction.Less, AlphaFunction.Equal, AlphaFunction.Lequal, AlphaFunction.Greater, AlphaFunction.Notequal, AlphaFunction.Gequal, AlphaFunction.Always }; // texturing -- texture 0 will be used if (mat.TexStages[0] != 0xFFFF) { int texid = m_Textures[mat.TexStages[0]]; GL.Enable(EnableCap.Texture2D); GL.BindTexture(TextureTarget.Texture2D, texid); } else GL.Disable(EnableCap.Texture2D); // alpha test -- only one comparison can be done if (mat.AlphaComp.MergeFunc == 1 && (mat.AlphaComp.Func0 == 7 || mat.AlphaComp.Func1 == 7)) GL.Disable(EnableCap.AlphaTest); else if (mat.AlphaComp.MergeFunc == 0 && (mat.AlphaComp.Func0 == 0 || mat.AlphaComp.Func1 == 0)) { GL.Enable(EnableCap.AlphaTest); GL.AlphaFunc(AlphaFunction.Never, 0f); } else { GL.Enable(EnableCap.AlphaTest); if ((mat.AlphaComp.MergeFunc == 1 && mat.AlphaComp.Func0 == 0) || (mat.AlphaComp.MergeFunc == 0 && mat.AlphaComp.Func0 == 7)) GL.AlphaFunc(alphafunc[mat.AlphaComp.Func1], (float)mat.AlphaComp.Ref1 / 255f); else GL.AlphaFunc(alphafunc[mat.AlphaComp.Func0], (float)mat.AlphaComp.Ref0 / 255f); } } switch (mat.BlendMode.BlendMode) { case 0: GL.Disable(EnableCap.Blend); GL.Disable(EnableCap.ColorLogicOp); break; case 1: case 3: GL.Enable(EnableCap.Blend); GL.Disable(EnableCap.ColorLogicOp); if (mat.BlendMode.BlendMode == 3) GL.BlendEquation(BlendEquationMode.FuncSubtract); else GL.BlendEquation(BlendEquationMode.FuncAdd); GL.BlendFunc(blendsrc[mat.BlendMode.SrcFactor], blenddst[mat.BlendMode.DstFactor]); break; case 2: GL.Disable(EnableCap.Blend); GL.Enable(EnableCap.ColorLogicOp); GL.LogicOp(logicop[mat.BlendMode.BlendOp]); break; } if (mat.CullMode == 0) GL.Disable(EnableCap.CullFace); else { GL.Enable(EnableCap.CullFace); GL.CullFace(cullmodes[mat.CullMode - 1]); } if (mat.ZMode.EnableZTest) { GL.Enable(EnableCap.DepthTest); GL.DepthFunc(depthfuncs[mat.ZMode.Func]); } else GL.Disable(EnableCap.DepthTest); GL.DepthMask(mat.ZMode.EnableZWrite); } else { //if (info.Mode != RenderMode.Opaque) continue; // if (m_HasShaders) GL.UseProgram(0); throw new Exception("Material-less geometry node " + node.NodeID.ToString()); } Bmd.Batch batch = m_Model.Batches[shape]; /*if (batch.MatrixType == 1) { GL.PushMatrix(); GL.CallList(info.BillboardDL); } else if (batch.MatrixType == 2) { GL.PushMatrix(); GL.CallList(info.YBillboardDL); }*/ foreach (Bmd.Batch.Packet packet in batch.Packets) { Matrix4[] mtxtable = new Matrix4[packet.MatrixTable.Length]; int[] mtx_debug = new int[packet.MatrixTable.Length]; for (int i = 0; i < packet.MatrixTable.Length; i++) { if (packet.MatrixTable[i] == 0xFFFF) { mtxtable[i] = lastmatrixtable[i]; mtx_debug[i] = 2; } else { Bmd.MatrixType mtxtype = m_Model.MatrixTypes[packet.MatrixTable[i]]; if (mtxtype.IsWeighted) { //throw new NotImplementedException("weighted matrix"); // code inspired from bmdview2, except doesn't work right /*Matrix4 mtx = new Matrix4(); Bmd.MultiMatrix mm = m_Model.MultiMatrices[mtxtype.Index]; for (int j = 0; j < mm.NumMatrices; j++) { Matrix4 wmtx = mm.Matrices[j]; float weight = mm.MatrixWeights[j]; Matrix4.Mult(ref wmtx, ref m_Model.Joints[mm.MatrixIndices[j]].Matrix, out wmtx); Vector4.Mult(ref wmtx.Row0, weight, out wmtx.Row0); Vector4.Mult(ref wmtx.Row1, weight, out wmtx.Row1); Vector4.Mult(ref wmtx.Row2, weight, out wmtx.Row2); //Vector4.Mult(ref wmtx.Row3, weight, out wmtx.Row3); Vector4.Add(ref mtx.Row0, ref wmtx.Row0, out mtx.Row0); Vector4.Add(ref mtx.Row1, ref wmtx.Row1, out mtx.Row1); Vector4.Add(ref mtx.Row2, ref wmtx.Row2, out mtx.Row2); //Vector4.Add(ref mtx.Row3, ref wmtx.Row3, out mtx.Row3); } mtx.M44 = 1f; mtxtable[i] = mtx;*/ // seems fine in most cases // but hey, certainly not right, that data has to be used in some way mtxtable[i] = Matrix4.Identity; mtx_debug[i] = 1; } else { mtxtable[i] = m_Model.Joints[mtxtype.Index].FinalMatrix; mtx_debug[i] = 0; } } } lastmatrixtable = mtxtable; foreach (Bmd.Batch.Packet.Primitive prim in packet.Primitives) { PrimitiveType[] primtypes = { PrimitiveType.Quads, PrimitiveType.Points, PrimitiveType.Triangles, PrimitiveType.TriangleStrip, PrimitiveType.TriangleFan, PrimitiveType.Lines, PrimitiveType.LineStrip, PrimitiveType.Points }; GL.Begin(primtypes[(prim.PrimitiveType - 0x80) / 8]); //GL.Begin(BeginMode.Points); for (int i = 0; i < prim.NumIndices; i++) { if (((prim.ArrayMask & (1 << 11)) != 0)) { GL.Color4(m_Model.ColorArray[0][prim.ColorIndices[0][i]]); } if (m_HasShaders) { if (((prim.ArrayMask & (1 << 12)) != 0) && !m_simpleRendering) { Vector4 color2 = m_Model.ColorArray[1][prim.ColorIndices[1][i]]; GL.SecondaryColor3(color2.X, color2.Y, color2.Z); //throw new Exception("color2 detected"); } if ((prim.ArrayMask & (1 << 13)) != 0) GL.MultiTexCoord2(TextureUnit.Texture0, ref m_Model.TexcoordArray[0][prim.TexcoordIndices[0][i]]); if (!m_simpleRendering) { if ((prim.ArrayMask & (1 << 14)) != 0) GL.MultiTexCoord2(TextureUnit.Texture1, ref m_Model.TexcoordArray[1][prim.TexcoordIndices[1][i]]); if ((prim.ArrayMask & (1 << 15)) != 0) GL.MultiTexCoord2(TextureUnit.Texture2, ref m_Model.TexcoordArray[2][prim.TexcoordIndices[2][i]]); if ((prim.ArrayMask & (1 << 16)) != 0) GL.MultiTexCoord2(TextureUnit.Texture3, ref m_Model.TexcoordArray[3][prim.TexcoordIndices[3][i]]); if ((prim.ArrayMask & (1 << 17)) != 0) GL.MultiTexCoord2(TextureUnit.Texture4, ref m_Model.TexcoordArray[4][prim.TexcoordIndices[4][i]]); if ((prim.ArrayMask & (1 << 18)) != 0) GL.MultiTexCoord2(TextureUnit.Texture5, ref m_Model.TexcoordArray[5][prim.TexcoordIndices[5][i]]); if ((prim.ArrayMask & (1 << 19)) != 0) GL.MultiTexCoord2(TextureUnit.Texture6, ref m_Model.TexcoordArray[6][prim.TexcoordIndices[6][i]]); if ((prim.ArrayMask & (1 << 20)) != 0) GL.MultiTexCoord2(TextureUnit.Texture7, ref m_Model.TexcoordArray[7][prim.TexcoordIndices[7][i]]); } } else { if ((prim.ArrayMask & (1 << 13)) != 0) GL.TexCoord2(m_Model.TexcoordArray[0][prim.TexcoordIndices[0][i]]); } //if ((prim.ArrayMask & (1 << 0)) != 0) GL.Color4(debug[prim.PosMatrixIndices[i]]); if (!m_simpleRendering) { if ((prim.ArrayMask & (1 << 10)) != 0) GL.Normal3(m_Model.NormalArray[prim.NormalIndices[i]]); } Vector3 pos = m_Model.PositionArray[prim.PositionIndices[i]]; if ((prim.ArrayMask & (1 << 0)) != 0) Vector3.TransformPerspective(ref pos, ref mtxtable[prim.PosMatrixIndices[i]], out pos); else Vector3.TransformPerspective(ref pos, ref mtxtable[0], out pos); GL.Vertex3(pos); } GL.End(); } } //if (batch.MatrixType == 1 || batch.MatrixType == 2) // GL.PopMatrix(); } //Clear shaders. Added 1/22/15 foreach (Bmd.SceneGraphNode node in m_Model.SceneGraph) { if (node.NodeType != 0) continue; int shape = node.NodeID; if (node.MaterialID != 0xFFFF) { if (m_HasShaders) { // shader: handles multitexturing, color combination, alpha test GL.UseProgram(m_Shaders[node.MaterialID].Program); // do multitexturing int max_i = 8; if (m_simpleRendering) { max_i = 1; } for (int i = 0; i < max_i; i++) { GL.ActiveTexture(TextureUnit.Texture0 + i); GL.Disable(EnableCap.Texture2D); } } } } GL.UseProgram(0); GL.Color4(1f, 1f, 1f, 1f); }