使用Manged DirectX 9.0 --- Part III

在Part I中建立了一个框架, 这一节则把它的功能完善起来.
[code]
1.全屏模式和窗口模式
    
private void InitDirectDraw()
{            
    display = new Device(); // 创建显示设备.
    description = new SurfaceDescription();// 新建一个页面描述
    if(IsFullScreen)//全屏模式
    {
        display.SetCooperativeLevel(this.Window,CooperativeLevelFlags.FullscreenExclusive);//全屏独占模式
        display.SetDisplayMode(ScreenWidth, ScreenHeight, BitPerPixel, 0, false);//设置分辨率,色深
        description.SurfaceCaps.PrimarySurface = true;//为主页面
        description.SurfaceCaps.Flip = true;//有换页链
        description.SurfaceCaps.Complex = true;//有后台缓存
        description.BackBufferCount = 1;//一个后台缓存
        front = new Surface(description, display);//得到主页面
        SurfaceCaps caps = new SurfaceCaps();
        caps.BackBuffer = true;
        back = front.GetAttachedSurface(caps);//缓冲页面
    }
    else//窗口模式
    {
        display.SetCooperativeLevel(this.Window,CooperativeLevelFlags.Normal);
        description.SurfaceCaps.PrimarySurface = true; // 仅设为主页面

 

        front = new Surface(description, display);//得到主页面
        clip = new Clipper(display);//裁剪器
        clip.Window = Window;
        front.Clipper = clip;

        description.Clear(); // 每次新建一个页面时,页面描述要清空一下
        description.SurfaceCaps.OffScreenPlain=true;
        back = new Surface(new Bitmap(ScreenWidth,ScreenHeight),description, display); 
        this.Window.Paint += new System.Windows.Forms.PaintEventHandler(this.Windowed_Paint);
        this.Window.Resize += new System.EventHandler(this.Windowed_SizeChanged);
        this.Window.SizeChanged += new System.EventHandler(this.Windowed_SizeChanged);
    }    
}
    

2.导入多种图像格式
    
