public override void Update() { D3D9RenderSystem rs = (D3D9RenderSystem)Root.Instance.RenderSystem; if (rs.DeviceLost) { return; } base.Update(); }
/// <summary> /// /// </summary> /// <param name="waitForVSync"></param> public override void SwapBuffers(bool waitForVSync) { D3D.Device device = driver.Device; if (device != null) { int status; // tests coop level to make sure we are ok to render device.CheckCooperativeLevel(out status); if (status == (int)Microsoft.DirectX.Direct3D.ResultCode.Success) { // swap back buffer to the front if (isSwapChain) { swapChain.Present(); } else { device.Present(); } } else if (status == (int)Microsoft.DirectX.Direct3D.ResultCode.DeviceLost) { // Device is lost, and is not available for reset now log.Warn("Device State: DeviceLost"); D3D9RenderSystem renderSystem = (D3D9RenderSystem)Root.Instance.RenderSystem; renderSystem.NotifyDeviceLost(); } else if (status == (int)Microsoft.DirectX.Direct3D.ResultCode.DeviceNotReset) { // The device needs to be reset, and has not yet been reset. log.Warn("Device State: DeviceNotReset"); device.Reset(device.PresentationParameters); } else { throw new Exception(string.Format("Unknown status code from CheckCooperativeLevel: {0}", status)); } } }
public void ApplyCache(D3D9RenderSystem renderSystem, D3D.Device device, D3D.Caps d3dCaps) { log.Info("DirectXCache.ApplyCache: Starting to apply cache settings to device"); renderSystem.SetSceneDetailLevel(rasterizationMode); renderSystem.SetColorBufferWriteEnabledInternal(writeEnabledRed, writeEnabledGreen, writeEnabledBlue, writeEnabledAlpha); device.RenderState.AlphaTestEnable = alphaTestEnable; device.RenderState.AlphaFunction = D3DHelper.ConvertEnum(alphaFunction); device.RenderState.ReferenceAlpha = referenceAlpha; renderSystem.SetRenderState(RenderStates.ColorVertex, colorVertex); device.RenderState.ShadeMode = D3DHelper.ConvertEnum(shadingMode); device.RenderState.CullMode = D3DHelper.ConvertEnum(cullingMode, cullingFlip); if (d3dCaps.RasterCaps.SupportsDepthBias) renderSystem.SetRenderState(RenderStates.DepthBias, -constantBias / 250000.0f); if (d3dCaps.RasterCaps.SupportsSlopeScaleDepthBias) renderSystem.SetRenderState(RenderStates.SlopeScaleDepthBias, -slopeScaleBias); renderSystem.SetRenderState(RenderStates.PointSpriteEnable, pointSpriteEnable); renderSystem.SetRenderState(RenderStates.PointScaleEnable, pointScaleEnable); renderSystem.SetRenderState(RenderStates.PointSize, pointSize); renderSystem.SetRenderState(RenderStates.PointSizeMin, pointSizeMin); renderSystem.SetRenderState(RenderStates.PointSizeMax, pointSizeMax); device.RenderState.ZBufferFunction = D3DHelper.ConvertEnum(zBufferFunction); if(depthCheck) { // use w-buffer if available if(renderSystem.useWBuffer && d3dCaps.RasterCaps.SupportsWBuffer) device.RenderState.UseWBuffer = true; else device.RenderState.ZBufferEnable = true; } else device.RenderState.ZBufferEnable = false; zBufferWriteEnable = device.RenderState.ZBufferWriteEnable; device.RenderState.AlphaBlendEnable = alphaBlendEnable; device.RenderState.SourceBlend = D3DHelper.ConvertEnum(sourceBlend); device.RenderState.DestinationBlend = D3DHelper.ConvertEnum(destinationBlend); for (int i=0; i<d3dCaps.MaxSimultaneousTextures; i++) { device.TextureState[i].TextureCoordinateIndex = D3DHelper.ConvertEnum(renderSystem.texStageDesc[i].autoTexCoordType, d3dCaps) | textureCoordinateIndex[i]; renderSystem.texStageDesc[i].autoTexCoordType = TexCoordCalcMethod.None; renderSystem.SetTextureMatrixInternal(i, textureMatrix[i]); device.TextureState[i].ColorOperation = colorOperation[i]; device.TextureState[i].AlphaOperation = alphaOperation[i]; device.TextureState[i].ColorArgument1 = colorArgument1[i]; device.TextureState[i].ColorArgument2 = colorArgument2[i]; device.TextureState[i].AlphaArgument1 = alphaArgument1[i]; device.TextureState[i].AlphaArgument2 = alphaArgument2[i]; device.TextureState[i].TextureTransform = textureTransformOp[i]; for (int j=0; j<3; j++) renderSystem.SetTextureUnitFilteringInternal(i, (FilterType)j, textureUnitFilteringFilter[i,j]); } device.RenderState.TextureFactor = textureFactor;; device.Transform.World = renderSystem.MakeD3DMatrix(worldMatrix); renderSystem.SetViewMatrixInternal(viewMatrix); renderSystem.SetProjectionMatrixInternal(projectionMatrix, false); device.RenderState.Ambient = ambient.ToColor(); // create a new material based on the supplied params D3D.Material mat = new D3D.Material(); mat.Diffuse = materialDiffuse.ToColor(); mat.Ambient = materialAmbient.ToColor(); mat.Specular = materialSpecular.ToColor(); mat.Emissive = materialEmissive.ToColor(); mat.SpecularSharpness = materialShininess; // set the current material device.Material = mat; device.VertexShader = vertexShader; device.PixelShader = pixelShader; device.Indices = indexBuffer; for (int i=0; i<d3dCaps.MaxStreams; i++) { streamNull[i] = true; device.SetStreamSource(i, null, 0, 0); } device.VertexDeclaration = null; device.RenderState.FogEnable = fogEnable; device.RenderState.FogColor = fogColor.ToColor(); device.RenderState.FogDensity = fogDensity; device.RenderState.FogStart = fogStart; device.RenderState.FogEnd = fogEnd; device.RenderState.FogVertexMode = D3DHelper.ConvertEnum(fogMode); device.RenderState.FogTableMode = D3D.FogMode.None; intShaderConstants = new Object[d3dCaps.MaxVertexShaderConst]; floatShaderConstants = new float[d3dCaps.MaxVertexShaderConst * 4]; intPixelConstants = new Object[d3dCaps.MaxVertexShaderConst]; floatPixelConstants = new float[d3dCaps.MaxVertexShaderConst * 4]; for (int i=0; i<cachedLights.Length; i++) { CachedLight cachedLight = cachedLights[i]; device.Lights[i].Enabled = cachedLight.enabled; switch(cachedLight.type) { case LightType.Point: device.Lights[i].Type = D3D.LightType.Point; break; case LightType.Directional: device.Lights[i].Type = D3D.LightType.Directional; break; case LightType.Spotlight: device.Lights[i].Type = D3D.LightType.Spot; break; } device.Lights[i].Falloff = cachedLight.spotFalloff; device.Lights[i].InnerConeAngle = MathUtil.DegreesToRadians(cachedLight.spotInner); device.Lights[i].OuterConeAngle = MathUtil.DegreesToRadians(cachedLight.spotOuter); device.Lights[i].Diffuse = cachedLight.diffuse.ToColor(); device.Lights[i].Specular = cachedLight.specular.ToColor(); Axiom.MathLib.Vector3 vec = cachedLight.position; device.Lights[i].Position = new DX.Vector3(vec.x, vec.y, vec.z); vec = cachedLight.direction; device.Lights[i].Direction = new DX.Vector3(vec.x, vec.y, vec.z); device.Lights[i].Range = cachedLight.range; device.Lights[i].Attenuation0 = cachedLight.attenuationConst; device.Lights[i].Attenuation1 = cachedLight.attenuationLinear; device.Lights[i].Attenuation2 = cachedLight.attenuationQuad; device.RenderState.Lighting = renderSystem.lightingEnabled; } log.Info("DirectXCache.ApplyCache: Finished applying cache settings to device"); }
public override void Update() { D3D9RenderSystem rs = (D3D9RenderSystem)Root.Instance.RenderSystem; // access device through driver D3D.Device device = driver.Device; if (rs.DeviceLost) { log.Info("In D3DRenderWindow.Update, rs.DeviceLost is true"); // Test the cooperative mode first int status; device.CheckCooperativeLevel(out status); if (status == (int)Microsoft.DirectX.Direct3D.ResultCode.DeviceLost) { // device lost, and we can't reset // can't do anything about it here, wait until we get // D3DERR_DEVICENOTRESET; rendering calls will silently fail until // then (except Present, but we ignore device lost there too) // FIXME: Ogre doesn't do these two Dispose calls here. #if NOT // This code is what Ogre does for this clause, but since // Ogre gets to immediately call release on the renderSurface // and renderZBuffer, this assign of null will end up leaving // the reference count at 0 for them, and will cause them to // be freed. For the Axiom code, I'm just going to leave them // alone, and do the proper dispose calls in the devicenotreset // clause. renderSurface = null; // need to release if swap chain if (!isSwapChain) { renderZBuffer = null; } else { // Do I need to dispose of the ZBuffer here? // SAFE_RELEASE (mpRenderZBuffer); if (renderZBuffer != null) { renderZBuffer.Dispose(); renderZBuffer = null; } } #endif Thread.Sleep(50); return; } else { if (status != (int)Microsoft.DirectX.Direct3D.ResultCode.Success && status != (int)Microsoft.DirectX.Direct3D.ResultCode.DeviceNotReset) { // I've encountered some unexpected device state // Ogre would just continue, but I want to make sure I notice this. throw new Exception(string.Format("Unknown Device State: {0}", status)); } // FIXME: Ogre doesn't do these two Dispose calls here. if (renderSurface != null) { log.Info("Disposing of render surface"); renderSurface.Dispose(); renderSurface = null; } if (renderZBuffer != null) { log.Info("Disposing of render zbuffer"); renderZBuffer.Dispose(); renderZBuffer = null; } log.InfoFormat("In D3DRenderWindow.Update, calling rs.RestoreLostDevice(); status = {0}", status); // device lost, and we can reset rs.RestoreLostDevice(); // Still lost? if (rs.DeviceLost) { // Wait a while Thread.Sleep(50); return; } if (!isSwapChain) { log.Info("In D3DRenderWindow.Update, re-querying buffers"); // re-qeuery buffers renderSurface = device.GetRenderTarget(0); renderZBuffer = device.DepthStencilSurface; // release immediately so we don't hog them // mpRenderSurface->Release(); // mpRenderZBuffer->Release(); } else { log.Info("In D3DRenderWindow.Update, isSwapChain is true, changing viewport dimensions"); // Update dimensions incase changed foreach (Axiom.Core.Viewport vp in viewportList) { vp.UpdateDimensions(); } // Actual restoration of surfaces will happen in // D3D9RenderSystem.RestoreLostDevice when it calls // CreateD3DResources for each secondary window } } } base.Update(); }
public void WindowMovedOrResized() { log.Info("D3DRenderWindow.WindowMovedOrResized called."); if (windowHandle == null) { return; } Form form = windowHandle.FindForm(); if (form != null) { if (form.WindowState == FormWindowState.Minimized) { return; } this.top = form.DesktopLocation.Y; this.left = form.DesktopLocation.X; } if ((width == windowHandle.Size.Width) && (height == windowHandle.Size.Height)) { return; } if (isSwapChain) { PresentParameters pp = new PresentParameters(presentParams); width = windowHandle.Size.Width > 0 ? windowHandle.Size.Width : 1; height = windowHandle.Size.Height > 0 ? windowHandle.Size.Height : 1; if (presentParams.Windowed) { pp.BackBufferWidth = width; pp.BackBufferHeight = height; } if (renderZBuffer != null) { renderZBuffer.Dispose(); renderZBuffer = null; } if (swapChain != null) { swapChain.Dispose(); swapChain = null; } if (renderSurface != null) { renderSurface.Dispose(); renderSurface = null; } swapChain = new SwapChain(driver.Device, pp); presentParams = pp; renderSurface = swapChain.GetBackBuffer(0, BackBufferType.Mono); renderZBuffer = driver.Device.CreateDepthStencilSurface(presentParams.BackBufferWidth, presentParams.BackBufferHeight, presentParams.AutoDepthStencilFormat, presentParams.MultiSample, presentParams.MultiSampleQuality, false); // TODO: Ogre releases here // renderSurface.Release(); } else { // primary windows must reset the device width = windowHandle.Size.Width > 0 ? windowHandle.Size.Width : 1; height = windowHandle.Size.Height > 0 ? windowHandle.Size.Height : 1; if (presentParams.Windowed) { presentParams.BackBufferWidth = width; presentParams.BackBufferHeight = height; } D3D9RenderSystem renderSystem = (D3D9RenderSystem)Root.Instance.RenderSystem; renderSystem.NotifyDeviceLost(); } // Notify viewports of resize foreach (Axiom.Core.Viewport viewport in viewportList) { viewport.UpdateDimensions(); } }