diff --git a/MoonWorks.Test.Common/Content/Videos/hello.ogv b/MoonWorks.Test.Common/Content/Videos/hello.ogv new file mode 100644 index 0000000..52f9b2a Binary files /dev/null and b/MoonWorks.Test.Common/Content/Videos/hello.ogv differ diff --git a/MoonWorks.Test.Common/TestUtils.cs b/MoonWorks.Test.Common/TestUtils.cs index e1b931e..f190a0d 100644 --- a/MoonWorks.Test.Common/TestUtils.cs +++ b/MoonWorks.Test.Common/TestUtils.cs @@ -56,6 +56,11 @@ namespace MoonWorks.Test return SDL2.SDL.SDL_GetBasePath() + "Content/Textures/" + textureName; } + public static string GetVideoPath(string videoName) + { + return SDL2.SDL.SDL_GetBasePath() + "Content/Videos/" + videoName; + } + public enum ButtonType { Left, // A/left arrow on keyboard, left face button on gamepad diff --git a/MoonWorksGraphicsTests.sln b/MoonWorksGraphicsTests.sln index 3dac47a..c7facaf 100644 --- a/MoonWorksGraphicsTests.sln +++ b/MoonWorksGraphicsTests.sln @@ -35,7 +35,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DrawIndirect", "DrawIndirec EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CompressedTextures", "CompressedTextures\CompressedTextures.csproj", "{E90D236C-BD0F-4420-ADD0-867D21F4DCA5}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CopyTexture", "CopyTexture\CopyTexture.csproj", "{CF25A5A2-A0BD-4C9B-BB07-19CCD97C1C4E}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CopyTexture", "CopyTexture\CopyTexture.csproj", "{CF25A5A2-A0BD-4C9B-BB07-19CCD97C1C4E}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VideoPlayer", "VideoPlayer\VideoPlayer.csproj", "{FCD63849-9D3C-4D48-A8BD-39671096F03A}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -111,6 +113,10 @@ Global {CF25A5A2-A0BD-4C9B-BB07-19CCD97C1C4E}.Debug|x64.Build.0 = Debug|x64 {CF25A5A2-A0BD-4C9B-BB07-19CCD97C1C4E}.Release|x64.ActiveCfg = Release|Any CPU {CF25A5A2-A0BD-4C9B-BB07-19CCD97C1C4E}.Release|x64.Build.0 = Release|Any CPU + {FCD63849-9D3C-4D48-A8BD-39671096F03A}.Debug|x64.ActiveCfg = Debug|x64 + {FCD63849-9D3C-4D48-A8BD-39671096F03A}.Debug|x64.Build.0 = Debug|x64 + {FCD63849-9D3C-4D48-A8BD-39671096F03A}.Release|x64.ActiveCfg = Release|Any CPU + {FCD63849-9D3C-4D48-A8BD-39671096F03A}.Release|x64.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/README.md b/README.md index b52b1e3..e690318 100644 --- a/README.md +++ b/README.md @@ -59,3 +59,7 @@ Loads a series of compressed textures, then displays them for viewing. Tests com **CopyTexture** Loads an image, then makes three copies of the image. One is a 1:1 scale image, another is a half-sized image (to test linear/nearest blitting), and the final copy is to a buffer. The buffer bytes are then compared with the original texture bytes to verify the copy's correctness. Tests CopyTextureToTexture, CopyTextureToBuffer, vertex offsets, and index offsets. + +**VideoPlayer** + +Plays a sample Ogg Theora video file. Tests YUV textures and video rendering. diff --git a/VideoPlayer/VideoPlayer.csproj b/VideoPlayer/VideoPlayer.csproj new file mode 100644 index 0000000..2868e63 --- /dev/null +++ b/VideoPlayer/VideoPlayer.csproj @@ -0,0 +1,17 @@ + + + + + + + + + Exe + net7.0 + enable + x64 + + + + + diff --git a/VideoPlayer/VideoPlayerGame.cs b/VideoPlayer/VideoPlayerGame.cs new file mode 100644 index 0000000..81b1c82 --- /dev/null +++ b/VideoPlayer/VideoPlayerGame.cs @@ -0,0 +1,99 @@ +using MoonWorks.Math.Float; +using MoonWorks.Graphics; +using MoonWorks.Video; + +namespace MoonWorks.Test +{ + class VideoPlayerGame : Game + { + private GraphicsPipeline pipeline; + private Sampler sampler; + private Buffer vertexBuffer; + private Buffer indexBuffer; + + private Video.Video video; + private VideoPlayer videoPlayer; + + public VideoPlayerGame() : base(TestUtils.GetStandardWindowCreateInfo(), TestUtils.GetStandardFrameLimiterSettings(), 60, true) + { + // Load the shaders + ShaderModule vertShaderModule = new ShaderModule(GraphicsDevice, TestUtils.GetShaderPath("TexturedQuadVert")); + ShaderModule fragShaderModule = new ShaderModule(GraphicsDevice, TestUtils.GetShaderPath("TexturedQuadFrag")); + + // Create the graphics pipeline + GraphicsPipelineCreateInfo pipelineCreateInfo = TestUtils.GetStandardGraphicsPipelineCreateInfo( + MainWindow.SwapchainFormat, + vertShaderModule, + fragShaderModule + ); + pipelineCreateInfo.VertexInputState = VertexInputState.CreateSingleBinding(); + pipelineCreateInfo.FragmentShaderInfo.SamplerBindingCount = 1; + pipeline = new GraphicsPipeline(GraphicsDevice, pipelineCreateInfo); + + // Create the sampler + sampler = new Sampler(GraphicsDevice, SamplerCreateInfo.LinearClamp); + + // Create and populate the GPU resources + vertexBuffer = Buffer.Create(GraphicsDevice, BufferUsageFlags.Vertex, 4); + indexBuffer = Buffer.Create(GraphicsDevice, BufferUsageFlags.Index, 6); + + CommandBuffer cmdbuf = GraphicsDevice.AcquireCommandBuffer(); + cmdbuf.SetBufferData( + vertexBuffer, + new PositionTextureVertex[] + { + new PositionTextureVertex(new Vector3(-1, -1, 0), new Vector2(0, 0)), + new PositionTextureVertex(new Vector3(1, -1, 0), new Vector2(1, 0)), + new PositionTextureVertex(new Vector3(1, 1, 0), new Vector2(1, 1)), + new PositionTextureVertex(new Vector3(-1, 1, 0), new Vector2(0, 1)), + } + ); + cmdbuf.SetBufferData( + indexBuffer, + new ushort[] + { + 0, 1, 2, + 0, 2, 3, + } + ); + GraphicsDevice.Submit(cmdbuf); + GraphicsDevice.Wait(); + + // Load the video + video = new Video.Video(TestUtils.GetVideoPath("hello.ogv")); + + // Play the video + videoPlayer = new VideoPlayer(GraphicsDevice, AudioDevice); + videoPlayer.Load(video); + videoPlayer.Play(); + } + + protected override void Update(System.TimeSpan delta) + { + videoPlayer.Render(); + } + + protected override void Draw(double alpha) + { + CommandBuffer cmdbuf = GraphicsDevice.AcquireCommandBuffer(); + Texture? backbuffer = cmdbuf.AcquireSwapchainTexture(MainWindow); + if (backbuffer != null) + { + cmdbuf.BeginRenderPass(new ColorAttachmentInfo(backbuffer, Color.CornflowerBlue)); + cmdbuf.BindGraphicsPipeline(pipeline); + cmdbuf.BindVertexBuffers(vertexBuffer); + cmdbuf.BindIndexBuffer(indexBuffer, IndexElementSize.Sixteen); + cmdbuf.BindFragmentSamplers(new TextureSamplerBinding(videoPlayer.RenderTexture, sampler)); + cmdbuf.DrawIndexedPrimitives(0, 0, 2, 0, 0); + cmdbuf.EndRenderPass(); + } + GraphicsDevice.Submit(cmdbuf); + } + + public static void Main(string[] args) + { + VideoPlayerGame game = new VideoPlayerGame(); + game.Run(); + } + } +}