wow, it works!
git-svn-id: svn://svn.ijw.co.nz/svn/OpenRa@1190 993157c7-ee19-0410-b2c4-bb4e9862e678
This commit is contained in:
@@ -17,6 +17,7 @@ namespace BluntDirectX { namespace Direct3D
|
||||
Position = D3DFVF_XYZ,
|
||||
Normal = D3DFVF_NORMAL,
|
||||
Texture = D3DFVF_TEX1,
|
||||
Texture2 = D3DFVF_TEX2,
|
||||
};
|
||||
|
||||
public enum class PrimitiveType
|
||||
|
||||
@@ -7,12 +7,12 @@ namespace OpenRa.FileFormats
|
||||
{
|
||||
public static class BitmapBuilder
|
||||
{
|
||||
public static Bitmap FromBytes( byte[] imageBytes, int width, int height, Palette pal )
|
||||
public static Bitmap FromBytes(byte[] imageBytes, Size size, Palette pal)
|
||||
{
|
||||
Bitmap bitmap = new Bitmap( width, height );
|
||||
for( int x = 0 ; x < width ; x++ )
|
||||
for( int y = 0 ; y < height ; y++ )
|
||||
bitmap.SetPixel( x, y, pal.GetColor( imageBytes[ x + width * y ] ) );
|
||||
Bitmap bitmap = new Bitmap(size.Width, size.Height);
|
||||
for (int x = 0; x < size.Width; x++)
|
||||
for (int y = 0; y < size.Height; y++)
|
||||
bitmap.SetPixel(x, y, pal.GetColor(imageBytes[x + size.Width * y]));
|
||||
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
@@ -42,6 +42,8 @@ namespace OpenRa.FileFormats
|
||||
public readonly ushort Width;
|
||||
public readonly ushort Height;
|
||||
|
||||
public Size Size { get { return new Size(Width, Height); } }
|
||||
|
||||
private readonly List<ImageHeader> headers = new List<ImageHeader>();
|
||||
|
||||
int recurseDepth = 0;
|
||||
|
||||
@@ -16,6 +16,7 @@ namespace OpenRa.FileFormats
|
||||
|
||||
readonly byte[] index;
|
||||
readonly List<Bitmap> TileBitmaps = new List<Bitmap>();
|
||||
public readonly List<byte[]> TileBitmapBytes = new List<byte[]>();
|
||||
|
||||
public Terrain( Stream stream, Palette pal )
|
||||
{
|
||||
@@ -44,15 +45,19 @@ namespace OpenRa.FileFormats
|
||||
|
||||
for( int i = 0 ; i < index.Length ; i++ )
|
||||
{
|
||||
if( index[ i ] != 255 )
|
||||
if (index[i] != 255)
|
||||
{
|
||||
byte[] tileData = new byte[ 24 * 24 ];
|
||||
stream.Position = ImgStart + index[ i ] * 24 * 24;
|
||||
stream.Read( tileData, 0, 24 * 24 );
|
||||
TileBitmaps.Add( BitmapBuilder.FromBytes( tileData, 24, 24, pal ) );
|
||||
byte[] tileData = new byte[24 * 24];
|
||||
stream.Position = ImgStart + index[i] * 24 * 24;
|
||||
stream.Read(tileData, 0, 24 * 24);
|
||||
TileBitmaps.Add(BitmapBuilder.FromBytes(tileData, new Size(24, 24), pal));
|
||||
TileBitmapBytes.Add(tileData);
|
||||
}
|
||||
else
|
||||
TileBitmaps.Add( null );
|
||||
{
|
||||
TileBitmaps.Add(null);
|
||||
TileBitmapBytes.Add(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ namespace OpenRa.Game
|
||||
this.device = device;
|
||||
}
|
||||
|
||||
public void Resolve()
|
||||
void Resolve()
|
||||
{
|
||||
const string filename = "../../../palette-cache.png";
|
||||
bitmap.Save(filename);
|
||||
|
||||
@@ -53,27 +53,25 @@ namespace OpenRa.Game
|
||||
|
||||
if (!tileMapping.ContainsKey(tileRef))
|
||||
{
|
||||
Bitmap srcImage = tileSet.tiles[tileRef.tile].GetTile(tileRef.image);
|
||||
SheetRectangle<Sheet> rect = builder.AddImage(srcImage.Size);
|
||||
|
||||
using (Graphics g = Graphics.FromImage(rect.sheet.bitmap))
|
||||
g.DrawImage(srcImage, rect.origin);
|
||||
SheetRectangle<Sheet> rect = builder.AddImage(new Size(24, 24));
|
||||
Util.CopyIntoChannel(rect.sheet.bitmap, TextureChannel.Red,
|
||||
tileSet.tiles[tileRef.tile].TileBitmapBytes[tileRef.image], rect);
|
||||
|
||||
tileMapping.Add(tileRef, rect);
|
||||
}
|
||||
}
|
||||
|
||||
world = new World(renderer.Device);
|
||||
treeCache = new TreeCache(renderer.Device, map, TileMix, pal);
|
||||
treeCache = new TreeCache(renderer.Device, map, TileMix);
|
||||
|
||||
foreach (TreeReference treeReference in map.Trees)
|
||||
world.Add(new Tree(treeReference, treeCache, map));
|
||||
|
||||
UnitSheetBuilder.Initialize(renderer.Device);
|
||||
UnitSheetBuilder.AddUnit("mcv", playerPal);
|
||||
UnitSheetBuilder.AddUnit("1tnk", playerPal);
|
||||
UnitSheetBuilder.AddUnit("2tnk", playerPal);
|
||||
UnitSheetBuilder.AddUnit("3tnk", playerPal);
|
||||
UnitSheetBuilder.AddUnit("mcv");
|
||||
UnitSheetBuilder.AddUnit("1tnk");
|
||||
UnitSheetBuilder.AddUnit("2tnk");
|
||||
UnitSheetBuilder.AddUnit("3tnk");
|
||||
|
||||
world.Add(new Mcv(new PointF(24 * 5, 24 * 5)));
|
||||
}
|
||||
@@ -226,7 +224,7 @@ namespace OpenRa.Game
|
||||
hardwarePalette.AddPalette(new Palette(pal, new PaletteRemap(
|
||||
File.OpenRead("../../../" + remap + ".rem"))));
|
||||
|
||||
hardwarePalette.Resolve();
|
||||
renderer.SetPalette(hardwarePalette);
|
||||
|
||||
return new TileSet(TileMix, TileSuffix, pal);
|
||||
}
|
||||
|
||||
@@ -13,10 +13,15 @@ namespace OpenRa.Game
|
||||
readonly GraphicsDevice device;
|
||||
readonly Effect shader;
|
||||
|
||||
readonly IntPtr r1Handle, r2Handle, baseTextureHandle, scrollHandle;
|
||||
readonly IntPtr r1Handle, r2Handle, baseTextureHandle, scrollHandle, paletteHandle;
|
||||
|
||||
const string shaderName = "diffuse.fx";
|
||||
|
||||
public void SetPalette(HardwarePalette hp)
|
||||
{
|
||||
shader.SetTexture(paletteHandle, hp.PaletteTexture);
|
||||
}
|
||||
|
||||
public Renderer(Control host, Size resolution, bool windowed)
|
||||
{
|
||||
host.ClientSize = resolution;
|
||||
@@ -30,6 +35,7 @@ namespace OpenRa.Game
|
||||
scrollHandle = shader.GetHandle("Scroll");
|
||||
r1Handle = shader.GetHandle("r1");
|
||||
r2Handle = shader.GetHandle("r2");
|
||||
paletteHandle = shader.GetHandle("Palette");
|
||||
}
|
||||
|
||||
public GraphicsDevice Device { get { return device; } }
|
||||
|
||||
@@ -17,6 +17,15 @@ namespace OpenRa.Game
|
||||
|
||||
public Sheet(Bitmap b, GraphicsDevice d) { bitmap = b; device = d; }
|
||||
|
||||
public Sheet(Size size, GraphicsDevice d)
|
||||
{
|
||||
bitmap = new Bitmap(size.Width, size.Height);
|
||||
device = d;
|
||||
|
||||
using (Graphics g = Graphics.FromImage(bitmap))
|
||||
g.FillRectangle(Brushes.Fuchsia, 0, 0, size.Width, size.Height);
|
||||
}
|
||||
|
||||
public Texture Texture
|
||||
{
|
||||
get
|
||||
|
||||
@@ -13,14 +13,14 @@ namespace OpenRa.Game
|
||||
|
||||
public readonly Sheet sh;
|
||||
|
||||
public TreeCache(GraphicsDevice device, Map map, Package package, Palette pal)
|
||||
public TreeCache(GraphicsDevice device, Map map, Package package)
|
||||
{
|
||||
Size pageSize = new Size(1024, 512);
|
||||
List<Sheet> sheets = new List<Sheet>();
|
||||
|
||||
Provider<Sheet> sheetProvider = delegate
|
||||
{
|
||||
Sheet sheet = new Sheet(new Bitmap(pageSize.Width, pageSize.Height), device);
|
||||
Sheet sheet = new Sheet(pageSize, device);
|
||||
sheets.Add(sheet);
|
||||
return sheet;
|
||||
};
|
||||
@@ -32,13 +32,11 @@ namespace OpenRa.Game
|
||||
if (trees.ContainsKey(r.Image))
|
||||
continue;
|
||||
|
||||
ShpReader reader = new ShpReader(package.GetContent(r.Image + "." + map.Theater.Substring(0, 3)));
|
||||
Bitmap bitmap = BitmapBuilder.FromBytes(reader[0].Image, reader.Width, reader.Height, pal);
|
||||
|
||||
SheetRectangle<Sheet> rect = builder.AddImage(bitmap.Size);
|
||||
using (Graphics g = Graphics.FromImage(rect.sheet.bitmap))
|
||||
g.DrawImage(bitmap, rect.origin);
|
||||
string filename = r.Image + "." + map.Theater.Substring(0, 3);
|
||||
|
||||
ShpReader reader = new ShpReader(package.GetContent(filename));
|
||||
SheetRectangle<Sheet> rect = builder.AddImage(reader.Size);
|
||||
Util.CopyIntoChannel(rect.sheet.bitmap, TextureChannel.Red, reader[0].Image, rect);
|
||||
trees.Add(r.Image, rect);
|
||||
}
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace OpenRa.Game
|
||||
{
|
||||
Provider<Sheet> sheetProvider = delegate
|
||||
{
|
||||
Sheet sheet = new Sheet(new Bitmap(pageSize.Width, pageSize.Height), device);
|
||||
Sheet sheet = new Sheet(pageSize, device);
|
||||
sheets.Add(sheet);
|
||||
return sheet;
|
||||
};
|
||||
@@ -28,17 +28,13 @@ namespace OpenRa.Game
|
||||
builder = new TileSheetBuilder<Sheet>(pageSize, sheetProvider);
|
||||
}
|
||||
|
||||
public static void AddUnit( string name, Palette pal )
|
||||
public static void AddUnit( string name )
|
||||
{
|
||||
ShpReader reader = new ShpReader( unitsPackage.GetContent( name + ".shp" ) );
|
||||
foreach( ImageHeader h in reader )
|
||||
{
|
||||
Bitmap bitmap = BitmapBuilder.FromBytes( h.Image, reader.Width, reader.Height, pal );
|
||||
|
||||
SheetRectangle<Sheet> rect = builder.AddImage( bitmap.Size );
|
||||
using( Graphics g = Graphics.FromImage( rect.sheet.bitmap ) )
|
||||
g.DrawImage( bitmap, rect.origin );
|
||||
|
||||
SheetRectangle<Sheet> rect = builder.AddImage(reader.Size);
|
||||
Util.CopyIntoChannel(rect.sheet.bitmap, TextureChannel.Red, h.Image, rect);
|
||||
McvSheet.Add( rect );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ namespace OpenRa.Game
|
||||
float u0 = (float)(s.origin.X + 0.5f) / (float)s.sheet.bitmap.Width;
|
||||
float u1 = (float)(s.origin.X + s.size.Width) / (float)s.sheet.bitmap.Width;
|
||||
|
||||
return (u > 0) ? u1 : u0;// (1 - u) * u0 + u * u1;
|
||||
return (u > 0) ? u1 : u0;
|
||||
}
|
||||
|
||||
public static float V(SheetRectangle<Sheet> s, float v)
|
||||
@@ -21,7 +21,7 @@ namespace OpenRa.Game
|
||||
float v0 = (float)(s.origin.Y + 0.5f) / (float)s.sheet.bitmap.Height;
|
||||
float v1 = (float)(s.origin.Y + s.size.Height) / (float)s.sheet.bitmap.Height;
|
||||
|
||||
return (v > 0) ? v1 : v0;// return (1 - v) * v0 + v * v1;
|
||||
return (v > 0) ? v1 : v0;
|
||||
}
|
||||
|
||||
public static Vertex MakeVertex(PointF o, float u, float v, SheetRectangle<Sheet> r)
|
||||
@@ -29,7 +29,8 @@ namespace OpenRa.Game
|
||||
float x2 = o.X + r.size.Width;
|
||||
float y2 = o.Y + r.size.Height;
|
||||
|
||||
return new Vertex(Lerp(o.X, x2, u), Lerp(o.Y, y2, v), 0, U(r, u), V(r, v));
|
||||
return new Vertex(Lerp(o.X, x2, u), Lerp(o.Y, y2, v), 0, U(r, u), V(r, v),
|
||||
0, 1);
|
||||
}
|
||||
|
||||
static float Lerp(float a, float b, float t)
|
||||
@@ -54,5 +55,39 @@ namespace OpenRa.Game
|
||||
indices.Add((ushort)(offset + 3));
|
||||
indices.Add((ushort)(offset + 2));
|
||||
}
|
||||
|
||||
public static void CopyIntoChannel(Bitmap bitmap, TextureChannel channel, byte[] src, SheetRectangle<Sheet> s)
|
||||
{
|
||||
for( int i = 0; i < s.size.Width; i++ )
|
||||
for (int j = 0; j < s.size.Height; j++)
|
||||
{
|
||||
Point p = new Point(s.origin.X + i, s.origin.Y + j);
|
||||
byte b = src[i + s.size.Width * j];
|
||||
Color original = bitmap.GetPixel(p.X, p.Y);
|
||||
bitmap.SetPixel(p.X, p.Y, ReplaceChannel(original, channel, b));
|
||||
}
|
||||
}
|
||||
|
||||
static Color ReplaceChannel(Color o, TextureChannel channel, byte p)
|
||||
{
|
||||
switch (channel)
|
||||
{
|
||||
case TextureChannel.Red: return Color.FromArgb(o.A, p, o.G, o.B);
|
||||
case TextureChannel.Green: return Color.FromArgb(o.A, o.R, p, o.B);
|
||||
case TextureChannel.Blue: return Color.FromArgb(o.A, o.R, o.G, p);
|
||||
case TextureChannel.Alpha: return Color.FromArgb(p, o.R, o.G, o.B);
|
||||
|
||||
default:
|
||||
throw new ArgumentException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum TextureChannel
|
||||
{
|
||||
Red,
|
||||
Green,
|
||||
Blue,
|
||||
Alpha,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,14 +10,18 @@ namespace OpenRa.Game
|
||||
struct Vertex
|
||||
{
|
||||
public float x, y, z, u, v;
|
||||
public float p, c;
|
||||
|
||||
public Vertex(float x, float y, float z, float u, float v)
|
||||
public Vertex(float x, float y, float z, float u, float v, float p, float c)
|
||||
{
|
||||
this.x = x; this.y = y; this.z = z;
|
||||
this.u = u;
|
||||
this.v = v;
|
||||
|
||||
this.p = p;
|
||||
this.c = c;
|
||||
}
|
||||
|
||||
public const VertexFormat Format = VertexFormat.Position | VertexFormat.Texture;
|
||||
public const VertexFormat Format = VertexFormat.Position | VertexFormat.Texture2;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -143,7 +143,7 @@ namespace OpenRa.TechTreeTest
|
||||
Stream s = package.GetContent(filename);
|
||||
ShpReader reader = new ShpReader(s);
|
||||
foreach (ImageHeader h in reader)
|
||||
return BitmapBuilder.FromBytes(h.Image, reader.Width, reader.Height, palette);
|
||||
return BitmapBuilder.FromBytes(h.Image, reader.Size, palette);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -92,7 +92,7 @@ namespace ShpViewer
|
||||
if (!TreeCache.TryGetValue(name, out ret))
|
||||
{
|
||||
ShpReader shp = new ShpReader(TileSet.MixFile.GetContent(name + TileSuffix));
|
||||
ret = BitmapBuilder.FromBytes(shp[0].Image, shp.Width, shp.Height, pal); ;
|
||||
ret = BitmapBuilder.FromBytes(shp[0].Image, shp.Size, pal); ;
|
||||
TreeCache.Add(name, ret);
|
||||
}
|
||||
return ret;
|
||||
|
||||
@@ -30,7 +30,7 @@ namespace ShpViewer
|
||||
pal = new Palette(pal, remap);
|
||||
|
||||
foreach( ImageHeader h in shpReader )
|
||||
bitmaps.Add( BitmapBuilder.FromBytes( h.Image, shpReader.Width, shpReader.Height, pal ) );
|
||||
bitmaps.Add( BitmapBuilder.FromBytes( h.Image, shpReader.Size, pal ) );
|
||||
}
|
||||
else if( ext == ".tem" || ext == ".sno" || ext == ".int" )
|
||||
{
|
||||
|
||||
43
diffuse.fx
43
diffuse.fx
@@ -2,7 +2,7 @@
|
||||
// Author: C. Forbes
|
||||
//--------------------------------------------------------
|
||||
|
||||
shared texture DiffuseTexture;
|
||||
shared texture DiffuseTexture, Palette;
|
||||
shared float2 Scroll;
|
||||
|
||||
shared float2 r1, r2; // matrix elements
|
||||
@@ -18,32 +18,57 @@ sampler s_DiffuseTexture = sampler_state {
|
||||
AddressW = Wrap;
|
||||
};
|
||||
|
||||
sampler s_PaletteTexture = sampler_state {
|
||||
Texture = <Palette>;
|
||||
MinFilter = None;
|
||||
MagFilter = None;
|
||||
MipFilter = None;
|
||||
|
||||
AddressU = Clamp;
|
||||
AddressV = Clamp;
|
||||
};
|
||||
|
||||
struct VertexIn {
|
||||
float4 Position: POSITION;
|
||||
float2 Tex0: TEXCOORD0;
|
||||
float2 Tex1: TEXCOORD1;
|
||||
};
|
||||
|
||||
struct VertexOut {
|
||||
float4 Position: POSITION;
|
||||
float2 Tex0: TEXCOORD0;
|
||||
float3 Tex0: TEXCOORD0;
|
||||
float4 ChannelMask: TEXCOORD1;
|
||||
};
|
||||
|
||||
struct FragmentIn {
|
||||
float2 Tex0: TEXCOORD0;
|
||||
float3 Tex0: TEXCOORD0;
|
||||
float4 ChannelMask: TEXCOORD1;
|
||||
};
|
||||
|
||||
float4 DecodeChannelMask( float x )
|
||||
{
|
||||
if (x > 0)
|
||||
return (x > 0.5f) ? float4(1,0,0,0) : float4(0,1,0,0);
|
||||
else
|
||||
return (x <-0.5f) ? float4(0,0,0,1) : float4(0,0,1,0);
|
||||
}
|
||||
|
||||
VertexOut Simple_vp(VertexIn v) {
|
||||
VertexOut o;
|
||||
|
||||
float2 p = (v.Position.xy - Scroll.xy) * r1 + r2;
|
||||
o.Position = float4(p.x,p.y,0,1);
|
||||
o.Tex0 = v.Tex0;
|
||||
o.Tex0 = float3(v.Tex0.x, v.Tex0.y, v.Tex1.x);
|
||||
o.ChannelMask = DecodeChannelMask( v.Tex1.y );
|
||||
return o;
|
||||
}
|
||||
|
||||
float4 Simple_fp(FragmentIn f) : COLOR0 {
|
||||
float4 color = tex2D(s_DiffuseTexture, f.Tex0);
|
||||
return color;
|
||||
const float2 texelOffset = float2( 0, 1.0f/32.0f );
|
||||
|
||||
float4 Palette_fp(FragmentIn f) : COLOR0 {
|
||||
float4 x = tex2D(s_DiffuseTexture, f.Tex0.xy);
|
||||
float2 p = float2( dot(x, f.ChannelMask), f.Tex0.z );
|
||||
return tex2D(s_PaletteTexture, p + texelOffset);
|
||||
}
|
||||
|
||||
technique low_quality {
|
||||
@@ -53,7 +78,7 @@ technique low_quality {
|
||||
ZEnable = false;
|
||||
CullMode = None;
|
||||
VertexShader = compile vs_2_0 Simple_vp();
|
||||
PixelShader = compile ps_2_0 Simple_fp();
|
||||
PixelShader = compile ps_2_0 Palette_fp();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,7 +89,7 @@ technique high_quality {
|
||||
ZEnable = false;
|
||||
CullMode = None;
|
||||
VertexShader = compile vs_2_0 Simple_vp();
|
||||
PixelShader = compile ps_2_0 Simple_fp();
|
||||
PixelShader = compile ps_2_0 Palette_fp();
|
||||
|
||||
SrcBlend = SrcAlpha;
|
||||
DestBlend = InvSrcAlpha;
|
||||
|
||||
Reference in New Issue
Block a user