|
- 1471
- 12099
- 版主
|
chenkwok
2006-03-19 17:12
| 只看楼主
收藏|
1
#
[讨论]WW中看大片,keyhole一定得看看
先看图此主题相关图片  怎么样够爽吧,一边玩WW,一边看影片---------这只是个试验品,不成熟,希望精c#的给完善一下 1.加上播放控制,这个应该不难  2.降低机能消耗,老蔡的机子也有点吃不消它  3.播放文件种类少  代码如下  br> //----------------------------------------------------------------------------
// NAME: Video Billboard plug-in
// VERSION: 1.0 (2006-03)
// DESCRIPTION: Play video/audio in the World Wind window
// DEVELOPER: mashi
// WEBSITE: http://www.godeyes.cn
// REFERENCES: Microsoft.DirectX.AudioVideoPlayback
//----------------------------------------------------------------------------
//
// This file is in the Public Domain, and comes with no warranty.
//
// NOTE: This file is probably only useful for developers since there still are issues to work out br> //
// - Eliminate texture copy in RenderVideo()
// - Make playback stable in all frame rates
//
using System;
using System.Diagnostics;
using System.Drawing;
using System.Windows.Forms;
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;
using WorldWind;
using WorldWind.Renderable;
using Microsoft.DirectX.AudioVideoPlayback;
using Direct3D=Microsoft.DirectX.Direct3D;
namespace WorldWind.Renderable
{
public class VideoBillBoardPlugin : WorldWind.PluginEngine.Plugin
{
Billboard bb;
/// <summary>
/// Plugin entry point - All plugins must implement this function
/// </summary>
public override void Load()
{
// Add us to the list of renderable objects - this puts us in the render loop
bb = new Billboard( "播放文件位置,仅支持Mediaplay的影片");
bb.Position = new Vector3(0.4f, -0.4f,0);
bb.Size = new SizeF( 1f, 0.9f );
Application.WorldWindow.CurrentWorld.RenderableObjects.Add(bb);
}
/// <summary>
/// Unloads our plugin
/// </summary>
public override void Unload()
{
Application.WorldWindow.CurrentWorld.RenderableObjects.Remove(bb.Name);
}
}
/// <summary>
/// A polygon that always faces the viewer. Also known as an impostor.
/// </summary>
public class Billboard : RenderableObject
{
bool autoSize;
string textureFilePath;
Texture texture;
SizeF size = new SizeF(1,1);
Rectangle bounds; // bounds in screen coordinates
int alpha = Color.FromArgb(215,0,0,0).ToArgb();
CustomVertex.TransformedColoredTextured[] verts = new CustomVertex.TransformedColoredTextured[4];
// The actual video itself
private Video videoTexture = null;
DrawArgs drawArgs;
string error;
/// <summary>
/// Constructor
/// </summary>
public Billboard(): base("Billboard", Vector3.Empty, Quaternion.Identity)
{
}
/// <summary>
/// Constructor
/// </summary>
/// <param name="textureFilename">Path/filename of billboard texture</param>
public Billboard(string textureFilename ): base("Billboard", Vector3.Empty, Quaternion.Identity)
{
this.textureFilePath = textureFilename;
RenderPriority = RenderPriority.Icons;
}
/// <summary>
/// Constructor
/// </summary>
/// <param name="position">Position in screen coordinates (pixels) - Z value unused</param>
/// <param name="textureFilename">Path/filename of billboard texture</param>
public Billboard( Vector3 position, string textureFilename ): base("Billboard", position, Quaternion.Identity)
{
this.textureFilePath = textureFilename;
}
/// <summary>
/// Billboard alpha (transparency) in the range 0-255
/// </summary>
public int Alpha
{
get { return alpha; }
set
{
if(value>0&value<255)
throw new ArgumentException("Alpha out of range.");
alpha = Color.FromArgb(value,0,0,0).ToArgb();
isInitialized = false;
}
}
/// <summary>
/// Size of the billboard in pixels.
/// </summary>
public SizeF Size
{
get { return size; }
set
{
if(AutoSize)
throw new ArgumentException("Billboard size can not be modified when AutoSize is enabled.");
size = value;
isInitialized = false;
}
}
/// <summary>
/// Resize billboard automatically to match the textures size
/// </summary>
public bool AutoSize
{
get { return autoSize; }
set
{
if(value==autoSize)
return;
autoSize = value;
isInitialized = false;
}
}
/// <summary>
/// Loads a new texture on the billboard.
/// </summary>
public void LoadTexture( string textureFilePath )
{
this.textureFilePath = textureFilePath;
Dispose();
}
public override void Initialize(DrawArgs drawArgs)
{
int xMid = drawArgs.screenWidth >> 1;
int yMid = drawArgs.screenHeight >> 1;
int halfWidth = (int)(xMid * (size.Width / 2));
int halfHeight = (int)(yMid * (size.Height / 2));
bounds = new Rectangle(
xMid + (int)(Position.X*xMid) - halfWidth,
yMid + (int)(Position.Y*yMid) - halfHeight,
2*halfWidth,
2*halfHeight);
verts[2].X = bounds.Left;
verts[2].Y = bounds.Top;
verts[2].Tu = 0;
verts[2].Tv = 0;
verts[2].Color = alpha;
verts[0].X = bounds.Left;
verts[0].Y = bounds.Bottom;
verts[0].Tu = 0;
verts[0].Tv = 1;
verts[0].Color = alpha;
verts[3].X = bounds.Right;
verts[3].Y = bounds.Top;
verts[3].Tu = 1;
verts[3].Tv = 0;
verts[3].Color = alpha;
verts[1].X = bounds.Right;
verts[1].Y = bounds.Bottom;
verts[1].Tu = 1;
verts[1].Tv = 1;
verts[1].Color = alpha;
this.drawArgs = drawArgs;
isInitialized = true;
if(textureFilePath!=null)
{
try
{
videoTexture = Video.FromFile(textureFilePath);
// TODO: Why isn't this working?
videoTexture.Ending += new EventHandler(MovieOver);
videoTexture.TextureReadyToRender += new TextureRenderEventHandler(RenderVideo);
// Now start rendering to our texture
videoTexture.RenderToTexture(drawArgs.device);
}
catch(Exception err)
{
error = string.Format("An error has occurred that will not allow this sample to continue.\r\nException={0}", err.ToString());
}
}
}
public override void Dispose()
{
isInitialized = false;
if(videoTexture!=null)
{
if(!videoTexture.Audio.Disposed)
{
videoTexture.Audio.Dispose();
}
if(!videoTexture.Disposed)
{
videoTexture.Stop();
// videoTexture.Dispose();
}
videoTexture = null;
}
if(texture != null)
{
texture.Dispose();
texture = null;
}
}
public override bool PerformSelectionAction(DrawArgs drawArgs)
{
return false;
}
public override void Update(DrawArgs drawArgs)
{
if(!this.isInitialized)
this.Initialize(drawArgs);
}
public override void Render(DrawArgs drawArgs)
{
if(error!=null)
{
MessageBox.Show(error);
error = null;
}
if(!isInitialized)
return;
if(texture==null)
return;
Device device = drawArgs.device;
device.SetTexture(0, texture);
device.TextureState[0].AlphaOperation = TextureOperation.Modulate;
device.TextureState[0].ColorOperation = TextureOperation.Add;
device.VertexFormat = CustomVertex.TransformedColoredTextured.Format;
device.DrawUserPrimitives(PrimitiveType.TriangleStrip, 2, verts);
}
public void RenderVideo(object sender, TextureRenderEventArgs e)
{
if(e.Texture==null)
return;
// TODO: Figure out how to avoid copying surfaces
using(Surface s = e.Texture.GetSurfaceLevel(0))
{
if(texture==null)
{
texture = new Texture(drawArgs.device, s.Description.Width,s.Description.Height,
1,s.Description.Usage, s.Description.Format, s.Description.Pool);
}
using(Surface d = texture.GetSurfaceLevel(0))
{
SurfaceLoader.FromSurface(d, s, Filter.Linear, unchecked((int)0xffffffff));
}
}
}
/// <summary>
/// Movie playback has ended
/// </summary>
void MovieOver(object sender, EventArgs e)
{
Dispose();
}
}
}
|
|