bool RenderPrimitive(UInt16 address, PrimitiveInstruction opCode)
            {
                float shade = 0;

                // check if first vertex is a normal vector
                VertexInstruction vertex = Memory[address];

                if (vertex.IsNormalVector)
                {
                    // get the normal vector
                    Vector3 normal = GetVertexFromTable(vertex);
                    normal = Vector3.Transform(normal, Parent.WorldRotation);

                    // get the first coordinate
                    Vector3 pt = GetVertexFromTable(Memory[address + 1]);
                    pt = Vector3.Transform(pt, Parent.D3DTS_WORLD);

                    // check if surface is visible
                    if (Vector3.Dot(normal, pt) <= 0)
                    {
                        return(false); // not visible
                    }
                    // if shading enabled
                    if (opCode.IsShaded)
                    {
                        // both values are 14 bit fractional precision
                        // so dot product must be dividied by 2^(14+14) to normalize from 0.0 - 1.0
                        // but then we multiply by 8 (2^3) to convert to a pallete index
                        // so we divide by 2^(14+14-3)
                        const float scale = 1.0f / (1 << 25);
                        shade = Vector3.Dot(normal, Parent.Light) * scale;
                        shade = Math.Min(7, Math.Max(0, shade));
                    }
                }

                // should we skip rendering?
                if (opCode.SkipRender)
                {
                    return(true); // would have been visible
                }
                // prepare the vertex buffer
                BuildPrimitive(address, Parent.GetColor(opCode.ColorIndex, shade), opCode.RenderMode);

                return(true);
            }
            void BuildPrimitive(UInt16 address, Color color, Mathbox.RenderMode renderMode)
            {
                // add points to buffer
                for (int numVertices = 0; ;)
                {
                    VertexInstruction vertex = Memory[++address];
                    Vertices[numVertices++] = Vector3.Transform(GetVertexFromTable(vertex), Parent.D3DTS_WORLD);

                    // is this the last point of the plygon?
                    if (vertex.IsLastVertex)
                    {
#if DEBUG
                        if (MaxVertices < numVertices)
                        {
                            MaxVertices = numVertices;
                            Debug.WriteLine($"Max Vertices = {MaxVertices}");
                        }
#endif
                        DisplayListManager.AddPrimitive(renderMode, Vertices, numVertices, color);
                        return;
                    }
                }
            }
 Vector3 GetVertexFromTable(VertexInstruction vertex)
 {
     return(Parent.GetVectorAt((UInt16)(VertexTableAddr + vertex.VertexOffset)));
 }