public void SetVertexArray(int VbIndex, int Stride, byte[] Buffer, GalVertexAttrib[] Attribs) { EnsureVbInitialized(VbIndex); VertexBuffers[VbIndex].PrimCount = Buffer.Length / Stride; VbInfo Vb = VertexBuffers[VbIndex]; IntPtr Length = new IntPtr(Buffer.Length); GL.BindBuffer(BufferTarget.ArrayBuffer, Vb.VboHandle); GL.BufferData(BufferTarget.ArrayBuffer, Length, Buffer, BufferUsageHint.StreamDraw); GL.BindBuffer(BufferTarget.ArrayBuffer, 0); GL.BindVertexArray(Vb.VaoHandle); for (int Attr = 0; Attr < 16; Attr++) { GL.DisableVertexAttribArray(Attr); } for (int Index = 0; Index < Attribs.Length; Index++) { GalVertexAttrib Attrib = Attribs[Index]; GL.EnableVertexAttribArray(Index); GL.BindBuffer(BufferTarget.ArrayBuffer, Vb.VboHandle); bool Unsigned = Attrib.Type == GalVertexAttribType.Unorm || Attrib.Type == GalVertexAttribType.Uint || Attrib.Type == GalVertexAttribType.Uscaled; bool Normalize = Attrib.Type == GalVertexAttribType.Snorm || Attrib.Type == GalVertexAttribType.Unorm; VertexAttribPointerType Type = 0; if (Attrib.Type == GalVertexAttribType.Float) { Type = VertexAttribPointerType.Float; } else { Type = AttribTypes[Attrib.Size] + (Unsigned ? 1 : 0); } int Size = AttribElements[Attrib.Size]; int Offset = Attrib.Offset; GL.VertexAttribPointer(Index, Size, Type, Normalize, Stride, Offset); } GL.BindVertexArray(0); }
private void SendVertexBuffers(AMemory Memory) { long Position = (long)GetRegister(NsGpuRegister._3dVertexArray0StartHigh) << 32 | (long)GetRegister(NsGpuRegister._3dVertexArray0StartLow) << 0; long Limit = (long)GetRegister(NsGpuRegister._3dVertexArray0LimitHigh) << 32 | (long)GetRegister(NsGpuRegister._3dVertexArray0LimitLow) << 0; int VbIndex = CurrentVertexBuffers.Count; if (!CurrentVertexBuffers.TryAdd(Position, VbIndex)) { VbIndex = CurrentVertexBuffers[Position]; } if (Limit != 0) { long Size = (Limit - Position) + 1; Position = Gpu.MemoryMgr.GetCpuAddr(Position); if (Position != -1) { byte[] Buffer = AMemoryHelper.ReadBytes(Memory, Position, (int)Size); int Stride = GetRegister(NsGpuRegister._3dVertexArray0Fetch) & 0xfff; List <GalVertexAttrib> Attribs = new List <GalVertexAttrib>(); for (int Attr = 0; Attr < 16; Attr++) { int Packed = GetRegister(NsGpuRegister._3dVertexAttrib0Format + Attr * 4); GalVertexAttrib Attrib = new GalVertexAttrib(Attr, (Packed >> 0) & 0x1f, ((Packed >> 6) & 0x1) != 0, (Packed >> 7) & 0x3fff, (GalVertexAttribSize)((Packed >> 21) & 0x3f), (GalVertexAttribType)((Packed >> 27) & 0x7), ((Packed >> 31) & 0x1) != 0); if (Attrib.Offset < Stride) { Attribs.Add(Attrib); } } Gpu.Renderer.QueueAction(delegate() { Gpu.Renderer.SendVertexBuffer(VbIndex, Buffer, Stride, Attribs.ToArray()); }); } } }
private static void ThrowUnsupportedAttrib(GalVertexAttrib Attrib) { throw new NotImplementedException("Unsupported size \"" + Attrib.Size + "\" on type \"" + Attrib.Type + "\"!"); }
private unsafe static void SetConstAttrib(GalVertexAttrib Attrib) { if (Attrib.Size == GalVertexAttribSize._10_10_10_2 || Attrib.Size == GalVertexAttribSize._11_11_10) { ThrowUnsupportedAttrib(Attrib); } if (Attrib.Type == GalVertexAttribType.Unorm) { switch (Attrib.Size) { case GalVertexAttribSize._8: case GalVertexAttribSize._8_8: case GalVertexAttribSize._8_8_8: case GalVertexAttribSize._8_8_8_8: GL.VertexAttrib4N((uint)Attrib.Index, (byte *)Attrib.Pointer); break; case GalVertexAttribSize._16: case GalVertexAttribSize._16_16: case GalVertexAttribSize._16_16_16: case GalVertexAttribSize._16_16_16_16: GL.VertexAttrib4N((uint)Attrib.Index, (ushort *)Attrib.Pointer); break; case GalVertexAttribSize._32: case GalVertexAttribSize._32_32: case GalVertexAttribSize._32_32_32: case GalVertexAttribSize._32_32_32_32: GL.VertexAttrib4N((uint)Attrib.Index, (uint *)Attrib.Pointer); break; } } else if (Attrib.Type == GalVertexAttribType.Snorm) { switch (Attrib.Size) { case GalVertexAttribSize._8: case GalVertexAttribSize._8_8: case GalVertexAttribSize._8_8_8: case GalVertexAttribSize._8_8_8_8: GL.VertexAttrib4N((uint)Attrib.Index, (sbyte *)Attrib.Pointer); break; case GalVertexAttribSize._16: case GalVertexAttribSize._16_16: case GalVertexAttribSize._16_16_16: case GalVertexAttribSize._16_16_16_16: GL.VertexAttrib4N((uint)Attrib.Index, (short *)Attrib.Pointer); break; case GalVertexAttribSize._32: case GalVertexAttribSize._32_32: case GalVertexAttribSize._32_32_32: case GalVertexAttribSize._32_32_32_32: GL.VertexAttrib4N((uint)Attrib.Index, (int *)Attrib.Pointer); break; } } else if (Attrib.Type == GalVertexAttribType.Uint) { switch (Attrib.Size) { case GalVertexAttribSize._8: case GalVertexAttribSize._8_8: case GalVertexAttribSize._8_8_8: case GalVertexAttribSize._8_8_8_8: GL.VertexAttribI4((uint)Attrib.Index, (byte *)Attrib.Pointer); break; case GalVertexAttribSize._16: case GalVertexAttribSize._16_16: case GalVertexAttribSize._16_16_16: case GalVertexAttribSize._16_16_16_16: GL.VertexAttribI4((uint)Attrib.Index, (ushort *)Attrib.Pointer); break; case GalVertexAttribSize._32: case GalVertexAttribSize._32_32: case GalVertexAttribSize._32_32_32: case GalVertexAttribSize._32_32_32_32: GL.VertexAttribI4((uint)Attrib.Index, (uint *)Attrib.Pointer); break; } } else if (Attrib.Type == GalVertexAttribType.Sint) { switch (Attrib.Size) { case GalVertexAttribSize._8: case GalVertexAttribSize._8_8: case GalVertexAttribSize._8_8_8: case GalVertexAttribSize._8_8_8_8: GL.VertexAttribI4((uint)Attrib.Index, (sbyte *)Attrib.Pointer); break; case GalVertexAttribSize._16: case GalVertexAttribSize._16_16: case GalVertexAttribSize._16_16_16: case GalVertexAttribSize._16_16_16_16: GL.VertexAttribI4((uint)Attrib.Index, (short *)Attrib.Pointer); break; case GalVertexAttribSize._32: case GalVertexAttribSize._32_32: case GalVertexAttribSize._32_32_32: case GalVertexAttribSize._32_32_32_32: GL.VertexAttribI4((uint)Attrib.Index, (int *)Attrib.Pointer); break; } } else if (Attrib.Type == GalVertexAttribType.Float) { switch (Attrib.Size) { case GalVertexAttribSize._32: case GalVertexAttribSize._32_32: case GalVertexAttribSize._32_32_32: case GalVertexAttribSize._32_32_32_32: GL.VertexAttrib4(Attrib.Index, (float *)Attrib.Pointer); break; default: ThrowUnsupportedAttrib(Attrib); break; } } }
private static VertexAttribPointerType GetType(Dictionary <GalVertexAttribSize, VertexAttribPointerType> Dict, GalVertexAttrib Attrib) { if (!Dict.TryGetValue(Attrib.Size, out VertexAttribPointerType Type)) { ThrowUnsupportedAttrib(Attrib); } return(Type); }
private static unsafe void SetConstAttrib(GalVertexAttrib attrib) { if (attrib.Size == GalVertexAttribSize._10_10_10_2 || attrib.Size == GalVertexAttribSize._11_11_10) { ThrowUnsupportedAttrib(attrib); } fixed(byte *ptr = attrib.Data) { if (attrib.Type == GalVertexAttribType.Unorm) { switch (attrib.Size) { case GalVertexAttribSize._8: case GalVertexAttribSize._8_8: case GalVertexAttribSize._8_8_8: case GalVertexAttribSize._8_8_8_8: GL.VertexAttrib4N((uint)attrib.Index, ptr); break; case GalVertexAttribSize._16: case GalVertexAttribSize._16_16: case GalVertexAttribSize._16_16_16: case GalVertexAttribSize._16_16_16_16: GL.VertexAttrib4N((uint)attrib.Index, (ushort *)ptr); break; case GalVertexAttribSize._32: case GalVertexAttribSize._32_32: case GalVertexAttribSize._32_32_32: case GalVertexAttribSize._32_32_32_32: GL.VertexAttrib4N((uint)attrib.Index, (uint *)ptr); break; } } else if (attrib.Type == GalVertexAttribType.Snorm) { switch (attrib.Size) { case GalVertexAttribSize._8: case GalVertexAttribSize._8_8: case GalVertexAttribSize._8_8_8: case GalVertexAttribSize._8_8_8_8: GL.VertexAttrib4N((uint)attrib.Index, (sbyte *)ptr); break; case GalVertexAttribSize._16: case GalVertexAttribSize._16_16: case GalVertexAttribSize._16_16_16: case GalVertexAttribSize._16_16_16_16: GL.VertexAttrib4N((uint)attrib.Index, (short *)ptr); break; case GalVertexAttribSize._32: case GalVertexAttribSize._32_32: case GalVertexAttribSize._32_32_32: case GalVertexAttribSize._32_32_32_32: GL.VertexAttrib4N((uint)attrib.Index, (int *)ptr); break; } } else if (attrib.Type == GalVertexAttribType.Uint) { switch (attrib.Size) { case GalVertexAttribSize._8: case GalVertexAttribSize._8_8: case GalVertexAttribSize._8_8_8: case GalVertexAttribSize._8_8_8_8: GL.VertexAttribI4((uint)attrib.Index, ptr); break; case GalVertexAttribSize._16: case GalVertexAttribSize._16_16: case GalVertexAttribSize._16_16_16: case GalVertexAttribSize._16_16_16_16: GL.VertexAttribI4((uint)attrib.Index, (ushort *)ptr); break; case GalVertexAttribSize._32: case GalVertexAttribSize._32_32: case GalVertexAttribSize._32_32_32: case GalVertexAttribSize._32_32_32_32: GL.VertexAttribI4((uint)attrib.Index, (uint *)ptr); break; } } else if (attrib.Type == GalVertexAttribType.Sint) { switch (attrib.Size) { case GalVertexAttribSize._8: case GalVertexAttribSize._8_8: case GalVertexAttribSize._8_8_8: case GalVertexAttribSize._8_8_8_8: GL.VertexAttribI4((uint)attrib.Index, (sbyte *)ptr); break; case GalVertexAttribSize._16: case GalVertexAttribSize._16_16: case GalVertexAttribSize._16_16_16: case GalVertexAttribSize._16_16_16_16: GL.VertexAttribI4((uint)attrib.Index, (short *)ptr); break; case GalVertexAttribSize._32: case GalVertexAttribSize._32_32: case GalVertexAttribSize._32_32_32: case GalVertexAttribSize._32_32_32_32: GL.VertexAttribI4((uint)attrib.Index, (int *)ptr); break; } } else if (attrib.Type == GalVertexAttribType.Float) { switch (attrib.Size) { case GalVertexAttribSize._32: case GalVertexAttribSize._32_32: case GalVertexAttribSize._32_32_32: case GalVertexAttribSize._32_32_32_32: GL.VertexAttrib4(attrib.Index, (float *)ptr); break; default: ThrowUnsupportedAttrib(attrib); break; } } } }
private unsafe static void SetConstAttrib(GalVertexAttrib Attrib) { void Unsupported() { throw new NotImplementedException("Constant attribute " + Attrib.Size + " not implemented!"); } if (Attrib.Size == GalVertexAttribSize._10_10_10_2 || Attrib.Size == GalVertexAttribSize._11_11_10) { Unsupported(); } if (Attrib.Type == GalVertexAttribType.Unorm) { switch (Attrib.Size) { case GalVertexAttribSize._8: case GalVertexAttribSize._8_8: case GalVertexAttribSize._8_8_8: case GalVertexAttribSize._8_8_8_8: GL.VertexAttrib4N((uint)Attrib.Index, (byte *)Attrib.Pointer); break; case GalVertexAttribSize._16: case GalVertexAttribSize._16_16: case GalVertexAttribSize._16_16_16: case GalVertexAttribSize._16_16_16_16: GL.VertexAttrib4N((uint)Attrib.Index, (ushort *)Attrib.Pointer); break; case GalVertexAttribSize._32: case GalVertexAttribSize._32_32: case GalVertexAttribSize._32_32_32: case GalVertexAttribSize._32_32_32_32: GL.VertexAttrib4N((uint)Attrib.Index, (uint *)Attrib.Pointer); break; } } else if (Attrib.Type == GalVertexAttribType.Snorm) { switch (Attrib.Size) { case GalVertexAttribSize._8: case GalVertexAttribSize._8_8: case GalVertexAttribSize._8_8_8: case GalVertexAttribSize._8_8_8_8: GL.VertexAttrib4N((uint)Attrib.Index, (sbyte *)Attrib.Pointer); break; case GalVertexAttribSize._16: case GalVertexAttribSize._16_16: case GalVertexAttribSize._16_16_16: case GalVertexAttribSize._16_16_16_16: GL.VertexAttrib4N((uint)Attrib.Index, (short *)Attrib.Pointer); break; case GalVertexAttribSize._32: case GalVertexAttribSize._32_32: case GalVertexAttribSize._32_32_32: case GalVertexAttribSize._32_32_32_32: GL.VertexAttrib4N((uint)Attrib.Index, (int *)Attrib.Pointer); break; } } else if (Attrib.Type == GalVertexAttribType.Uint) { switch (Attrib.Size) { case GalVertexAttribSize._8: case GalVertexAttribSize._8_8: case GalVertexAttribSize._8_8_8: case GalVertexAttribSize._8_8_8_8: GL.VertexAttribI4((uint)Attrib.Index, (byte *)Attrib.Pointer); break; case GalVertexAttribSize._16: case GalVertexAttribSize._16_16: case GalVertexAttribSize._16_16_16: case GalVertexAttribSize._16_16_16_16: GL.VertexAttribI4((uint)Attrib.Index, (ushort *)Attrib.Pointer); break; case GalVertexAttribSize._32: case GalVertexAttribSize._32_32: case GalVertexAttribSize._32_32_32: case GalVertexAttribSize._32_32_32_32: GL.VertexAttribI4((uint)Attrib.Index, (uint *)Attrib.Pointer); break; } } else if (Attrib.Type == GalVertexAttribType.Sint) { switch (Attrib.Size) { case GalVertexAttribSize._8: case GalVertexAttribSize._8_8: case GalVertexAttribSize._8_8_8: case GalVertexAttribSize._8_8_8_8: GL.VertexAttribI4((uint)Attrib.Index, (sbyte *)Attrib.Pointer); break; case GalVertexAttribSize._16: case GalVertexAttribSize._16_16: case GalVertexAttribSize._16_16_16: case GalVertexAttribSize._16_16_16_16: GL.VertexAttribI4((uint)Attrib.Index, (short *)Attrib.Pointer); break; case GalVertexAttribSize._32: case GalVertexAttribSize._32_32: case GalVertexAttribSize._32_32_32: case GalVertexAttribSize._32_32_32_32: GL.VertexAttribI4((uint)Attrib.Index, (int *)Attrib.Pointer); break; } } else if (Attrib.Type == GalVertexAttribType.Float) { switch (Attrib.Size) { case GalVertexAttribSize._32: case GalVertexAttribSize._32_32: case GalVertexAttribSize._32_32_32: case GalVertexAttribSize._32_32_32_32: GL.VertexAttrib4(Attrib.Index, (float *)Attrib.Pointer); break; default: Unsupported(); break; } } }
private static VertexAttribPointerType GetType(Dictionary <GalVertexAttribSize, VertexAttribPointerType> Dict, GalVertexAttrib Attrib) { if (!Dict.TryGetValue(Attrib.Size, out VertexAttribPointerType Type)) { throw new NotImplementedException("Unsupported size \"" + Attrib.Size + "\" on type \"" + Attrib.Type + "\"!"); } return(Type); }