public void CreateDisplayLists(bool texenabled, CombinerTypes combinertype) { Program.Status.Message = string.Format("Rendering room '{0}'...", (this.Parent as HeaderCommands.Rooms.RoomInfoClass).Description); CachedWithTextures = texenabled; CachedWithCombinerType = combinertype; /* Execute DLs once before creating GL lists, to cache textures & fragment programs beforehand */ foreach (uint dl in DLAddresses) { this.ROM.Renderer.Render(dl); } /* Copy most recently rendered triangles - this mesh header's DL's - to triangle list */ TriangleList = new List <SimpleF3DEX2.SimpleTriangle>(); foreach (SimpleF3DEX2.SimpleTriangle st in this.ROM.Renderer.LastTriList) { TriangleList.Add(st); } /* Now execute DLs again, with stuff already cached, which speeds everything up! */ DLs = new List <OpenGLHelpers.DisplayListEx>(); foreach (uint dl in DLAddresses) { OpenGLHelpers.DisplayListEx newdlex = new OpenGLHelpers.DisplayListEx(ListMode.Compile); this.ROM.Renderer.Render(dl, gldl: newdlex); newdlex.End(); DLs.Add(newdlex); } /* Clear the renderer's triangle list */ this.ROM.Renderer.LastTriList.Clear(); /* Finally, from the triangle list compiled before, create a simple display list for picking purposes */ PickGLID = GL.GenLists(1); GL.NewList(PickGLID, ListMode.Compile); GL.Disable(EnableCap.Lighting); GL.Disable(EnableCap.Texture2D); if (OpenGLHelpers.Initialization.SupportsFunction("glGenProgramsARB")) { GL.Disable((EnableCap)All.FragmentProgram); } GL.Begin(PrimitiveType.Triangles); foreach (SimpleF3DEX2.SimpleTriangle st in TriangleList) { GL.Vertex3(st.Vertices[0]); GL.Vertex3(st.Vertices[1]); GL.Vertex3(st.Vertices[2]); } GL.End(); GL.EndList(); }
public void Render(uint adr, bool call = false, OpenGLHelpers.DisplayListEx gldl = null) { try { ActiveGLDL.Push(gldl); /* Set some defaults */ if (!call) { GL.DepthMask(true); if (OpenGLHelpers.Initialization.SupportsFunction("glGenProgramsARB")) { GL.Disable((EnableCap)All.FragmentProgram); } if (OpenGLHelpers.Initialization.SupportsFunction("glCreateShader")) { GL.UseProgram(0); } PrimColor = EnvColor = new Color4(0.5f, 0.5f, 0.5f, 0.5f); /* If emulating combiner, set more defaults / load values */ if (Configuration.CombinerType == CombinerTypes.ArbCombiner) { GL.Arb.BindProgram(AssemblyProgramTargetArb.FragmentProgram, 0); GL.Arb.ProgramEnvParameter4(AssemblyProgramTargetArb.FragmentProgram, 0, PrimColor.R, PrimColor.G, PrimColor.B, PrimColor.A); GL.Arb.ProgramEnvParameter4(AssemblyProgramTargetArb.FragmentProgram, 1, EnvColor.R, EnvColor.G, EnvColor.B, EnvColor.A); } /* Clear out texture units */ for (int i = 0; i < (OpenGLHelpers.Initialization.SupportsFunction("glActiveTextureARB") ? 2 : 1); i++) { OpenGLHelpers.Initialization.ActiveTextureChecked(TextureUnit.Texture0 + i); GL.BindTexture(TextureTarget.Texture2D, OpenGLHelpers.MiscDrawingHelpers.DummyTextureID); } } /* Ucode interpreter starts here */ byte seg = (byte)(adr >> 24); adr &= 0xFFFFFF; byte[] segdata = (byte[])ROM.SegmentMapping[seg]; while (adr < segdata.Length) { byte cmd = segdata[adr]; /* EndDL */ if (cmd == (byte)General.UcodeCmds.ENDDL) { break; } /* Try to detect macros if any are defined */ inmacro = false; if (macros != null) { foreach (Macro m in macros) { if (adr + ((m.Commands.Length + 3) * 8) > segdata.Length) { break; } General.UcodeCmds[] nextcmd = new General.UcodeCmds[m.Commands.Length]; uint[] nextw0 = new uint[nextcmd.Length + 2]; uint[] nextw1 = new uint[nextcmd.Length + 2]; for (int i = 0; i < nextw0.Length; i++) { nextw0[i] = Endian.SwapUInt32(BitConverter.ToUInt32(segdata, (int)adr + (i * 8))); nextw1[i] = Endian.SwapUInt32(BitConverter.ToUInt32(segdata, (int)adr + (i * 8) + 4)); if (i < m.Commands.Length) { nextcmd[i] = (General.UcodeCmds)(nextw0[i] >> 24); } } if (inmacro = (Enumerable.SequenceEqual(m.Commands, nextcmd))) { m.Function(nextw0, nextw1); adr += (uint)(m.Commands.Length * 8); break; } } } /* No macro detected */ if (!inmacro) { /* Execute command */ ucodecmds[cmd](Endian.SwapUInt32(BitConverter.ToUInt32(segdata, (int)adr)), Endian.SwapUInt32(BitConverter.ToUInt32(segdata, (int)adr + 4))); adr += 8; /* Texture loading hack; if SetCombine OR LoadBlock command detected, try loading textures again (fixes Water Temple 1st room, borked walls; SM64toZ64 conversions?) */ if (Configuration.RenderTextures && (cmd == (byte)General.UcodeCmds.SETCOMBINE || cmd == (byte)General.UcodeCmds.LOADBLOCK) && Textures[0] != null) { LoadTextures(); } } } } catch (EntryPointNotFoundException) { //TODO handle this? } finally { ActiveGLDL.Pop(); } }
public void CreateDisplayLists(bool texenabled, CombinerTypes combinertype) { Program.Status.Message = string.Format("Rendering room '{0}'...", (this.Parent as HeaderCommands.Rooms.RoomInfoClass).Description); CachedWithTextures = texenabled; CachedWithCombinerType = combinertype; /* Execute DLs once before creating GL lists, to cache textures & fragment programs beforehand */ foreach (uint dl in DLAddresses) this.ROM.Renderer.Render(dl); /* Copy most recently rendered triangles - this mesh header's DL's - to triangle list */ TriangleList = new List<SimpleF3DEX2.SimpleTriangle>(); foreach (SimpleF3DEX2.SimpleTriangle st in this.ROM.Renderer.LastTriList) TriangleList.Add(st); /* Now execute DLs again, with stuff already cached, which speeds everything up! */ DLs = new List<OpenGLHelpers.DisplayListEx>(); foreach (uint dl in DLAddresses) { OpenGLHelpers.DisplayListEx newdlex = new OpenGLHelpers.DisplayListEx(ListMode.Compile); this.ROM.Renderer.Render(dl, gldl: newdlex); newdlex.End(); DLs.Add(newdlex); } /* Clear the renderer's triangle list */ this.ROM.Renderer.LastTriList.Clear(); /* Finally, from the triangle list compiled before, create a simple display list for picking purposes */ PickGLID = GL.GenLists(1); GL.NewList(PickGLID, ListMode.Compile); GL.Disable(EnableCap.Lighting); GL.Disable(EnableCap.Texture2D); if (OpenGLHelpers.Initialization.SupportsFunction("glGenProgramsARB")) GL.Disable((EnableCap)All.FragmentProgram); GL.Begin(PrimitiveType.Triangles); foreach (SimpleF3DEX2.SimpleTriangle st in TriangleList) { GL.Vertex3(st.Vertices[0]); GL.Vertex3(st.Vertices[1]); GL.Vertex3(st.Vertices[2]); } GL.End(); GL.EndList(); }