git-svn-id: svn://svn.ijw.co.nz/svn/OpenRa@1167 993157c7-ee19-0410-b2c4-bb4e9862e678
This commit is contained in:
@@ -16,20 +16,20 @@ namespace OpenRa.Game
|
|||||||
|
|
||||||
class Tree : Actor
|
class Tree : Actor
|
||||||
{
|
{
|
||||||
public Tree( TreeReference r, TreeRenderer renderer, Map map )
|
public Tree( TreeReference r, TreeCache renderer, Map map )
|
||||||
{
|
{
|
||||||
location = new PointF(24 * (r.X - map.XOffset), 24 * (r.Y - map.YOffset));
|
location = new PointF(24 * (r.X - map.XOffset), 24 * (r.Y - map.YOffset));
|
||||||
currentImages = new SheetRectangle<Sheet>[] { renderer.GetImage( r.Image ) };
|
currentImages = new SheetRectangle<Sheet>[] { renderer.GetImage( r.Image ) };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class TreeRenderer
|
class TreeCache
|
||||||
{
|
{
|
||||||
Dictionary<string, SheetRectangle<Sheet>> trees = new Dictionary<string, SheetRectangle<Sheet>>();
|
Dictionary<string, SheetRectangle<Sheet>> trees = new Dictionary<string, SheetRectangle<Sheet>>();
|
||||||
|
|
||||||
public readonly Sheet sh;
|
public readonly Sheet sh;
|
||||||
|
|
||||||
public TreeRenderer(GraphicsDevice device, Map map, Package package, Palette pal)
|
public TreeCache(GraphicsDevice device, Map map, Package package, Palette pal)
|
||||||
{
|
{
|
||||||
Size pageSize = new Size( 1024, 512 );
|
Size pageSize = new Size( 1024, 512 );
|
||||||
List<Sheet> sheets = new List<Sheet>();
|
List<Sheet> sheets = new List<Sheet>();
|
||||||
@@ -97,11 +97,12 @@ namespace OpenRa.Game
|
|||||||
// assumption: its not going to hurt, to draw *all* units.
|
// assumption: its not going to hurt, to draw *all* units.
|
||||||
// in reality, 500 tanks is going to hurt our perf.
|
// in reality, 500 tanks is going to hurt our perf.
|
||||||
|
|
||||||
public void Draw()
|
public void Draw( Renderer renderer )
|
||||||
{
|
{
|
||||||
int sprites = 0;
|
int sprites = 0;
|
||||||
List<Vertex> vertices = new List<Vertex>();
|
List<Vertex> vertices = new List<Vertex>();
|
||||||
List<ushort> indices = new List<ushort>();
|
List<ushort> indices = new List<ushort>();
|
||||||
|
Sheet sheet = null;
|
||||||
|
|
||||||
foreach (Actor a in actors)
|
foreach (Actor a in actors)
|
||||||
{
|
{
|
||||||
@@ -124,9 +125,11 @@ namespace OpenRa.Game
|
|||||||
indices.Add((ushort)(offset + 3));
|
indices.Add((ushort)(offset + 3));
|
||||||
indices.Add((ushort)(offset + 2));
|
indices.Add((ushort)(offset + 2));
|
||||||
|
|
||||||
|
sheet = image.sheet;
|
||||||
|
|
||||||
if (++sprites >= spritesPerBatch)
|
if (++sprites >= spritesPerBatch)
|
||||||
{
|
{
|
||||||
DrawBatch(vertices, indices);
|
DrawBatch(vertices, indices, renderer, sheet);
|
||||||
|
|
||||||
vertices = new List<Vertex>();
|
vertices = new List<Vertex>();
|
||||||
indices = new List<ushort>();
|
indices = new List<ushort>();
|
||||||
@@ -136,19 +139,22 @@ namespace OpenRa.Game
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (sprites > 0)
|
if (sprites > 0)
|
||||||
DrawBatch(vertices, indices);
|
DrawBatch(vertices, indices, renderer, sheet);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DrawBatch(List<Vertex> vertices, List<ushort> indices)
|
void DrawBatch(List<Vertex> vertices, List<ushort> indices, Renderer renderer, Sheet sheet)
|
||||||
{
|
{
|
||||||
vb.SetData(vertices.ToArray());
|
vb.SetData(vertices.ToArray());
|
||||||
ib.SetData(indices.ToArray());
|
ib.SetData(indices.ToArray());
|
||||||
|
|
||||||
vb.Bind(0);
|
renderer.DrawWithShader(ShaderQuality.High,
|
||||||
ib.Bind();
|
delegate
|
||||||
|
{
|
||||||
device.DrawIndexedPrimitives(PrimitiveType.TriangleList,
|
renderer.DrawBatch(vb, ib,
|
||||||
vertices.Count, indices.Count / 3);
|
new Range<int>(0, vertices.Count),
|
||||||
|
new Range<int>(0, indices.Count),
|
||||||
|
sheet.texture);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
static float U(SheetRectangle<Sheet> s, float u)
|
static float U(SheetRectangle<Sheet> s, float u)
|
||||||
|
|||||||
@@ -12,7 +12,8 @@ namespace OpenRa.Game
|
|||||||
{
|
{
|
||||||
class MainWindow : Form
|
class MainWindow : Form
|
||||||
{
|
{
|
||||||
readonly GraphicsDevice device;
|
readonly Renderer renderer;
|
||||||
|
|
||||||
readonly Map map;
|
readonly Map map;
|
||||||
readonly TileSet tileSet;
|
readonly TileSet tileSet;
|
||||||
|
|
||||||
@@ -21,7 +22,6 @@ namespace OpenRa.Game
|
|||||||
string TileSuffix;
|
string TileSuffix;
|
||||||
|
|
||||||
const string mapName = "scm12ea.ini";
|
const string mapName = "scm12ea.ini";
|
||||||
const string shaderName = "diffuse.fx";
|
|
||||||
|
|
||||||
Dictionary<TileReference, SheetRectangle<Sheet>> tileMapping =
|
Dictionary<TileReference, SheetRectangle<Sheet>> tileMapping =
|
||||||
new Dictionary<TileReference, SheetRectangle<Sheet>>();
|
new Dictionary<TileReference, SheetRectangle<Sheet>>();
|
||||||
@@ -30,11 +30,8 @@ namespace OpenRa.Game
|
|||||||
|
|
||||||
Dictionary<Sheet, IndexBuffer> drawBatches = new Dictionary<Sheet, IndexBuffer>();
|
Dictionary<Sheet, IndexBuffer> drawBatches = new Dictionary<Sheet, IndexBuffer>();
|
||||||
|
|
||||||
Effect effect;
|
|
||||||
IntPtr texture, scroll, r1h, r2h;
|
|
||||||
|
|
||||||
World world;
|
World world;
|
||||||
TreeRenderer treeRenderer;
|
TreeCache treeRenderer;
|
||||||
|
|
||||||
void LoadTextures()
|
void LoadTextures()
|
||||||
{
|
{
|
||||||
@@ -68,10 +65,10 @@ namespace OpenRa.Game
|
|||||||
}
|
}
|
||||||
|
|
||||||
foreach (Sheet s in tempSheets)
|
foreach (Sheet s in tempSheets)
|
||||||
s.LoadTexture(device);
|
s.LoadTexture(renderer.Device);
|
||||||
|
|
||||||
world = new World(device);
|
world = new World(renderer.Device);
|
||||||
treeRenderer = new TreeRenderer(device, map, TileMix, pal);
|
treeRenderer = new TreeCache(renderer.Device, map, TileMix, pal);
|
||||||
|
|
||||||
foreach (TreeReference treeReference in map.Trees)
|
foreach (TreeReference treeReference in map.Trees)
|
||||||
world.Add(new Tree(treeReference, treeRenderer, map));
|
world.Add(new Tree(treeReference, treeRenderer, map));
|
||||||
@@ -123,12 +120,12 @@ namespace OpenRa.Game
|
|||||||
indexList.Add((ushort)(offset + 2));
|
indexList.Add((ushort)(offset + 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
vertexBuffer = new FvfVertexBuffer<Vertex>(device, vertices.Count, Vertex.Format);
|
vertexBuffer = new FvfVertexBuffer<Vertex>(renderer.Device, vertices.Count, Vertex.Format);
|
||||||
vertexBuffer.SetData(vertices.ToArray());
|
vertexBuffer.SetData(vertices.ToArray());
|
||||||
|
|
||||||
foreach (KeyValuePair<Sheet, List<ushort>> p in indexMap)
|
foreach (KeyValuePair<Sheet, List<ushort>> p in indexMap)
|
||||||
{
|
{
|
||||||
IndexBuffer indexBuffer = new IndexBuffer(device, p.Value.Count);
|
IndexBuffer indexBuffer = new IndexBuffer(renderer.Device, p.Value.Count);
|
||||||
indexBuffer.SetData(p.Value.ToArray());
|
indexBuffer.SetData(p.Value.ToArray());
|
||||||
drawBatches.Add(p.Key, indexBuffer);
|
drawBatches.Add(p.Key, indexBuffer);
|
||||||
}
|
}
|
||||||
@@ -136,14 +133,9 @@ namespace OpenRa.Game
|
|||||||
|
|
||||||
public MainWindow()
|
public MainWindow()
|
||||||
{
|
{
|
||||||
ClientSize = new Size(1280,800);
|
renderer = new Renderer(this, new Size(1280, 800), false);
|
||||||
|
|
||||||
Visible = true;
|
Visible = true;
|
||||||
|
|
||||||
//device = GraphicsDevice.Create(this, ClientSize.Width, ClientSize.Height, true, false);
|
|
||||||
|
|
||||||
device = GraphicsDevice.Create(this, 1280, 800, false, false);
|
|
||||||
|
|
||||||
IniFile mapFile = new IniFile(File.OpenRead("../../../" + mapName));
|
IniFile mapFile = new IniFile(File.OpenRead("../../../" + mapName));
|
||||||
map = new Map(mapFile);
|
map = new Map(mapFile);
|
||||||
|
|
||||||
@@ -153,13 +145,6 @@ namespace OpenRa.Game
|
|||||||
|
|
||||||
LoadTextures();
|
LoadTextures();
|
||||||
LoadVertexBuffer();
|
LoadVertexBuffer();
|
||||||
|
|
||||||
effect = new Effect(device, File.OpenRead("../../../" + shaderName));
|
|
||||||
texture = effect.GetHandle("DiffuseTexture");
|
|
||||||
scroll = effect.GetHandle("Scroll");
|
|
||||||
|
|
||||||
r1h = effect.GetHandle("r1");
|
|
||||||
r2h = effect.GetHandle("r2");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void Run()
|
internal void Run()
|
||||||
@@ -211,67 +196,39 @@ namespace OpenRa.Game
|
|||||||
PointF r1 = new PointF(2.0f / ClientSize.Width, -2.0f / ClientSize.Height);
|
PointF r1 = new PointF(2.0f / ClientSize.Width, -2.0f / ClientSize.Height);
|
||||||
PointF r2 = new PointF(-1, 1);
|
PointF r2 = new PointF(-1, 1);
|
||||||
|
|
||||||
device.Begin();
|
renderer.BeginFrame(r1, r2, scrollPos);
|
||||||
device.Clear( 0, Surfaces.Color );
|
|
||||||
|
|
||||||
vertexBuffer.Bind(0);
|
|
||||||
|
|
||||||
effect.Quality = ShaderQuality.Low;
|
|
||||||
effect.Begin();
|
|
||||||
effect.BeginPass(0);
|
|
||||||
|
|
||||||
effect.SetValue(scroll, scrollPos);
|
|
||||||
effect.SetValue(r1h, r1);
|
|
||||||
effect.SetValue(r2h, r2);
|
|
||||||
|
|
||||||
foreach (KeyValuePair<Sheet, IndexBuffer> batch in drawBatches)
|
foreach (KeyValuePair<Sheet, IndexBuffer> batch in drawBatches)
|
||||||
|
DrawTerrainBatch(batch);
|
||||||
|
|
||||||
|
world.Draw(renderer);
|
||||||
|
|
||||||
|
renderer.EndFrame();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawTerrainBatch(KeyValuePair<Sheet, IndexBuffer> batch)
|
||||||
|
{
|
||||||
|
int indicesPerRow = map.Width * 6;
|
||||||
|
int verticesPerRow = map.Width * 4;
|
||||||
|
|
||||||
|
int visibleRows = (int)(ClientSize.Height / 24.0f + 2);
|
||||||
|
|
||||||
|
int firstRow = (int)(scrollPos.Y / 24.0f);
|
||||||
|
int lastRow = firstRow + visibleRows;
|
||||||
|
|
||||||
|
if (firstRow < 0) firstRow = 0;
|
||||||
|
|
||||||
|
if (lastRow < 0) lastRow = 0;
|
||||||
|
|
||||||
|
if (lastRow > map.Height) lastRow = map.Height;
|
||||||
|
|
||||||
|
Range<int> indexRange = new Range<int>(indicesPerRow * firstRow, indicesPerRow * lastRow);
|
||||||
|
Range<int> vertexRange = new Range<int>(verticesPerRow * firstRow, verticesPerRow * lastRow);
|
||||||
|
|
||||||
|
renderer.DrawWithShader(ShaderQuality.Low, delegate
|
||||||
{
|
{
|
||||||
effect.SetTexture(texture, batch.Key.texture);
|
renderer.DrawBatch(vertexBuffer, batch.Value, vertexRange, indexRange, batch.Key.texture);
|
||||||
effect.Commit();
|
});
|
||||||
|
|
||||||
batch.Value.Bind();
|
|
||||||
|
|
||||||
int indicesPerRow = map.Width * 6;
|
|
||||||
int verticesPerRow = map.Width * 4;
|
|
||||||
|
|
||||||
int visibleRows = (int)(ClientSize.Height / 24.0f + 2);
|
|
||||||
|
|
||||||
int firstRow = (int)(scrollPos.Y / 24.0f);
|
|
||||||
int lastRow = firstRow + visibleRows;
|
|
||||||
|
|
||||||
if (firstRow < 0)
|
|
||||||
firstRow = 0;
|
|
||||||
|
|
||||||
if (lastRow < 0)
|
|
||||||
lastRow = 0;
|
|
||||||
|
|
||||||
if (lastRow > map.Height)
|
|
||||||
lastRow = map.Height;
|
|
||||||
|
|
||||||
Range<int> indexRange = new Range<int>(indicesPerRow * firstRow, indicesPerRow * lastRow);
|
|
||||||
Range<int> vertexRange = new Range<int>(verticesPerRow * firstRow, verticesPerRow * lastRow);
|
|
||||||
|
|
||||||
device.DrawIndexedPrimitives(PrimitiveType.TriangleList,
|
|
||||||
vertexRange, indexRange);
|
|
||||||
}
|
|
||||||
|
|
||||||
effect.EndPass();
|
|
||||||
effect.End();
|
|
||||||
|
|
||||||
effect.Quality = ShaderQuality.High;
|
|
||||||
effect.Begin();
|
|
||||||
effect.BeginPass(0);
|
|
||||||
|
|
||||||
effect.SetTexture(texture, treeRenderer.sh.texture);
|
|
||||||
effect.Commit();
|
|
||||||
|
|
||||||
world.Draw();
|
|
||||||
|
|
||||||
effect.EndPass();
|
|
||||||
effect.End();
|
|
||||||
|
|
||||||
device.End();
|
|
||||||
device.Present();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TileSet LoadTileSet(Map currentMap)
|
TileSet LoadTileSet(Map currentMap)
|
||||||
|
|||||||
@@ -43,6 +43,7 @@
|
|||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="Program.cs" />
|
<Compile Include="Program.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
|
<Compile Include="Renderer.cs" />
|
||||||
<Compile Include="Sheet.cs" />
|
<Compile Include="Sheet.cs" />
|
||||||
<Compile Include="Vertex.cs" />
|
<Compile Include="Vertex.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|||||||
82
OpenRa.Game/Renderer.cs
Normal file
82
OpenRa.Game/Renderer.cs
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
using System.Drawing;
|
||||||
|
using BluntDirectX.Direct3D;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
namespace OpenRa.Game
|
||||||
|
{
|
||||||
|
class Renderer
|
||||||
|
{
|
||||||
|
readonly GraphicsDevice device;
|
||||||
|
readonly Effect shader;
|
||||||
|
|
||||||
|
readonly IntPtr r1Handle, r2Handle, baseTextureHandle, scrollHandle;
|
||||||
|
|
||||||
|
const string shaderName = "diffuse.fx";
|
||||||
|
|
||||||
|
public Renderer(Control host, Size resolution, bool windowed)
|
||||||
|
{
|
||||||
|
host.ClientSize = resolution;
|
||||||
|
device = GraphicsDevice.Create(host,
|
||||||
|
resolution.Width, resolution.Height, windowed, false);
|
||||||
|
|
||||||
|
shader = new Effect(device, File.OpenRead("../../../" + shaderName));
|
||||||
|
shader.Quality = ShaderQuality.Low;
|
||||||
|
|
||||||
|
baseTextureHandle = shader.GetHandle("DiffuseTexture");
|
||||||
|
scrollHandle = shader.GetHandle("Scroll");
|
||||||
|
r1Handle = shader.GetHandle("r1");
|
||||||
|
r2Handle = shader.GetHandle("r2");
|
||||||
|
}
|
||||||
|
|
||||||
|
public GraphicsDevice Device { get { return device; } }
|
||||||
|
|
||||||
|
public void BeginFrame( PointF r1, PointF r2, PointF scroll )
|
||||||
|
{
|
||||||
|
device.Begin();
|
||||||
|
device.Clear(0, Surfaces.Color);
|
||||||
|
|
||||||
|
shader.SetValue(scrollHandle, scroll);
|
||||||
|
shader.SetValue(r1Handle, r1);
|
||||||
|
shader.SetValue(r2Handle, r2);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void EndFrame()
|
||||||
|
{
|
||||||
|
device.End();
|
||||||
|
device.Present();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DrawWithShader(ShaderQuality quality, MethodInvoker task)
|
||||||
|
{
|
||||||
|
shader.Quality = quality;
|
||||||
|
|
||||||
|
int passes = shader.Begin();
|
||||||
|
for (int pass = 0; pass < passes; pass++)
|
||||||
|
{
|
||||||
|
shader.BeginPass(pass);
|
||||||
|
task();
|
||||||
|
shader.EndPass();
|
||||||
|
}
|
||||||
|
|
||||||
|
shader.End();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DrawBatch<T>(FvfVertexBuffer<T> vertices, IndexBuffer indices,
|
||||||
|
Range<int> vertexRange, Range<int> indexRange, Texture texture)
|
||||||
|
where T : struct
|
||||||
|
{
|
||||||
|
shader.SetTexture(baseTextureHandle, texture);
|
||||||
|
shader.Commit();
|
||||||
|
|
||||||
|
vertices.Bind(0);
|
||||||
|
indices.Bind();
|
||||||
|
|
||||||
|
device.DrawIndexedPrimitives(PrimitiveType.TriangleList,
|
||||||
|
vertexRange, indexRange);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user