/// <summary>
/// 图像资源由Tile类来处理
/// </summary>
public class Tile
{
    public string Name="";
    public Bitmap ImageData;
    public bool UseColorKey=false;
    public int Width=0;
    public int Height=0;
    public int Rows=1;
    public int Columns=1;
    public int TileWidth;
    public int TileHeight;
    public Tile(Bitmap bitmap)
    {
        ImageData=bitmap;
        TileWidth=Width=ImageData.Width;
        TileHeight=Height=ImageData.Height;
    }
    public Tile(string filename):this(filename,filename){}
    public Tile(string tilename,string filename)//支持BMP,JEPG,GIF,WMF,EMF,ICO,PNG,TIFF
    {
        Name=tilename;
        ImageData=new Bitmap(Image.FromFile(filename));//GDI+不支持所给的文件格式时,抛出内存不足的异常
        TileWidth=Width=ImageData.Width;
        TileHeight=Height=ImageData.Height;
    }
    public Tile(string filename,int row,int col):this(filename,filename,row,col){}
    public Tile(string tilename,string filename,int row,int col)
    {
        Name=tilename;
        ImageData=new Bitmap(Image.FromFile(filename));
        Width=ImageData.Width;
        Height=ImageData.Height;
        Rows=row;
        Columns=col;
        TileWidth=Width/Columns;
        TileHeight=Height/Rows;
    }
    

3.设置颜色键
    
public Color ColorKey
{
    set
    {
        int key=value.ToArgb();
        int black=Color.Black.ToArgb();
        if(key==black)
        {
            UseColorKey=true;
            return;
        }
        Color Fblack=Color.FromArgb(0,0,8);
        for(int i=0;i<ImageData.Width;i++)
        {
            for(int j=0;j<ImageData.Height;j++)
            {
                int pixel=ImageData.GetPixel(i,j).ToArgb();
                if(pixel==black)
                {
                    ImageData.SetPixel(i,j,Fblack);
                }
                else if(pixel==key)
                {
                    ImageData.SetPixel(i,j,Color.Black);
                }
            }
        }
        UseColorKey=true;
    }
}
    
4.设置透明色和透明度
public Color AlphaColor
{
    set{ImageData.MakeTransparent(value);}
}
public int Alphavalue
{
    set
    {
        for(int i=0;i<ImageData.Width;i++)
        {
            for(int j=0;j<ImageData.Height;j++)
            {
                Color pixel=ImageData.GetPixel(i,j);
                ImageData.SetPixel(i,j,Color.FromArgb(value,pixel.R,pixel.G,pixel.B));
            }
        }
    }
}
5.把图像分成小格子
    
public Tile this[int i,int j]
{
    get
    {
        Rectangle rect=this.Rectangles(i,j);
        Tile subtile=this.GetSubTile(rect);
        subtile.Name=this.Name+i+j;
        return subtile;
    }
}
public Rectangle Rectangles(int i,int j)
{
    if(i<1||i>Rows||j<1||j>Columns)
        throw new IndexOutOfRangeException("Tile index");
    int x=(j-1)*TileWidth;
    int y=(i-1)*TileHeight;
    return new Rectangle(x,y,TileWidth,TileHeight);
}
public Tile GetSubTile(Rectangle rect)
{
    Bitmap bm=this.ImageData.Clone(rect,ImageData.PixelFormat);
    Tile tile=new Tile(bm);
    tile.UseColorKey=this.UseColorKey;
    return tile;
}
    
6.图像加入绘图设备
    
public void AddTiles(params Tile[] tiles)
{
    foreach(Tile t in tiles)
    {
        this.AddTile(t);
        if(t.Rows>1||t.Columns>1)
        {
            for(int i=1;i<=t.Rows;i++)
            {
                for(int j=1;j<=t.Columns;j++)
                {
                    this.AddTile(t[i,j]);
                }
            }
        }
    }
}
void AddTile(Tile tile)
{
    this.Tiles.Add(tile.Name,CreateSurface(tile));
}
Surface CreateSurface(Tile tile)
{
    description.Clear();
    description.SurfaceCaps.OffScreenPlain=true;
    Surface surface=new Surface(tile.ImageData,description,display);
    if(tile.UseColorKey)
    {
        ColorKey ck=new ColorKey();
        surface.SetColorKey(ColorKeyFlags.SourceDraw,ck);
    }
    return surface;
}
    
7.绘制图像--普通绘制
    
public void DrawTile(int x,int y,string tilename)
{
    back.DrawFast(x,y,(Surface)Tiles[tilename],DrawFastFlags.Wait);
}
    
8.绘制图像--颜色键绘制
    
public void DrawTile(int x,int y,Tile tile)
{
    if(tile.UseColorKey)
    {
        back.DrawFast(x,y,(Surface)Tiles[tile.Name],DrawFastFlags.Wait|DrawFastFlags.SourceColorKey);
    }
    else
    {
        back.DrawFast(x,y,(Surface)Tiles[tile.Name],DrawFastFlags.Wait);
    }
}
    
9.绘制图像--Alpha混合绘制
    
public void DrawTileAlpha(int x,int y,Tile pic)
{
    IntPtr MyDC = back.GetDc();
    Graphics MyDraw = Graphics.FromHdc(MyDC);//暂时由GDI+来实现

    MyDraw.DrawImage(pic.ImageData,x,y);

    MyDraw.Dispose();
    back.ReleaseDc(MyDC);
}
    
10.绘制图像--图像RECT裁减绘制
    
public void DrawTile(int x,int y,Tile tile,Rectangle rect)
{
    Tile pic=tile.GetSubTile(rect);
    DrawTile(x,y,pic,true);
}
public void DrawTile(int x,int y,Tile pic,bool docut)
{
    int w=pic.Width;
    int h=pic.Height;
    Bitmap bm=pic.ImageData;
    bool cut=false;
    if(pic.Width>ScreenWidth-x)
    {
        w=ScreenWidth-x;
        cut=true;
    }
    if(pic.Height>ScreenHeight-y)
    {
        h=ScreenHeight-y;
        cut=true;
    }
    if(cut)
    {
        Rectangle srcRect=new Rectangle(0,0,w,h);
        bm=pic.ImageData.Clone(srcRect,pic.ImageData.PixelFormat);
    }
    description.Clear();
    description.SurfaceCaps.OffScreenPlain=true;
    Surface surface=new Surface(bm,description,display);

    if(pic.UseColorKey==false)
    {
        back.DrawFast(x,y,surface,DrawFastFlags.Wait);
    }
    else
    {
        ColorKey ck=new ColorKey();
        surface.SetColorKey(ColorKeyFlags.SourceDraw,ck);
        back.DrawFast(x,y,surface,DrawFastFlags.Wait|DrawFastFlags.SourceColorKey);
    }
    surface.Dispose();
}

    
11.设置前景色,字体 以及绘制字体
    
public Color ForeColor
{
    get{return back.ForeColor;}
    set{back.ForeColor=value;}
}
public Font Font
{
    set{back.FontHandle=value.ToHfont();}
}
public Color FontBackColor
{
    get{return back.FontBackColor;}
    set{back.FontBackColor=value;}
}
public bool FontTransparency
{
    get{return back.FontTransparency;}
    set{back.FontTransparency=value;}
}
public void DrawText(int x,int y,string text)
{
    back.DrawText(x,y,text,false);
}
    
12. 设置填充色, 以及清屏
public Color FillColor
{
    get{return back.FillColor;}
    set{back.FillColor=value;}
}

public void Clear(Color color)
{
    back.ColorFill(color);
}
13.绘制直线,矩形,圆角矩形,圆,椭圆
public int DrawWidth
{
    get{return back.DrawWidth;}
    set{back.DrawWidth=value;}
}
public int DrawStyle
{
    get{return back.DrawStyle;}
    set{back.DrawStyle=value;}
}
public int FillStyle
{
    get{return back.FillStyle;}
    set{back.FillStyle=value;}
}
public void DrawLine(int x1,int y1,int x2,int y2)
{
    back.DrawLine(x1,y1,x2,y2);
}
public void DrawBox( int left,int top,int right,int bottom)
{
    back.DrawBox(left,top,right,bottom);
}
public void DrawBox( int left,int top,int right,int bottom,int rw,int rh)
{
    back.DrawRoundedBox(left,top,right,bottom,rw,rh);
}
public void DrawCircle( int x,int y,int radius)
{
    back.DrawCircle(x,x,radius);
}
public void DrawEllipse(int x1,int y1,int x2,int y2)
{
    back.DrawEllipse(x1,y1,x2,y2);
}
14.主循环以及显示帧频
public void MainLoop()
{
    if(IsFullScreen)
    {
        int onesecond=10000000;
        long begin,end;
        begin=DateTime.Now.Ticks;
        int total=0;
        int count=0;
        while(this.Window.Created)
        {
            this.FullScreenDraw();
            Application.DoEvents();

            end=DateTime.Now.Ticks;
            total+=(int)(end-begin);
            count++;
            begin=end;
            if(total>onesecond)
            {
                FPS=onesecond/(total/count);//计算帧频
                total=0;
                count=0;
            }

        }
    }
    else
    {
    }
}
void FullScreenDraw()
{
    if (front == null)
    {
        return;
    }
    try
    {
        front.Flip(back, FlipFlags.Wait);
        this.OnDraw(this);
#if DEBUG
        this.FontTransparency=false;
        this.FontBackColor=Color.Black;
        this.ForeColor=Color.Green;
        this.DrawText(5,5,"FPS="+FPS.ToString());
        this.FontTransparency=true;
#endif
    }
    catch(WasStillDrawingException)
    {
        return;
    }
    catch(SurfaceLostException)
    {
        RestoreSurfaces();//恢复页面
    }
}
private void RestoreSurfaces()
{
    display.RestoreAllSurfaces();
    this.OnDraw(this);
    return;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值