internal Renderer(Window window, int index = -1, SDL_RendererFlags flags = SDL_RendererFlags.SDL_RENDERER_ACCELERATED | SDL_RendererFlags.SDL_RENDERER_PRESENTVSYNC) { _window = window; this.index = index; this.flags = flags; Create(); }
public virtual bool GetVSync() { SDL_RendererInfo info; SDL_GetRendererInfo(this.Renderer.SDL_Renderer, out info); SDL_RendererFlags flags = (SDL_RendererFlags)info.flags; bool VSync = (flags & SDL_RendererFlags.SDL_RENDERER_PRESENTVSYNC) != 0; return(VSync); }
public int MaxTextureHeight; // The maximimum texture height public RendererInfo() { Flags = SDL_RendererFlags.SDL_RENDERER_ACCELERATED | SDL_RendererFlags.SDL_RENDERER_PRESENTVSYNC | SDL_RendererFlags.SDL_RENDERER_TARGETTEXTURE; NumTextureFormats = 1; TextureFormats = new Format[16]; TextureFormats[0] = Format.A8R8G8B8; MaxTextureWidth = 0; MaxTextureHeight = 0; }
public virtual void SetVSync(bool VSync) { SDL_RendererInfo info; SDL_GetRendererInfo(this.Renderer.SDL_Renderer, out info); SDL_RendererFlags flags = (SDL_RendererFlags)info.flags; bool HardwareAcceleration = (flags & SDL_RendererFlags.SDL_RENDERER_ACCELERATED) != 0; bool SoftwareRendering = (flags & SDL_RendererFlags.SDL_RENDERER_SOFTWARE) != 0; bool TargetTexture = (flags & SDL_RendererFlags.SDL_RENDERER_TARGETTEXTURE) != 0; bool OldVSync = (flags & SDL_RendererFlags.SDL_RENDERER_PRESENTVSYNC) != 0; if (OldVSync == VSync) { return; } SDL_RendererFlags newflags = 0; if (HardwareAcceleration) { newflags |= SDL_RendererFlags.SDL_RENDERER_ACCELERATED; } if (SoftwareRendering) { newflags |= SDL_RendererFlags.SDL_RENDERER_SOFTWARE; } if (TargetTexture) { newflags |= SDL_RendererFlags.SDL_RENDERER_TARGETTEXTURE; } if (VSync) { newflags |= SDL_RendererFlags.SDL_RENDERER_PRESENTVSYNC; } for (int i = 0; i < Bitmap.BitmapList.Count; i++) { Bitmap bmp = Bitmap.BitmapList[i]; if (bmp.Texture != IntPtr.Zero) { SDL_DestroyTexture(bmp.Texture); bmp.Texture = IntPtr.Zero; } } SDL_DestroyRenderer(this.Renderer.SDL_Renderer); this.Renderer.SDL_Renderer = SDL_CreateRenderer(this.SDL_Window, -1, newflags); for (int i = 0; i < Bitmap.BitmapList.Count; i++) { Bitmap bmp = Bitmap.BitmapList[i]; if (bmp.Renderer == null) { continue; } if (bmp.IsChunky) { bmp.InternalBitmaps.ForEach(ibmp => ibmp.RecreateTexture(false)); } else { bmp.RecreateTexture(false); } } }
/// <summary> /// Called to actually create the window and renderer. /// </summary> public virtual void Initialize(bool HardwareAcceleration = true, bool VSync = false, bool Borderless = false, bool ForceOpenGL = false) { if (Graphics.Windows.Contains(this)) { return; } _StartTime = DateTime.Now; if (ForceOpenGL) { SDL_SetHint(SDL_HINT_RENDER_DRIVER, "opengl"); } SDL_WindowFlags flags = SDL_WindowFlags.SDL_WINDOW_HIDDEN | SDL_WindowFlags.SDL_WINDOW_ALLOW_HIGHDPI; if (Borderless) { flags |= SDL_WindowFlags.SDL_WINDOW_BORDERLESS; } this.SDL_Window = SDL_CreateWindow(this.Text, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, this.Width, this.Height, flags); int WX; int WY; SDL_GetWindowPosition(this.SDL_Window, out WX, out WY); this.X = WX; this.Y = WY; SDL_SetWindowResizable(this.SDL_Window, Resizable ? SDL_bool.SDL_TRUE : SDL_bool.SDL_FALSE); if (this.Icon != null) { SDL_SetWindowIcon(this.SDL_Window, this.Icon.Surface); } SDL_RendererFlags renderflags = 0; if (HardwareAcceleration) { renderflags |= SDL_RendererFlags.SDL_RENDERER_ACCELERATED; } if (VSync) { renderflags |= SDL_RendererFlags.SDL_RENDERER_PRESENTVSYNC; } this.Renderer = new Renderer(SDL_CreateRenderer(this.SDL_Window, -1, renderflags)); if (Graphics.MaxTextureSize == null) { SDL_RendererInfo info; SDL_GetRendererInfo(this.Renderer.SDL_Renderer, out info); Graphics.MaxTextureSize = new Size(info.max_texture_width, info.max_texture_height); Console.WriteLine($"Maximum Texture Size: {info.max_texture_width}x{info.max_texture_height}"); } this.Viewport = new Viewport(this, 0, 0, this.Width, this.Height); this.Viewport.Name = "Main Viewport"; if (Viewport.DefaultWindow == null) { Viewport.DefaultWindow = this; } if (Sprite.DefaultViewport == null) { Sprite.DefaultViewport = this.Viewport; } BackgroundViewport = new Viewport(this, 0, 0, this.Width, this.Height); BackgroundViewport.Name = "Background Viewport"; BackgroundViewport.Z = -999999999; BackgroundSprite = new Sprite(BackgroundViewport); BackgroundSprite.Name = "Background"; BackgroundSprite.Z = -999999999; BackgroundSprite.Bitmap = new SolidBitmap(this.Width, this.Height, this.BackgroundColor); TopViewport = new Viewport(this, 0, 0, this.Width, this.Height); TopViewport.Z = -1; TopViewport.Name = "Top Viewport"; TopSprite = new Sprite(TopViewport, new SolidBitmap(this.Width, this.Height, Color.BLACK)); TopSprite.Z = 999999999; TopSprite.Opacity = 0; Graphics.AddWindow(this); if (MinimumSize != null) { SDL_SetWindowMinimumSize(SDL_Window, MinimumSize.Width, MinimumSize.Height); } Init = true; if (this.GetType() == typeof(Window)) { Start(); } }
private void Initialize(SDL_RendererFlags flags) { _info = new RendererInfo(); _info.Flags = SDL_RendererFlags.SDL_RENDERER_ACCELERATED; _d3d = new Direct3D(); _pparams = new PresentParameters(); _pparams.DeviceWindowHandle = _hwnd; _pparams.BackBufferWidth = _window.ClientSize.Width; _pparams.BackBufferHeight = _window.ClientSize.Height; if (Config.Fullscreen) { } else { _pparams.BackBufferFormat = Format.Unknown; } _pparams.BackBufferCount = 1;// 后备缓冲区的数量。通常设为“1”,即只有一个后备表面。 /* * 指定系统如何将后台缓冲区的内容复制到前台缓冲区,从而在屏幕上显示。它的值有: * D3DSWAPEFFECT_DISCARD: 清除后台缓存的内容。 * D3DSWAPEEFECT_FLIP: 保留后台缓存的内容,当缓存区>1时。 * D3DSWAPEFFECT_COPY: 保留后台缓存的内容,缓冲区=1时。 * 一般情况下使用D3DSWAPEFFECT_DISCARD */ _pparams.SwapEffect = SwapEffect.Discard; if (Config.Fullscreen) { if (Config.Borderless) { _pparams.Windowed = true; _pparams.FullScreenRefreshRateInHz = 0; } else { _pparams.Windowed = false; _pparams.FullScreenRefreshRateInHz = 0; } } else { _pparams.Windowed = true;// 指定窗口模式。True = 窗口模式;False = 全屏模式 /* * 显示适配器刷新屏幕的速率。该值取决于应用程序运行的模式: * 对于窗口模式,刷新率必须为0。 * 对于全屏模式,刷新率是EnumAdapterModes返回的刷新率之一。 */ _pparams.FullScreenRefreshRateInHz = 0; } if ((flags & SDL_RendererFlags.SDL_RENDERER_PRESENTVSYNC) != 0) { /* * 交换链的后缓冲区可以提供给前缓冲区的最大速率。可以用以下方式: * D3DPRESENT_INTERVAL_DEFAULT: 这几乎等同于D3DPRESENT_INTERVAL_ONE。 * D3DPRESENT_INTERVAL_ONE: 垂直同步。当前的操作不会比刷新屏幕更频繁地受到影响。 * D3DPRESENT_INTERVAL_IMMEDIATE: 以实时的方式来显示渲染画面。 */ _pparams.PresentationInterval = PresentInterval.One; } else { _pparams.PresentationInterval = PresentInterval.Immediate; } CreateFlags device_flags = CreateFlags.FpuPreserve;// 将Direct3D浮点计算的精度设置为调用线程使用的精度 //device_flags |= CreateFlags.Multithreaded;// 瓶颈主要在IO上面,且SDL中尚未设置,此处预留以备不时之需 Capabilities caps = _d3d.GetDeviceCaps(D3DADAPTER_DEFAULT, DeviceType.Hardware); if ((caps.DeviceCaps & DeviceCaps.HWTransformAndLight) != 0) { device_flags |= CreateFlags.HardwareVertexProcessing; } else { device_flags |= CreateFlags.SoftwareVertexProcessing; } /* * @param adapter 表示显示适配器的序号。D3DADAPTER_DEFAULT(0)始终是主要的显示适配器。 * @param renderWindow 窗体或任何其他Control派生类的句柄。此参数指示要绑定到设备的表面。 * 指定的窗口必须是顶级窗口。不支持空值。 * @param deviceType 定义设备类型。 * D3DDEVTYPE_HAL 硬件栅格化。可以使用软件,硬件或混合的变换和照明进行着色。 * 详见:https://docs.microsoft.com/en-us/windows/win32/direct3d9/d3ddevtype * @param behaviorFlags 控制设备创建行为的一个或多个标志的组合。 * D3DCREATE_HARDWARE_VERTEXPROCESSING 指定硬件顶点处理。 * D3DCREATE_SOFTWARE_VERTEXPROCESSING 指定软件顶点处理。 * 对于Windows 10版本1607及更高版本,不建议使用此设置。 * 使用D3DCREATE_HARDWARE_VERTEXPROCESSING。 * [!Note] 除非没有可用的硬件顶点处理, * 否则在Windows 10版本1607(及更高版本)中不建议使用软件顶点处理, * 因为在提高实现安全性的同时,软件顶点处理的效率已大大降低。 * 详见:https://docs.microsoft.com/en-us/windows/win32/direct3d9/d3dcreate * * @see https://docs.microsoft.com/en-us/windows/win32/api/d3d9/nf-d3d9-idirect3d9-createdevice */ _d3dDevice = new Device(_d3d , D3DADAPTER_DEFAULT , DeviceType.Hardware , _hwnd , device_flags , _pparams); _beginScene = true; _scaleMode = (TextureFilter)D3DTEXF_FORCE_DWORD; // Get presentation parameters to fill info SwapChain chain = _d3dDevice.GetSwapChain(0); _pparams = chain.PresentParameters; chain.Dispose();// FIXME: IDirect3DSwapChain9::Release? if (_pparams.PresentationInterval == PresentInterval.One) { _info.Flags |= SDL_RendererFlags.SDL_RENDERER_PRESENTVSYNC; } caps = _d3dDevice.Capabilities; _info.MaxTextureWidth = caps.MaxTextureWidth; _info.MaxTextureHeight = caps.MaxTextureHeight; if (caps.SimultaneousRTCount >= 2) { _info.Flags |= SDL_RendererFlags.SDL_RENDERER_TARGETTEXTURE; } // Set up parameters for rendering _d3dDevice.VertexShader = null; // IDirect3DDevice9::SetFVF(D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1) _d3dDevice.VertexFormat = VertexFormat.Position | VertexFormat.Diffuse | VertexFormat.Texture1; // IDirect3DDevice9::SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE) _d3dDevice.SetRenderState(RenderState.ZEnable, ZBufferType.DontUseZBuffer); _d3dDevice.SetRenderState(RenderState.CullMode, Cull.None); _d3dDevice.SetRenderState(RenderState.Lighting, false); // Enable color modulation by diffuse color _d3dDevice.SetTextureStageState(0, TextureStage.ColorOperation, TextureOperation.Modulate); _d3dDevice.SetTextureStageState(0, TextureStage.ColorArg1, TextureArgument.Texture); _d3dDevice.SetTextureStageState(0, TextureStage.ColorArg2, TextureArgument.Diffuse); // Enable alpha modulation by diffuse alpha _d3dDevice.SetTextureStageState(0, TextureStage.AlphaOperation, TextureOperation.Modulate); _d3dDevice.SetTextureStageState(0, TextureStage.AlphaArg1, TextureArgument.Texture); _d3dDevice.SetTextureStageState(0, TextureStage.AlphaArg2, TextureArgument.Diffuse); // Disable second texture stage, since we're done _d3dDevice.SetTextureStageState(1, TextureStage.ColorOperation, TextureOperation.Disable); _d3dDevice.SetTextureStageState(1, TextureStage.AlphaOperation, TextureOperation.Disable); // Store the default render target _defaultRenderTarget = _d3dDevice.GetRenderTarget(0); _currentRenderTarget = null; // Set an identity world and view matrix RawMatrix matrix; matrix.M11 = 1.0f; matrix.M12 = 0.0f; matrix.M13 = 0.0f; matrix.M14 = 0.0f; matrix.M21 = 0.0f; matrix.M22 = 1.0f; matrix.M23 = 0.0f; matrix.M24 = 0.0f; matrix.M31 = 0.0f; matrix.M32 = 0.0f; matrix.M33 = 1.0f; matrix.M34 = 0.0f; matrix.M41 = 0.0f; matrix.M42 = 0.0f; matrix.M43 = 0.0f; matrix.M44 = 1.0f; _d3dDevice.SetTransform(TransformState.World, matrix); _d3dDevice.SetTransform(TransformState.View, matrix); _scale.x = 1.0f; _scale.y = 1.0f; if (!_window.Visible || _window.WindowState == FormWindowState.Minimized) { _hidden = true; } else { _hidden = false; } }
public static extern IntPtr CreateRenderer(IntPtr window, int index, SDL_RendererFlags flags);