diff --git a/OpenRA.Game/Graphics/IGraphicsDevice.cs b/OpenRA.Game/Graphics/IGraphicsDevice.cs index 36cd2d8abe..17593a24bb 100644 --- a/OpenRA.Game/Graphics/IGraphicsDevice.cs +++ b/OpenRA.Game/Graphics/IGraphicsDevice.cs @@ -64,7 +64,6 @@ namespace OpenRA bool SetClipboardText(string text); void DrawPrimitives(PrimitiveType type, int firstVertex, int numVertices); - void SetLineWidth(float width); void EnableScissor(int left, int top, int width, int height); void DisableScissor(); @@ -123,7 +122,6 @@ namespace OpenRA PointList, LineList, TriangleList, - QuadList, } public struct Range diff --git a/OpenRA.Game/Graphics/RgbaColorRenderer.cs b/OpenRA.Game/Graphics/RgbaColorRenderer.cs index 860a8b1da5..71efd67086 100644 --- a/OpenRA.Game/Graphics/RgbaColorRenderer.cs +++ b/OpenRA.Game/Graphics/RgbaColorRenderer.cs @@ -30,7 +30,7 @@ namespace OpenRA.Graphics this.renderer = renderer; this.shader = shader; vertices = new Vertex[renderer.TempBufferSize]; - renderAction = () => renderer.DrawBatch(vertices, nv, PrimitiveType.QuadList); + renderAction = () => renderer.DrawBatch(vertices, nv, PrimitiveType.TriangleList); } public void Flush() @@ -49,7 +49,7 @@ namespace OpenRA.Graphics { renderer.CurrentBatchRenderer = this; - if (nv + 4 > renderer.TempBufferSize) + if (nv + 6 > renderer.TempBufferSize) Flush(); var delta = (end - start) / (end - start).Length; @@ -70,14 +70,16 @@ namespace OpenRA.Graphics vertices[nv++] = new Vertex(start - corner + Offset, sr, sg, sb, sa); vertices[nv++] = new Vertex(start + corner + Offset, sr, sg, sb, sa); vertices[nv++] = new Vertex(end + corner + Offset, er, eg, eb, ea); + vertices[nv++] = new Vertex(end + corner + Offset, er, eg, eb, ea); vertices[nv++] = new Vertex(end - corner + Offset, er, eg, eb, ea); + vertices[nv++] = new Vertex(start - corner + Offset, sr, sg, sb, sa); } public void DrawLine(float2 start, float2 end, float width, Color color) { renderer.CurrentBatchRenderer = this; - if (nv + 4 > renderer.TempBufferSize) + if (nv + 6 > renderer.TempBufferSize) Flush(); var delta = (end - start) / (end - start).Length; @@ -92,7 +94,9 @@ namespace OpenRA.Graphics vertices[nv++] = new Vertex(start - corner + Offset, r, g, b, a); vertices[nv++] = new Vertex(start + corner + Offset, r, g, b, a); vertices[nv++] = new Vertex(end + corner + Offset, r, g, b, a); + vertices[nv++] = new Vertex(end + corner + Offset, r, g, b, a); vertices[nv++] = new Vertex(end - corner + Offset, r, g, b, a); + vertices[nv++] = new Vertex(start - corner + Offset, r, g, b, a); } /// @@ -160,13 +164,15 @@ namespace OpenRA.Graphics var cd = closed || i < limit ? IntersectionOf(end - corner, dir, end - nextCorner, nextDir) : end - corner; // Fill segment - if (nv + 4 > renderer.TempBufferSize) + if (nv + 6 > renderer.TempBufferSize) Flush(); vertices[nv++] = new Vertex(ca + Offset, r, g, b, a); vertices[nv++] = new Vertex(cb + Offset, r, g, b, a); vertices[nv++] = new Vertex(cc + Offset, r, g, b, a); + vertices[nv++] = new Vertex(cc + Offset, r, g, b, a); vertices[nv++] = new Vertex(cd + Offset, r, g, b, a); + vertices[nv++] = new Vertex(ca + Offset, r, g, b, a); // Advance line segment end = next; @@ -215,7 +221,7 @@ namespace OpenRA.Graphics { renderer.CurrentBatchRenderer = this; - if (nv + 4 > renderer.TempBufferSize) + if (nv + 6 > renderer.TempBufferSize) Flush(); color = Util.PremultiplyAlpha(color); @@ -227,7 +233,9 @@ namespace OpenRA.Graphics vertices[nv++] = new Vertex(a + Offset, cr, cg, cb, ca); vertices[nv++] = new Vertex(b + Offset, cr, cg, cb, ca); vertices[nv++] = new Vertex(c + Offset, cr, cg, cb, ca); + vertices[nv++] = new Vertex(c + Offset, cr, cg, cb, ca); vertices[nv++] = new Vertex(d + Offset, cr, cg, cb, ca); + vertices[nv++] = new Vertex(a + Offset, cr, cg, cb, ca); } public void FillEllipse(RectangleF r, Color color, int vertices = 32) diff --git a/OpenRA.Game/Graphics/SpriteRenderer.cs b/OpenRA.Game/Graphics/SpriteRenderer.cs index a1a8d7436d..f040e3f6c2 100644 --- a/OpenRA.Game/Graphics/SpriteRenderer.cs +++ b/OpenRA.Game/Graphics/SpriteRenderer.cs @@ -29,7 +29,7 @@ namespace OpenRA.Graphics this.renderer = renderer; this.shader = shader; vertices = new Vertex[renderer.TempBufferSize]; - renderAction = () => renderer.DrawBatch(vertices, nv, PrimitiveType.QuadList); + renderAction = () => renderer.DrawBatch(vertices, nv, PrimitiveType.TriangleList); } public void Flush() @@ -51,7 +51,7 @@ namespace OpenRA.Graphics { renderer.CurrentBatchRenderer = this; - if (s.BlendMode != currentBlend || s.Sheet != currentSheet || nv + 4 > renderer.TempBufferSize) + if (s.BlendMode != currentBlend || s.Sheet != currentSheet || nv + 6 > renderer.TempBufferSize) Flush(); currentBlend = s.BlendMode; @@ -72,7 +72,7 @@ namespace OpenRA.Graphics { SetRenderStateForSprite(s); Util.FastCreateQuad(vertices, location + s.FractionalOffset * size, s, paletteTextureIndex, nv, size); - nv += 4; + nv += 6; } // For RGBASpriteRenderer, which doesn't use palettes @@ -90,14 +90,14 @@ namespace OpenRA.Graphics { SetRenderStateForSprite(s); Util.FastCreateQuad(vertices, a, b, c, d, s, 0, nv); - nv += 4; + nv += 6; } public void DrawSprite(Sprite s, Vertex[] sourceVertices, int offset) { SetRenderStateForSprite(s); - Array.Copy(sourceVertices, offset, vertices, nv, 4); - nv += 4; + Array.Copy(sourceVertices, offset, vertices, nv, 6); + nv += 6; } public void DrawVertexBuffer(IVertexBuffer buffer, int start, int length, PrimitiveType type, Sheet sheet, BlendMode blendMode) diff --git a/OpenRA.Game/Graphics/TerrainSpriteLayer.cs b/OpenRA.Game/Graphics/TerrainSpriteLayer.cs index 153f7eca24..4da279e2f5 100644 --- a/OpenRA.Game/Graphics/TerrainSpriteLayer.cs +++ b/OpenRA.Game/Graphics/TerrainSpriteLayer.cs @@ -44,7 +44,7 @@ namespace OpenRA.Graphics this.palette = palette; map = world.Map; - rowStride = 4 * map.MapSize.X; + rowStride = 6 * map.MapSize.X; vertices = new Vertex[rowStride * map.MapSize.Y]; vertexBuffer = Game.Renderer.Device.CreateVertexBuffer(vertices.Length); @@ -87,7 +87,7 @@ namespace OpenRA.Graphics else sprite = emptySprite; - var offset = rowStride * uv.V + 4 * uv.U; + var offset = rowStride * uv.V + 6 * uv.U; Util.FastCreateQuad(vertices, pos, sprite, palette.TextureIndex, offset, sprite.Size); dirtyRows.Add(uv.V); @@ -123,7 +123,7 @@ namespace OpenRA.Graphics Game.Renderer.WorldSpriteRenderer.DrawVertexBuffer( vertexBuffer, rowStride * firstRow, rowStride * (lastRow - firstRow), - PrimitiveType.QuadList, Sheet, BlendMode); + PrimitiveType.TriangleList, Sheet, BlendMode); Game.Renderer.Flush(); } diff --git a/OpenRA.Game/Graphics/Util.cs b/OpenRA.Game/Graphics/Util.cs index 5167792447..0178c5ffc5 100644 --- a/OpenRA.Game/Graphics/Util.cs +++ b/OpenRA.Game/Graphics/Util.cs @@ -38,7 +38,9 @@ namespace OpenRA.Graphics vertices[nv] = new Vertex(a, r.Left, r.Top, paletteTextureIndex, attribC); vertices[nv + 1] = new Vertex(b, r.Right, r.Top, paletteTextureIndex, attribC); vertices[nv + 2] = new Vertex(c, r.Right, r.Bottom, paletteTextureIndex, attribC); - vertices[nv + 3] = new Vertex(d, r.Left, r.Bottom, paletteTextureIndex, attribC); + vertices[nv + 3] = new Vertex(c, r.Right, r.Bottom, paletteTextureIndex, attribC); + vertices[nv + 4] = new Vertex(d, r.Left, r.Bottom, paletteTextureIndex, attribC); + vertices[nv + 5] = new Vertex(a, r.Left, r.Top, paletteTextureIndex, attribC); } public static void FastCopyIntoChannel(Sprite dest, byte[] src) { FastCopyIntoChannel(dest, 0, src); } diff --git a/OpenRA.Game/Graphics/VoxelLoader.cs b/OpenRA.Game/Graphics/VoxelLoader.cs index 64630e54a2..4153134c32 100644 --- a/OpenRA.Game/Graphics/VoxelLoader.cs +++ b/OpenRA.Game/Graphics/VoxelLoader.cs @@ -89,12 +89,14 @@ namespace OpenRA.Graphics var channelP = ChannelSelect[(int)s.Channel]; var channelC = ChannelSelect[(int)s.Channel + 1]; - return new Vertex[4] + return new Vertex[6] { new Vertex(coord(0, 0), s.Left, s.Top, channelP, channelC), new Vertex(coord(su, 0), s.Right, s.Top, channelP, channelC), new Vertex(coord(su, sv), s.Right, s.Bottom, channelP, channelC), - new Vertex(coord(0, sv), s.Left, s.Bottom, channelP, channelC) + new Vertex(coord(su, sv), s.Right, s.Bottom, channelP, channelC), + new Vertex(coord(0, sv), s.Left, s.Bottom, channelP, channelC), + new Vertex(coord(0, 0), s.Left, s.Top, channelP, channelC) }; } diff --git a/OpenRA.Game/Graphics/VoxelRenderer.cs b/OpenRA.Game/Graphics/VoxelRenderer.cs index bd25b01345..a7eb0a3ddf 100644 --- a/OpenRA.Game/Graphics/VoxelRenderer.cs +++ b/OpenRA.Game/Graphics/VoxelRenderer.cs @@ -263,7 +263,7 @@ namespace OpenRA.Graphics shader.SetVec("AmbientLight", ambientLight, 3); shader.SetVec("DiffuseLight", diffuseLight, 3); - shader.Render(() => renderer.DrawBatch(Game.ModData.VoxelLoader.VertexBuffer, renderData.Start, renderData.Count, PrimitiveType.QuadList)); + shader.Render(() => renderer.DrawBatch(Game.ModData.VoxelLoader.VertexBuffer, renderData.Start, renderData.Count, PrimitiveType.TriangleList)); } public void BeginFrame() diff --git a/OpenRA.Game/Renderer.cs b/OpenRA.Game/Renderer.cs index 232a13e48f..157362adc6 100644 --- a/OpenRA.Game/Renderer.cs +++ b/OpenRA.Game/Renderer.cs @@ -173,11 +173,6 @@ namespace OpenRA CurrentBatchRenderer = null; } - public void SetLineWidth(float width) - { - Device.SetLineWidth(width); - } - public Size Resolution { get { return Device.WindowSize; } } public interface IBatchRenderer { void Flush(); } diff --git a/OpenRA.Platforms.Default/Sdl2GraphicsDevice.cs b/OpenRA.Platforms.Default/Sdl2GraphicsDevice.cs index f0824c25fd..f438e209df 100644 --- a/OpenRA.Platforms.Default/Sdl2GraphicsDevice.cs +++ b/OpenRA.Platforms.Default/Sdl2GraphicsDevice.cs @@ -91,9 +91,9 @@ namespace OpenRA.Platforms.Default throw new InvalidProgramException("Missing OpenGL extension GL_EXT_framebuffer_object. See graphics.log for details."); } - GL.EnableClientState(ArrayCap.VertexArray); + GL.EnableVertexAttribArray(Shader.VertexPosAttributeIndex); ErrorHandler.CheckGlError(); - GL.EnableClientState(ArrayCap.TextureCoordArray); + GL.EnableVertexAttribArray(Shader.TexCoordAttributeIndex); ErrorHandler.CheckGlError(); SDL.SDL_SetModState(SDL.SDL_Keymod.KMOD_NONE); @@ -210,7 +210,6 @@ namespace OpenRA.Platforms.Default case PrimitiveType.PointList: return BeginMode.Points; case PrimitiveType.LineList: return BeginMode.Lines; case PrimitiveType.TriangleList: return BeginMode.Triangles; - case PrimitiveType.QuadList: return BeginMode.Quads; } throw new NotImplementedException(); @@ -332,13 +331,6 @@ namespace OpenRA.Platforms.Default ErrorHandler.CheckGlError(); } - public void SetLineWidth(float width) - { - VerifyThreadAffinity(); - GL.LineWidth(width); - ErrorHandler.CheckGlError(); - } - public Bitmap TakeScreenshot() { var rect = new Rectangle(Point.Empty, WindowSize); diff --git a/OpenRA.Platforms.Default/Shader.cs b/OpenRA.Platforms.Default/Shader.cs index 6e8653e1bd..78d2295c02 100644 --- a/OpenRA.Platforms.Default/Shader.cs +++ b/OpenRA.Platforms.Default/Shader.cs @@ -18,6 +18,9 @@ namespace OpenRA.Platforms.Default { class Shader : ThreadAffine, IShader { + public const int VertexPosAttributeIndex = 0; + public const int TexCoordAttributeIndex = 1; + readonly Dictionary samplers = new Dictionary(); readonly Dictionary textures = new Dictionary(); readonly int program; @@ -62,6 +65,12 @@ namespace OpenRA.Platforms.Default // Assemble program program = GL.CreateProgram(); ErrorHandler.CheckGlError(); + + GL.BindAttribLocation(program, VertexPosAttributeIndex, "aVertexPosition"); + ErrorHandler.CheckGlError(); + GL.BindAttribLocation(program, TexCoordAttributeIndex, "aVertexTexCoord"); + ErrorHandler.CheckGlError(); + GL.AttachShader(program, vertexShader); ErrorHandler.CheckGlError(); GL.AttachShader(program, fragmentShader); diff --git a/OpenRA.Platforms.Default/VertexBuffer.cs b/OpenRA.Platforms.Default/VertexBuffer.cs index 1126fff3d0..f3e44400e6 100644 --- a/OpenRA.Platforms.Default/VertexBuffer.cs +++ b/OpenRA.Platforms.Default/VertexBuffer.cs @@ -63,9 +63,9 @@ namespace OpenRA.Platforms.Default VerifyThreadAffinity(); GL.BindBuffer(BufferTarget.ArrayBuffer, buffer); ErrorHandler.CheckGlError(); - GL.VertexPointer(3, VertexPointerType.Float, VertexSize, IntPtr.Zero); + GL.VertexAttribPointer(Shader.VertexPosAttributeIndex, 3, VertexAttribPointerType.Float, false, VertexSize, IntPtr.Zero); ErrorHandler.CheckGlError(); - GL.TexCoordPointer(4, TexCoordPointerType.Float, VertexSize, new IntPtr(12)); + GL.VertexAttribPointer(Shader.TexCoordAttributeIndex, 4, VertexAttribPointerType.Float, false, VertexSize, new IntPtr(12)); ErrorHandler.CheckGlError(); } diff --git a/OpenRA.Platforms.Null/NullGraphicsDevice.cs b/OpenRA.Platforms.Null/NullGraphicsDevice.cs index 401310bf4e..6c10eb6f41 100644 --- a/OpenRA.Platforms.Null/NullGraphicsDevice.cs +++ b/OpenRA.Platforms.Null/NullGraphicsDevice.cs @@ -50,7 +50,6 @@ namespace OpenRA.Platforms.Null } public void DrawPrimitives(PrimitiveType pt, int firstVertex, int numVertices) { } - public void SetLineWidth(float width) { } public IVertexBuffer CreateVertexBuffer(int size) { return new NullVertexBuffer(); } public ITexture CreateTexture() { return new NullTexture(); } diff --git a/glsl/color.frag b/glsl/color.frag index 3f45d895ff..88c1daa512 100644 --- a/glsl/color.frag +++ b/glsl/color.frag @@ -1,4 +1,6 @@ +varying vec4 vColor; + void main() { - gl_FragColor = gl_Color; + gl_FragColor = vColor; } \ No newline at end of file diff --git a/glsl/color.vert b/glsl/color.vert index e38ef97d14..ffc17d90e1 100644 --- a/glsl/color.vert +++ b/glsl/color.vert @@ -1,8 +1,13 @@ uniform vec2 Scroll; -uniform vec2 r1, r2; // matrix elements +uniform vec2 r1, r2; + +attribute vec4 aVertexPosition; +attribute vec4 aVertexTexCoord; +varying vec4 vColor; + void main() { - vec2 p = (gl_Vertex.xy - Scroll.xy)*r1 + r2; + vec2 p = (aVertexPosition.xy - Scroll.xy)*r1 + r2; gl_Position = vec4(p.x,p.y,0,1); - gl_FrontColor = gl_MultiTexCoord0; + vColor = aVertexTexCoord; } diff --git a/glsl/rgba.frag b/glsl/rgba.frag index 7f52d6d4ac..b01e69da10 100644 --- a/glsl/rgba.frag +++ b/glsl/rgba.frag @@ -1,5 +1,7 @@ uniform sampler2D DiffuseTexture; +varying vec4 vTexCoord; + void main() { - gl_FragColor = texture2D(DiffuseTexture,gl_TexCoord[0].st); + gl_FragColor = texture2D(DiffuseTexture, vTexCoord.st); } \ No newline at end of file diff --git a/glsl/rgba.vert b/glsl/rgba.vert index 89ffea0e96..f5d8177526 100644 --- a/glsl/rgba.vert +++ b/glsl/rgba.vert @@ -1,9 +1,13 @@ uniform vec2 Scroll; uniform vec2 r1, r2; +attribute vec4 aVertexPosition; +attribute vec4 aVertexTexCoord; +varying vec4 vTexCoord; + void main() { - vec2 p = (gl_Vertex.xy - Scroll.xy)*r1 + r2; + vec2 p = (aVertexPosition.xy - Scroll.xy)*r1 + r2; gl_Position = vec4(p.x,p.y,0,1); - gl_TexCoord[0] = gl_MultiTexCoord0; + vTexCoord = aVertexTexCoord; } diff --git a/glsl/shp.frag b/glsl/shp.frag index 43972d45b6..c7e1c1189f 100644 --- a/glsl/shp.frag +++ b/glsl/shp.frag @@ -2,23 +2,23 @@ uniform sampler2D DiffuseTexture, Palette; uniform bool EnableDepthPreview; -varying vec4 TexCoord; -varying vec4 ChannelMask; -varying vec4 DepthMask; +varying vec4 vTexCoord; +varying vec4 vChannelMask; +varying vec4 vDepthMask; void main() { - vec4 x = texture2D(DiffuseTexture, TexCoord.st); - vec2 p = vec2(dot(x, ChannelMask), TexCoord.p); + vec4 x = texture2D(DiffuseTexture, vTexCoord.st); + vec2 p = vec2(dot(x, vChannelMask), vTexCoord.p); vec4 c = texture2D(Palette, p); // Discard any transparent fragments (both color and depth) if (c.a == 0.0) discard; - if (EnableDepthPreview && length(DepthMask) > 0.0) + if (EnableDepthPreview && length(vDepthMask) > 0.0) { - float depth = dot(x, DepthMask); + float depth = dot(x, vDepthMask); gl_FragColor = vec4(depth, depth, depth, 1); } else diff --git a/glsl/shp.vert b/glsl/shp.vert index 18fd603a77..c59498a96b 100644 --- a/glsl/shp.vert +++ b/glsl/shp.vert @@ -1,9 +1,11 @@ uniform vec2 Scroll; uniform vec2 r1,r2; // matrix elements -varying vec4 TexCoord; -varying vec4 ChannelMask; -varying vec4 DepthMask; +attribute vec4 aVertexPosition; +attribute vec4 aVertexTexCoord; +varying vec4 vTexCoord; +varying vec4 vChannelMask; +varying vec4 vDepthMask; vec4 DecodeChannelMask(float x) { @@ -34,9 +36,9 @@ vec4 DecodeDepthChannelMask(float x) void main() { - vec2 p = (gl_Vertex.xy - Scroll.xy) * r1 + r2; + vec2 p = (aVertexPosition.xy - Scroll.xy) * r1 + r2; gl_Position = vec4(p.x,p.y,0,1); - TexCoord = gl_MultiTexCoord0; - ChannelMask = DecodeChannelMask(gl_MultiTexCoord0.w); - DepthMask = DecodeDepthChannelMask(gl_MultiTexCoord0.w); + vTexCoord = aVertexTexCoord; + vChannelMask = DecodeChannelMask(aVertexTexCoord.w); + vDepthMask = DecodeDepthChannelMask(aVertexTexCoord.w); } diff --git a/glsl/vxl.frag b/glsl/vxl.frag index c29828ea69..c9373d5fb1 100644 --- a/glsl/vxl.frag +++ b/glsl/vxl.frag @@ -4,18 +4,18 @@ uniform vec2 PaletteRows; uniform vec4 LightDirection; uniform vec3 AmbientLight, DiffuseLight; -varying vec4 TexCoord; -varying vec4 ChannelMask; -varying vec4 NormalsMask; +varying vec4 vTexCoord; +varying vec4 vChannelMask; +varying vec4 vNormalsMask; void main() { - vec4 x = texture2D(DiffuseTexture, TexCoord.st); - vec4 color = texture2D(Palette, vec2(dot(x, ChannelMask), PaletteRows.x)); + vec4 x = texture2D(DiffuseTexture, vTexCoord.st); + vec4 color = texture2D(Palette, vec2(dot(x, vChannelMask), PaletteRows.x)); if (color.a < 0.01) discard; - vec4 normal = (2.0 * texture2D(Palette, vec2(dot(x, NormalsMask), PaletteRows.y)) - 1.0); + vec4 normal = (2.0 * texture2D(Palette, vec2(dot(x, vNormalsMask), PaletteRows.y)) - 1.0); vec3 intensity = AmbientLight + DiffuseLight * max(dot(normal, LightDirection), 0.0); gl_FragColor = vec4(intensity * color.rgb, color.a); } diff --git a/glsl/vxl.vert b/glsl/vxl.vert index e349fd4a2a..07a84997b2 100644 --- a/glsl/vxl.vert +++ b/glsl/vxl.vert @@ -1,9 +1,11 @@ uniform mat4 View; uniform mat4 TransformMatrix; -varying vec4 TexCoord; -varying vec4 ChannelMask; -varying vec4 NormalsMask; +attribute vec4 aVertexPosition; +attribute vec4 aVertexTexCoord; +varying vec4 vTexCoord; +varying vec4 vChannelMask; +varying vec4 vNormalsMask; vec4 DecodeMask(float x) { @@ -15,8 +17,8 @@ vec4 DecodeMask(float x) void main() { - gl_Position = View*TransformMatrix*gl_Vertex; - TexCoord = gl_MultiTexCoord0; - ChannelMask = DecodeMask(gl_MultiTexCoord0.z); - NormalsMask = DecodeMask(gl_MultiTexCoord0.w); + gl_Position = View*TransformMatrix*aVertexPosition; + vTexCoord = aVertexTexCoord; + vChannelMask = DecodeMask(aVertexTexCoord.z); + vNormalsMask = DecodeMask(aVertexTexCoord.w); }