static void RenderThread(Sample sample) { // initialize the renderer Bgfx.Init(); Bgfx.Reset(sample.WindowWidth, sample.WindowHeight, ResetFlags.Vsync); // enable debug text Bgfx.SetDebugFeatures(DebugFeatures.DisplayText); // set view 0 clear state Bgfx.SetViewClear(0, ClearTargets.Color | ClearTargets.Depth, 0x303030ff); // main loop while (sample.ProcessEvents(ResetFlags.Vsync)) { // set view 0 viewport Bgfx.SetViewRect(0, 0, 0, sample.WindowWidth, sample.WindowHeight); // make sure view 0 is cleared if no other draw calls are submitted Bgfx.Touch(0); // write some debug text Bgfx.DebugTextClear(); Bgfx.DebugTextWrite(0, 1, DebugColor.White, DebugColor.Blue, "SharpBgfx/Samples/00-HelloWorld"); Bgfx.DebugTextWrite(0, 2, DebugColor.White, DebugColor.Cyan, "Description: Initialization and debug text."); // advance to the next frame. Rendering thread will be kicked to // process submitted rendering primitives. Bgfx.Frame(); } // clean up Bgfx.Shutdown(); }
public static int Main(string[] args) { if (GLFW.Init() == 0) { return(-1); } GLFW.WindowHint(GLFW.CLIENT_API, GLFW.NO_API); string title = $"GLFW & SharpBgfx"; IntPtr window = GLFW.CreateWindow(640, 480, title, IntPtr.Zero, IntPtr.Zero); if (window == IntPtr.Zero) { GLFW.Terminate(); return(-1); } Bgfx.SetPlatformData(new PlatformData() { WindowHandle = GetWin32Window(window) }); Bgfx.Init(); Bgfx.Reset(640, 480, ResetFlags.Vsync); Bgfx.SetDebugFeatures(DebugFeatures.DisplayText); Bgfx.SetViewClear(0, ClearTargets.Color | ClearTargets.Depth, 0x303030ff); while (GLFW.WindowShouldClose(window) == 0) { GLFW.PollEvents(); Bgfx.Touch(0); // write some debug text Bgfx.DebugTextClear(); Bgfx.DebugTextWrite(0, 1, DebugColor.White, DebugColor.Blue, "GLFWDotNet & SharpBgfx"); Bgfx.DebugTextWrite(0, 2, DebugColor.White, DebugColor.Cyan, "Description: Initialization and debug text."); // advance to the next frame. Rendering thread will be kicked to // process submitted rendering primitives. Bgfx.Frame(); GLFW.SwapBuffers(window); } Bgfx.Shutdown(); GLFW.Terminate(); return(0); }
static void RunUnsupported(Sample sample) { // main loop while (sample.ProcessEvents(ResetFlags.Vsync)) { Bgfx.SetViewRect(0, 0, 0, sample.WindowWidth, sample.WindowHeight); Bgfx.DebugTextClear(); Bgfx.DebugTextWrite(0, 1, DebugColor.White, DebugColor.Blue, "SharpBgfx/Samples/24-NBody"); Bgfx.DebugTextWrite(0, 2, DebugColor.White, DebugColor.Cyan, "Description: N-body simulation with compute shaders using buffers."); Bgfx.DebugTextWrite(0, 5, DebugColor.White, DebugColor.Red, "Compute is not supported by your GPU."); Bgfx.Touch(0); Bgfx.Frame(); } }
static unsafe void RenderThread(Sample sample) { // initialize the renderer Bgfx.Init(); Bgfx.Reset(sample.WindowWidth, sample.WindowHeight, ResetFlags.Vsync); // enable debug text Bgfx.SetDebugFeatures(DebugFeatures.DisplayText); // load shaders var programTextureLighting = ResourceLoader.LoadProgram("vs_stencil_texture_lighting", "fs_stencil_texture_lighting"); var programColorLighting = ResourceLoader.LoadProgram("vs_stencil_color_lighting", "fs_stencil_color_lighting"); var programColorTexture = ResourceLoader.LoadProgram("vs_stencil_color_texture", "fs_stencil_color_texture"); var programColorBlack = ResourceLoader.LoadProgram("vs_stencil_color", "fs_stencil_color_black"); var programTexture = ResourceLoader.LoadProgram("vs_stencil_texture", "fs_stencil_texture"); // load meshes var bunnyMesh = ResourceLoader.LoadMesh("bunny.bin"); var columnMesh = ResourceLoader.LoadMesh("column.bin"); var hplaneMesh = new Mesh(MemoryBlock.FromArray(StaticMeshes.HorizontalPlane), PosNormalTexcoordVertex.Layout, StaticMeshes.PlaneIndices); var vplaneMesh = new Mesh(MemoryBlock.FromArray(StaticMeshes.VerticalPlane), PosNormalTexcoordVertex.Layout, StaticMeshes.PlaneIndices); // load textures var figureTex = ResourceLoader.LoadTexture("figure-rgba.dds"); var flareTex = ResourceLoader.LoadTexture("flare.dds"); var fieldstoneTex = ResourceLoader.LoadTexture("fieldstone-rgba.dds"); // create uniforms var colorTextureHandle = new Uniform("u_texColor", UniformType.Sampler); var uniforms = new Uniforms(); uniforms.SubmitConstUniforms(); // light colors uniforms.LightColor = new[] { new Vector4(1.0f, 0.7f, 0.2f, 0.0f), // yellow new Vector4(0.7f, 0.2f, 1.0f, 0.0f), // purple new Vector4(0.2f, 1.0f, 0.7f, 0.0f), // cyan new Vector4(1.0f, 0.4f, 0.2f, 0.0f) // orange }; // camera var camera = new Camera(60.0f, sample.WindowWidth, sample.WindowHeight, 0.1f, 100.0f); camera.Position = new Vector3(0.0f, 18.0f, -40.0f); // start the frame clock var clock = new Clock(); clock.Start(); // check caps and stats, for testing purposes Bgfx.GetCaps(); Bgfx.GetStats(); // main loop while (sample.ProcessEvents(ResetFlags.Vsync)) { // tick the clock var elapsed = clock.Frame(); var time = clock.TotalTime(); // write some debug text Bgfx.DebugTextClear(); Bgfx.DebugTextWrite(0, 1, DebugColor.White, DebugColor.Blue, "SharpBgfx/Samples/13-Stencil"); Bgfx.DebugTextWrite(0, 2, DebugColor.White, DebugColor.Cyan, "Description: Stencil reflections."); Bgfx.DebugTextWrite(0, 3, DebugColor.White, DebugColor.Cyan, "Frame: {0:F3} ms", elapsed * 1000); // clear the background Bgfx.SetViewClear(BaseId, ClearTargets.Color | ClearTargets.Depth | ClearTargets.Stencil, 0x30303000); Bgfx.SetViewRect(BaseId, 0, 0, sample.WindowWidth, sample.WindowHeight); Bgfx.Touch(BaseId); // set view params for each pass var viewMtx = camera.GetViewMatrix(); var projMtx = camera.GetProjectionMatrix(); for (byte i = PassId0; i <= PassId4; i++) { Bgfx.SetViewRect(i, 0, 0, sample.WindowWidth, sample.WindowHeight); Bgfx.SetViewTransform(i, (float *)&viewMtx, (float *)&projMtx); } // first pass - draw ground plane var floorMtx = FloorTransform; hplaneMesh.Submit(PassId0, programColorBlack, &floorMtx, StateGroups[PrebuiltRenderState.StencilReflectionCraftStencil], uniforms); // second pass - reflected objects Bgfx.SetViewClear(PassId1, ClearTargets.Depth, 0); uniforms.AmbientPass = true; uniforms.LightingPass = true; uniforms.Color = new Vector4(0.70f, 0.65f, 0.60f, 0.8f); uniforms.LightCount = LightCount; // light positions var lightPositions = new Vector4[LightCount]; var reflectedLights = new Vector4[LightCount]; for (int i = 0; i < lightPositions.Length; i++) { var v3 = new Vector3( (float)Math.Sin(time * 1.1 + i * 0.03 + i * 1.07 * Math.PI / 2) * 20.0f, 8.0f + (1.0f - (float)Math.Cos(time * 1.5 + i * 0.29 + 1.49f * Math.PI / 2)) * 4.0f, (float)Math.Cos(time * 1.3 + i * 0.13 + i * 1.79 * Math.PI / 2) * 20.0f ); lightPositions[i] = new Vector4(v3, 15.0f); reflectedLights[i] = new Vector4(Vector3.Transform(v3, ReflectionTransform), 15.0f); } uniforms.LightPosRadius = reflectedLights; var bunnyMtx = Matrix4x4.CreateScale(5) * Matrix4x4.CreateRotationY(time - 1.56f) * Matrix4x4.CreateTranslation(0.0f, 2.0f, 0.0f); var reflectedBunnyMtx = bunnyMtx * ReflectionTransform; bunnyMesh.Submit(PassId1, programColorLighting, &reflectedBunnyMtx, StateGroups[PrebuiltRenderState.StencilReflectionDrawReflected], uniforms); for (int i = 0; i < 4; i++) { var mtx = ColumnTransforms[i] * ReflectionTransform; columnMesh.Submit(PassId1, programColorLighting, &mtx, StateGroups[PrebuiltRenderState.StencilReflectionDrawReflected], uniforms); } // third pass - blend the plane and reflections uniforms.LightPosRadius = lightPositions; hplaneMesh.Submit(PassId2, programTextureLighting, &floorMtx, StateGroups[PrebuiltRenderState.StencilReflectionBlendPlane], uniforms, fieldstoneTex, colorTextureHandle); // fourth pass - draw the solid objects bunnyMesh.Submit(PassId3, programColorLighting, &bunnyMtx, StateGroups[PrebuiltRenderState.StencilReflectionDrawScene], uniforms); for (int i = 0; i < 4; i++) { var mtx = ColumnTransforms[i]; columnMesh.Submit(PassId3, programColorLighting, &mtx, StateGroups[PrebuiltRenderState.StencilReflectionDrawScene], uniforms); } // fifth pass - draw the lights as objects for (int i = 0; i < LightCount; i++) { var c = uniforms.LightColor[i]; uniforms.Color = new Vector4(c.X, c.Y, c.Z, 0.8f); var p = lightPositions[i]; var mtx = Matrix4x4.CreateScale(1.5f) * Matrix4x4.CreateBillboard(new Vector3(p.X, p.Y, p.Z), camera.Position, Vector3.UnitY, -Vector3.UnitZ); vplaneMesh.Submit(PassId4, programColorTexture, &mtx, StateGroups[PrebuiltRenderState.CustomBlendLightTexture], uniforms, flareTex, colorTextureHandle); } // advance to the next frame. Rendering thread will be kicked to // process submitted rendering primitives. Bgfx.Frame(); } // clean up bunnyMesh.Dispose(); columnMesh.Dispose(); hplaneMesh.Dispose(); vplaneMesh.Dispose(); figureTex.Dispose(); fieldstoneTex.Dispose(); flareTex.Dispose(); programTextureLighting.Dispose(); programColorLighting.Dispose(); programColorTexture.Dispose(); programColorBlack.Dispose(); programTexture.Dispose(); colorTextureHandle.Dispose(); uniforms.Dispose(); Bgfx.Shutdown(); }
static unsafe void RunCompute(Sample sample, bool indirectSupported) { // build vertex layouts var quadLayout = new VertexLayout(); quadLayout.Begin() .Add(VertexAttributeUsage.Position, 2, VertexAttributeType.Float) .End(); var computeLayout = new VertexLayout(); computeLayout.Begin() .Add(VertexAttributeUsage.TexCoord0, 4, VertexAttributeType.Float) .End(); // static quad data var vb = new VertexBuffer(MemoryBlock.FromArray(QuadVertices), quadLayout); var ib = new IndexBuffer(MemoryBlock.FromArray(QuadIndices)); // create compute buffers var currPositionBuffer0 = new DynamicVertexBuffer(1 << 15, computeLayout, BufferFlags.ComputeReadWrite); var currPositionBuffer1 = new DynamicVertexBuffer(1 << 15, computeLayout, BufferFlags.ComputeReadWrite); var prevPositionBuffer0 = new DynamicVertexBuffer(1 << 15, computeLayout, BufferFlags.ComputeReadWrite); var prevPositionBuffer1 = new DynamicVertexBuffer(1 << 15, computeLayout, BufferFlags.ComputeReadWrite); // load shaders var particleProgram = ResourceLoader.LoadProgram("vs_particle", "fs_particle"); var initInstancesProgram = ResourceLoader.LoadProgram("cs_init_instances"); var updateInstancesProgram = ResourceLoader.LoadProgram("cs_update_instances"); // indirect rendering support var indirectProgram = SharpBgfx.Program.Invalid; var indirectBuffer = IndirectBuffer.Invalid; bool useIndirect = false; if (indirectSupported) { indirectProgram = ResourceLoader.LoadProgram("cs_indirect"); indirectBuffer = new IndirectBuffer(2); useIndirect = true; } // setup params uniforms var paramData = new ParamsData { TimeStep = 0.0157f, DispatchSize = 32, Gravity = 0.109f, Damping = 0.25f, ParticleIntensity = 0.64f, ParticleSize = 0.279f, BaseSeed = 57, ParticlePower = 3.5f, InitialSpeed = 3.2f, InitialShape = 1, MaxAccel = 100.0f }; // have the compute shader run initialization var u_params = new Uniform("u_params", UniformType.Vector4, 3); Bgfx.SetUniform(u_params, ¶mData, 3); Bgfx.SetComputeBuffer(0, prevPositionBuffer0, ComputeBufferAccess.Write); Bgfx.SetComputeBuffer(1, currPositionBuffer0, ComputeBufferAccess.Write); Bgfx.Dispatch(0, initInstancesProgram, MaxParticleCount / ThreadGroupUpdateSize); // start the frame clock var clock = new Clock(); clock.Start(); // main loop while (sample.ProcessEvents(ResetFlags.Vsync)) { // tick the clock var elapsed = clock.Frame(); var time = clock.TotalTime(); // write some debug text Bgfx.DebugTextClear(); Bgfx.DebugTextWrite(0, 1, DebugColor.White, DebugColor.Blue, "SharpBgfx/Samples/24-NBody"); Bgfx.DebugTextWrite(0, 2, DebugColor.White, DebugColor.Cyan, "Description: N-body simulation with compute shaders using buffers."); Bgfx.DebugTextWrite(0, 3, DebugColor.White, DebugColor.Cyan, "Frame: {0:F3} ms", elapsed * 1000); // fill the indirect buffer if we're using it if (useIndirect) { Bgfx.SetUniform(u_params, ¶mData, 3); Bgfx.SetComputeBuffer(0, indirectBuffer, ComputeBufferAccess.Write); Bgfx.Dispatch(0, indirectProgram); } // update particle positions Bgfx.SetComputeBuffer(0, prevPositionBuffer0, ComputeBufferAccess.Read); Bgfx.SetComputeBuffer(1, currPositionBuffer0, ComputeBufferAccess.Read); Bgfx.SetComputeBuffer(2, prevPositionBuffer1, ComputeBufferAccess.Write); Bgfx.SetComputeBuffer(3, currPositionBuffer1, ComputeBufferAccess.Write); Bgfx.SetUniform(u_params, ¶mData, 3); if (useIndirect) { Bgfx.Dispatch(0, updateInstancesProgram, indirectBuffer, 1); } else { Bgfx.Dispatch(0, updateInstancesProgram, paramData.DispatchSize); } // ping-pong the buffers for next frame Swap(ref currPositionBuffer0, ref currPositionBuffer1); Swap(ref prevPositionBuffer0, ref prevPositionBuffer1); // view transforms for particle rendering var viewMatrix = Matrix4x4.CreateLookAt(new Vector3(0.0f, 0.0f, -45.0f), -Vector3.UnitZ, Vector3.UnitY); var projMatrix = Matrix4x4.CreatePerspectiveFieldOfView((float)Math.PI / 4, (float)sample.WindowWidth / sample.WindowHeight, 0.1f, 10000.0f); Bgfx.SetViewTransform(0, &viewMatrix.M11, &projMatrix.M11); Bgfx.SetViewRect(0, 0, 0, sample.WindowWidth, sample.WindowHeight); // draw the particles Bgfx.SetVertexBuffer(vb); Bgfx.SetIndexBuffer(ib); Bgfx.SetInstanceDataBuffer(currPositionBuffer0, 0, paramData.DispatchSize * ThreadGroupUpdateSize); Bgfx.SetRenderState(RenderState.ColorWrite | RenderState.BlendAdd | RenderState.DepthTestAlways); if (useIndirect) { Bgfx.Submit(0, particleProgram, indirectBuffer); } else { Bgfx.Submit(0, particleProgram); } // done with frame Bgfx.Frame(); } // cleanup if (indirectSupported) { indirectProgram.Dispose(); indirectBuffer.Dispose(); } u_params.Dispose(); currPositionBuffer0.Dispose(); currPositionBuffer1.Dispose(); prevPositionBuffer0.Dispose(); prevPositionBuffer1.Dispose(); updateInstancesProgram.Dispose(); initInstancesProgram.Dispose(); particleProgram.Dispose(); ib.Dispose(); vb.Dispose(); }
static unsafe void RenderThread(Sample sample) { // initialize the renderer Bgfx.Init(); Bgfx.Reset(sample.WindowWidth, sample.WindowHeight, ResetFlags.None); // enable debug text Bgfx.SetDebugFeatures(DebugFeatures.DisplayText); // set view 0 clear state Bgfx.SetViewClear(0, ClearTargets.Color | ClearTargets.Depth, 0x303030ff); // create vertex and index buffers var vbh = Cube.CreateVertexBuffer(); var ibh = Cube.CreateIndexBuffer(); // load shaders var program = ResourceLoader.LoadProgram("vs_cubes", "fs_cubes"); // start the frame clock var clock = new Clock(); clock.Start(); int cubeDim = 15; float lastUpdate = 0.0f; int frameCount = 0; // main loop while (sample.ProcessEvents(ResetFlags.None)) { // set view 0 viewport Bgfx.SetViewRect(0, 0, 0, sample.WindowWidth, sample.WindowHeight); // view transforms var viewMatrix = Matrix4x4.CreateLookAt(new Vector3(0.0f, 0.0f, -35.0f), Vector3.Zero, Vector3.UnitY); var projMatrix = Matrix4x4.CreatePerspectiveFieldOfView((float)Math.PI / 3, (float)sample.WindowWidth / sample.WindowHeight, 0.1f, 100.0f); Bgfx.SetViewTransform(0, &viewMatrix.M11, &projMatrix.M11); // make sure view 0 is cleared if no other draw calls are submitted Bgfx.Touch(0); // tick the clock var elapsed = clock.Frame(); var time = clock.TotalTime(); if (elapsed > 10) { elapsed = 0; } frameCount++; lastUpdate += elapsed; if (lastUpdate > 1.0f) { var avgFrameTime = frameCount / lastUpdate; if (avgFrameTime > HighThreshold) { cubeDim = Math.Min(cubeDim + 2, 40); } else if (avgFrameTime < LowThreshold) { cubeDim = Math.Max(cubeDim - 1, 2); } frameCount = 0; lastUpdate = 0; } var initial = new Vector3( -Step * cubeDim / 2.0f, -Step * cubeDim / 2.0f, -15.0f ); // write some debug text Bgfx.DebugTextClear(); Bgfx.DebugTextWrite(0, 1, DebugColor.White, DebugColor.Blue, "Description: CPU/driver stress test, maximizing draw calls."); Bgfx.DebugTextWrite(0, 2, DebugColor.White, DebugColor.Cyan, "Draw Calls: {0}", cubeDim * cubeDim * cubeDim); Bgfx.DebugTextWrite(0, 3, DebugColor.White, DebugColor.Cyan, "Frame: {0:F3} ms", elapsed * 1000); for (int z = 0; z < cubeDim; z++) { for (int y = 0; y < cubeDim; y++) { for (int x = 0; x < cubeDim; x++) { // model matrix var transform = Matrix4x4.CreateFromYawPitchRoll(time + x * 0.21f, time + y * 0.37f, time + y * 0.13f); transform = Matrix4x4.CreateScale(Scale) * transform; transform.M41 = initial.X + x * Step; transform.M42 = initial.Y + y * Step; transform.M43 = initial.Z + z * Step; Bgfx.SetTransform(&transform.M11); // set pipeline states Bgfx.SetVertexBuffer(0, vbh); Bgfx.SetIndexBuffer(ibh); Bgfx.SetRenderState(RenderState.Default); // submit primitives Bgfx.Submit(0, program); } } } // advance to the next frame. Rendering thread will be kicked to // process submitted rendering primitives. Bgfx.Frame(); } // clean up ibh.Dispose(); vbh.Dispose(); program.Dispose(); Bgfx.Shutdown(); }
unsafe static void Main(string[] args) { int width = 640; int height = 480; var renderer = new Renderer(); renderer.CreateSDL(width, height, string.Format("OpenLSR v{0}", Assembly.GetEntryAssembly().GetName().Version.ToString())); var wmi = new SDL_SysWMinfo(); SDL_VERSION(out wmi.version); SDL_GetWindowWMInfo(renderer.window, ref wmi); var pd = new PlatformData(); pd.WindowHandle = wmi.info.win.window; var init = new InitSettings(); init.PlatformData = pd; Bgfx.Init(init); Bgfx.Reset(width, height, ResetFlags.Vsync); SDL_ShowWindow(renderer.window); // enable debug text Bgfx.SetDebugFeatures(DebugFeatures.DisplayText); // set view 0 clear state Bgfx.SetViewClear(0, ClearTargets.Color | ClearTargets.Depth, 0x303030ff); bool quit = false; SDL_Event Event; // start the frame clock var clock = new GameClock(); clock.Start(); // main loop while (!quit) { while (SDL_PollEvent(out Event) != 0) { switch (Event.type) { case SDL_EventType.SDL_QUIT: quit = true; break; default: break; } } // set view 0 viewport Bgfx.SetViewRect(0, 0, 0, width, height); // make sure view 0 is cleared if no other draw calls are submitted Bgfx.Touch(0); // tick the clock var elapsed = clock.Frame(); var time = clock.TotalTime(); // write some debug text Bgfx.DebugTextClear(); Bgfx.DebugTextWrite(0, 1, DebugColor.White, DebugColor.Magenta, "OpenLSR Test"); Bgfx.DebugTextWrite(0, 2, DebugColor.White, DebugColor.Magenta, "Frame: {0:F3} ms", elapsed * 1000); // advance to the next frame. Rendering thread will be kicked to // process submitted rendering primitives. Bgfx.Frame(); } // clean up Bgfx.Shutdown(); SDL_DestroyRenderer(renderer.renderer); SDL_DestroyWindow(renderer.window); SDL_Quit(); }
static unsafe void RenderThread(Sample sample) { // initialize the renderer Bgfx.Init(); Bgfx.Reset(sample.WindowWidth, sample.WindowHeight, ResetFlags.Vsync); // enable debug text Bgfx.SetDebugFeatures(DebugFeatures.DisplayText); // set view 0 clear state Bgfx.SetViewClear(0, ClearTargets.Color | ClearTargets.Depth, 0x303030ff); // create vertex and index buffers var vbh = Cube.CreateVertexBuffer(); var ibh = Cube.CreateIndexBuffer(); // load shaders var program = ResourceLoader.LoadProgram("vs_cubes", "fs_cubes"); // start the frame clock var clock = new Clock(); clock.Start(); var imguiController = new ImGuiController(1); var image = imguiController.AddTexture(ResourceLoader.LoadTexture("fieldstone-rgba.dds")); // main loop while (sample.ProcessEvents(ResetFlags.Vsync)) { // set view 0 viewport Bgfx.SetViewRect(0, 0, 0, sample.WindowWidth, sample.WindowHeight); // view transforms var viewMatrix = Matrix4x4.CreateLookAt(new Vector3(0.0f, 0.0f, -35.0f), Vector3.Zero, Vector3.UnitY); var projMatrix = Matrix4x4.CreatePerspectiveFieldOfView((float)Math.PI / 3, (float)sample.WindowWidth / sample.WindowHeight, 0.1f, 100.0f); Bgfx.SetViewTransform(0, &viewMatrix.M11, &projMatrix.M11); // make sure view 0 is cleared if no other draw calls are submitted Bgfx.Touch(0); // tick the clock var elapsed = clock.Frame(); var time = clock.TotalTime(); // write some debug text Bgfx.DebugTextClear(); Bgfx.DebugTextWrite(0, 1, DebugColor.White, DebugColor.Blue, "SharpBgfx/Samples/ImGui"); Bgfx.DebugTextWrite(0, 2, DebugColor.White, DebugColor.Cyan, "Description: Rendering simple static mesh."); Bgfx.DebugTextWrite(0, 3, DebugColor.White, DebugColor.Cyan, "Frame: {0:F3} ms", elapsed * 1000); // submit 11x11 cubes for (int y = 0; y < 11; y++) { for (int x = 0; x < 11; x++) { // model matrix var transform = Matrix4x4.CreateFromYawPitchRoll(time + x * 0.21f, time + y * 0.37f, 0.0f); transform.M41 = -15.0f + x * 3.0f; transform.M42 = -15.0f + y * 3.0f; transform.M43 = 0.0f; Bgfx.SetTransform(&transform.M11); // set pipeline states Bgfx.SetVertexBuffer(0, vbh); Bgfx.SetIndexBuffer(ibh); Bgfx.SetRenderState(RenderState.Default); // submit primitives Bgfx.Submit(0, program); } } imguiController.StartFrame(); ImGui.ShowDemoWindow(); ImGui.SetNextWindowPos(new Vector2(100, 100)); ImGui.SetNextWindowSize(new Vector2(400, 400)); ImGui.Begin("Drawing an image"); ImGui.Image(image, new Vector2(((float)Math.Sin(clock.TotalTime()) + 1) * 200, ((float)Math.Sin(clock.TotalTime()) + 1) * 200)); ImGui.End(); imguiController.EndFrame(elapsed, new Vector2(sample.WindowWidth, sample.WindowHeight)); // advance to the next frame. Rendering thread will be kicked to // process submitted rendering primitives. Bgfx.Frame(); } // clean up ibh.Dispose(); vbh.Dispose(); program.Dispose(); Bgfx.Shutdown(); }
static unsafe void RenderThread(Sample sample) { // initialize the renderer Bgfx.Init(RendererBackend.OpenGL, callbackHandler: new CallbackHandler()); Bgfx.Reset(sample.WindowWidth, sample.WindowHeight, ResetFlags.MSAA16x | ResetFlags.Capture); // enable debug text Bgfx.SetDebugFeatures(DebugFeatures.DisplayText); // set view 0 clear state Bgfx.SetViewClear(0, ClearTargets.Color | ClearTargets.Depth, 0x303030ff); Bgfx.SetViewRect(0, 0, 0, sample.WindowWidth, sample.WindowHeight); // create vertex and index buffers var vbh = Cube.CreateVertexBuffer(); var ibh = Cube.CreateIndexBuffer(); // load shaders var program = ResourceLoader.LoadProgram("vs_callback", "fs_callback"); // 5 seconds of 60 Hz video var time = 0.0f; for (int frame = 0; frame < 300; frame++) { // write some debug text Bgfx.DebugTextClear(); Bgfx.DebugTextWrite(0, 1, DebugColor.White, DebugColor.Blue, "SharpBgfx/Samples/07-Callback"); Bgfx.DebugTextWrite(0, 2, DebugColor.White, DebugColor.Cyan, "Description: Implementing application specific callbacks for taking screen shots,"); Bgfx.DebugTextWrite(13, 3, DebugColor.White, DebugColor.Cyan, "caching OpenGL binary shaders, and video capture."); Bgfx.DebugTextWrite(0, 4, DebugColor.White, DebugColor.Cyan, "Frame: {0}", frame); // view transforms var viewMatrix = Matrix4x4.CreateLookAt(new Vector3(0.0f, 0.0f, 35.0f), Vector3.Zero, Vector3.UnitY); var projMatrix = Matrix4x4.CreatePerspectiveFieldOfView((float)Math.PI / 3, (float)sample.WindowWidth / sample.WindowHeight, 0.1f, 100.0f); Bgfx.SetViewTransform(0, &viewMatrix.M11, &projMatrix.M11); // fixed frame rate time += 1.0f / 60.0f; // submit 11x11 cubes for (int y = 0; y < 11; y++) { for (int x = 0; x < 11 - y; x++) { // model matrix var transform = Matrix4x4.CreateFromYawPitchRoll(time + x * 0.21f, time + y * 0.37f, 0.0f); transform.M41 = -15.0f + x * 3.0f; transform.M42 = -15.0f + y * 3.0f; transform.M43 = 0.0f; Bgfx.SetTransform(&transform.M11); // set pipeline states Bgfx.SetVertexBuffer(0, vbh); Bgfx.SetIndexBuffer(ibh); Bgfx.SetRenderState(RenderState.Default); // submit primitives Bgfx.Submit(0, program); } } // take a screenshot at frame 150 if (frame == 150) { Bgfx.RequestScreenShot("frame150"); } // advance to next frame Bgfx.Frame(); } // clean up ibh.Dispose(); vbh.Dispose(); program.Dispose(); Bgfx.Shutdown(); }
static unsafe void RenderThread(Sample sample) { // initialize the renderer Bgfx.Init(); Bgfx.Reset(sample.WindowWidth, sample.WindowHeight, ResetFlags.Vsync); // enable debug text Bgfx.SetDebugFeatures(DebugFeatures.DisplayText); // set view 0 clear state Bgfx.SetViewClear(0, ClearTargets.Color | ClearTargets.Depth, 0x303030ff); // create vertex and index buffers var vbh = Cube.CreateVertexBuffer(); var ibh = Cube.CreateIndexBuffer(); // load shaders var program = ResourceLoader.LoadProgram("vs_instancing", "fs_instancing"); // start the frame clock var clock = new Clock(); clock.Start(); // getting caps var caps = Bgfx.GetCaps(); // main loop while (sample.ProcessEvents(ResetFlags.Vsync)) { // set view 0 viewport Bgfx.SetViewRect(0, 0, 0, sample.WindowWidth, sample.WindowHeight); // view transforms var viewMatrix = Matrix4x4.CreateLookAt(new Vector3(0.0f, 0.0f, -35.0f), Vector3.Zero, Vector3.UnitY); var projMatrix = Matrix4x4.CreatePerspectiveFieldOfView((float)Math.PI / 3, (float)sample.WindowWidth / sample.WindowHeight, 0.1f, 100.0f); Bgfx.SetViewTransform(0, &viewMatrix.M11, &projMatrix.M11); // make sure view 0 is cleared if no other draw calls are submitted Bgfx.Touch(0); // tick the clock var elapsed = clock.Frame(); var time = clock.TotalTime(); // write some debug text Bgfx.DebugTextClear(); Bgfx.DebugTextWrite(0, 1, DebugColor.White, DebugColor.Blue, "SharpBgfx/Samples/05-Instancing"); Bgfx.DebugTextWrite(0, 2, DebugColor.White, DebugColor.Cyan, "Description: Geometry instancing."); Bgfx.DebugTextWrite(0, 3, DebugColor.White, DebugColor.Cyan, "Frame: {0:F3} ms", elapsed * 1000); // check caps if ((caps.SupportedFeatures & DeviceFeatures.Instancing) != DeviceFeatures.Instancing) { // instancing not supported Bgfx.DebugTextWrite(0, 3, DebugColor.White, DebugColor.Red, "Instancing not supported!"); } else { const int instanceStride = 80; const int instanceCount = 121; var idb = new InstanceDataBuffer(instanceCount, instanceStride); // fill in InstanceDataBuffer byte *dataPtr = (byte *)idb.Data.ToPointer(); // TODO: extract idb->data->num for (int y = 0; y < 11; y++) { for (int x = 0; x < 11; x++) { float *matrix = (float *)dataPtr; var realMatrix = Matrix4x4.CreateFromYawPitchRoll(time + x * 0.21f, time + y * 0.37f, 0f); realMatrix.M41 = -15.0f + x * 3.0f; realMatrix.M42 = -15.0f + y * 3.0f; realMatrix.M43 = 0.0f; // TODO: use proper copy function, not a bycicle float *realMatrixPtr = &realMatrix.M11; for (int i = 0; i < 16; i++) { matrix[i] = realMatrixPtr[i]; } float *color = (float *)(dataPtr + 64); color[0] = (float)Math.Sin(time + x / 11.0f) * 0.5f + 0.5f; color[1] = (float)Math.Cos(time + y / 11.0f) * 0.5f + 0.5f; color[2] = (float)Math.Sin(time * 3.0f) * 0.5f + 0.5f; color[3] = 1.0f; dataPtr += instanceStride; } } // set pipeline states Bgfx.SetVertexBuffer(0, vbh); Bgfx.SetIndexBuffer(ibh); Bgfx.SetInstanceDataBuffer(ref idb); Bgfx.SetRenderState(RenderState.Default); // submit primitives Bgfx.Submit(0, program); } // advance to the next frame. Rendering thread will be kicked to // process submitted rendering primitives. Bgfx.Frame(); } // clean up ibh.Dispose(); vbh.Dispose(); program.Dispose(); Bgfx.Shutdown(); }