Beispiel #1
0
        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();
            }
        }
Beispiel #3
0
        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();
        }