public unsafe ITexture2D GetGlTexture2D() { if (image is Ogl3TextureImage oglCgImage) { return(oglCgImage.GlTexture); } if (!isDirty) { return(glTexture2D); } var size = image.Size; if (glTexture2D == null || glTexture2D.Width != size.Width || glTexture2D.Height != size.Height) { glTexture2D?.Dispose(); var mipCount = image.Volatility != ResourceVolatility.Volatile ? GraphicsHelper.TextureMipCount(size.Width, size.Height) : 1; // To side-step the sRGB issue with GenerateMipmaps glTexture2D = infra.GlContext.Create.Texture2D(size.Width, size.Height, mipCount, format); } fixed(byte *pRawData = image.GetRawData()) glTexture2D.SetData(0, (IntPtr)pRawData, FormatColor.Bgra, FormatType.UnsignedByte); if (glTexture2D.MipCount != 1) { glTexture2D.GenerateMipmap(); } isDirty = false; return(glTexture2D); }
public void RenderToTexture(ITexture2D glTexture, IReadOnlyList <IViewport> viewports, float timestamp) { rttFramebuffer.AttachTextureImage(FramebufferAttachmentPoint.Color0, glTexture, 0); foreach (var viewport in viewports) { var offScreen = offScreenContainer.Get(this, viewport, viewport.Width, viewport.Height, MsaaCount, OffscreenTtl); for (var i = 0; i < viewport.View.Layers.Count; i++) { var layer = viewport.View.Layers[i]; var isFirstLayer = i == 0; var isLastLayer = i == viewport.View.Layers.Count - 1; var sceneRendererSettings = GetSceneRendererSettings(isFirstLayer, true, isLastLayer); var sceneRenderer = sceneRendererPool.Allocate(sceneRendererSettings); sceneRenderer.Execute(layer.VisibleScene, layer.Camera, offScreen, timestamp, sceneRendererSettings); sceneRendererPool.Return(sceneRenderer); } glContext.Actions.BlitFramebuffer(offScreen.Framebuffer, rttFramebuffer, 0, 0, viewport.Width, viewport.Height, viewport.Left, glTexture.Height - viewport.Top, viewport.Left + viewport.Width, glTexture.Height - (viewport.Top + viewport.Height), ClearBufferMask.ColorBufferBit, BlitFramebufferFilter.Nearest); } glTexture.GenerateMipmap(); }
public unsafe override void OnNewFrame(float totalSeconds, float elapsedSeconds) { float angle = totalSeconds * 0.125f; Matrix4 world = Matrix4.CreateRotationX(angle) * Matrix4.CreateRotationY(2 * angle) * Matrix4.CreateRotationZ(3 * angle); world.Transpose(); Vector3 cameraPosition = new Vector3(5, 3, 0); Matrix4 view = Matrix4.LookAt(cameraPosition, Vector3.Zero, Vector3.UnitZ); Matrix4 proj = Matrix4.CreatePerspectiveFieldOfView((float)Math.PI / 4f, 1f, 0.1f, 1000f); Matrix4 invertY = Matrix4.Identity; invertY.M22 = -1f; Matrix4 viewProjection = view * proj * invertY; viewProjection.Transpose(); Vector3 lightPosition = new Vector3(10, -7, 2); transformBuffer.SetDataByMapping((IntPtr)(&world)); cameraBuffer.SetDataByMapping((IntPtr)(&viewProjection)); cameraExtraBuffer.SetDataByMapping((IntPtr)(&cameraPosition)); lightBuffer.SetDataByMapping((IntPtr)(&lightPosition)); framebuffer.ClearColor(0, new Color4(0.4f, 0.6f, 0.9f, 1.0f)); framebuffer.ClearDepthStencil(DepthStencil.Both, 1f, 0); Context.Actions.ClearWindowColor(new Color4(0, 0, 0, 1)); Context.Actions.ClearWindowDepthStencil(DepthStencil.Both, 1f, 0); Context.States.ScreenClipping.United.Viewport.Set(RenderTargetSize, RenderTargetSize); Context.States.Rasterizer.FrontFace.Set(FrontFaceDirection.Cw); Context.States.Rasterizer.CullFaceEnable.Set(true); Context.States.Rasterizer.CullFace.Set(CullFaceMode.Front); Context.States.DepthStencil.DepthTestEnable.Set(true); Context.States.DepthStencil.DepthMask.Set(true); Context.Bindings.Framebuffers.Draw.Set(framebuffer); Context.Bindings.Program.Set(program); Context.Bindings.VertexArray.Set(vertexArray); Context.Bindings.Buffers.UniformIndexed[0].Set(transformBuffer); Context.Bindings.Buffers.UniformIndexed[1].Set(cameraBuffer); Context.Bindings.Buffers.UniformIndexed[2].Set(lightBuffer); Context.Bindings.Textures.Units[0].Set(diffuseMap); Context.Bindings.Samplers[0].Set(sampler); // Inside cube Context.Actions.Draw.Elements(BeginMode.Triangles, 36, DrawElementsType.UnsignedShort, 0); renderTarget.GenerateMipmap(); // Outside cube proj = Matrix4.CreatePerspectiveFieldOfView((float)Math.PI / 4f, (float)GameWindow.ClientSize.Width / GameWindow.ClientSize.Height, 0.1f, 1000f); viewProjection = view * proj; viewProjection.Transpose(); #if INTEL_WORKAROUND cameraOutsideBuffer.SetDataByMapping((IntPtr)(&viewProjection)); #else cameraBuffer.SetDataByMapping((IntPtr)(&viewProjection)); #endif Context.States.ScreenClipping.United.Viewport.Set(GameWindow.ClientSize.Width, GameWindow.ClientSize.Height); Context.States.Rasterizer.FrontFace.Set(FrontFaceDirection.Ccw); Context.Bindings.Framebuffers.Draw.Set(null); #if INTEL_WORKAROUND Context.Pipeline.UniformBuffers[1] = cameraOutsideBuffer; #endif Context.Bindings.Textures.Units[0].Set(renderTarget); Context.Bindings.Samplers[0].Set(sampler); Context.Actions.Draw.Elements(BeginMode.Triangles, 36, DrawElementsType.UnsignedShort, 0); }