wow, it works!

git-svn-id: svn://svn.ijw.co.nz/svn/OpenRa@1190 993157c7-ee19-0410-b2c4-bb4e9862e678
This commit is contained in:
chrisf
2007-07-13 09:15:06 +00:00
parent bbbb25909a
commit d37bab15d0
16 changed files with 136 additions and 57 deletions

View File

@@ -17,6 +17,7 @@ namespace BluntDirectX { namespace Direct3D
Position = D3DFVF_XYZ,
Normal = D3DFVF_NORMAL,
Texture = D3DFVF_TEX1,
Texture2 = D3DFVF_TEX2,
};
public enum class PrimitiveType

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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);
}
}
}

View File

@@ -24,7 +24,7 @@ namespace OpenRa.Game
this.device = device;
}
public void Resolve()
void Resolve()
{
const string filename = "../../../palette-cache.png";
bitmap.Save(filename);

View File

@@ -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);
}

View File

@@ -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; } }

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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 );
}
}

View File

@@ -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,
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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" )
{

View File

@@ -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;