[c#] swap chain

Started by
8 comments, last by Say 18 years, 6 months ago
hi at all, i'm making an editor with 4 viewport like 3dsmax. i'm trying it with two for the moment and with my code it just works but not fine... Maybe i wrong someting with Z buffer, or setting the two present parameters or use data of the first swap chain also for the second, infact if i resize the second viewport making it bigger i see a the mesh loaded a little crasched on its texture and shape... This is my code:


		bool InitializeGraphics()
		{
			try
			{
				Caps caps = Manager.GetDeviceCaps( Manager.Adapters.Default.Adapter, 
					DeviceType.Hardware );
				CreateFlags flags;

				if( caps.DeviceCaps.SupportsHardwareTransformAndLight )
					flags = CreateFlags.HardwareVertexProcessing;
				else
					flags = CreateFlags.SoftwareVertexProcessing;

				presentParams[0] = new PresentParameters();
				presentParams[1] = new PresentParameters();

				presentParams[0].Windowed = true;
				presentParams[0].SwapEffect = SwapEffect.Discard;
				DisplayMode mode = new DisplayMode();

				presentParams[0].BackBufferFormat = mode.Format;
				presentParams[0].BackBufferWidth = panel1.Width;
				presentParams[0].BackBufferHeight = panel1.Height;
				presentParams[0].EnableAutoDepthStencil = true;
				presentParams[0].AutoDepthStencilFormat = DepthFormat.D16;

				presentParams[1].Windowed = true;
				presentParams[1].SwapEffect = SwapEffect.Discard;

				presentParams[1].BackBufferFormat = mode.Format;
				presentParams[1].BackBufferWidth = panel2.Width;
				presentParams[1].BackBufferHeight = panel2.Height;
				presentParams[1].EnableAutoDepthStencil = true;
				presentParams[1].AutoDepthStencilFormat = DepthFormat.D16;

				// create the device
				device = new Device(0, DeviceType.Hardware, this, flags, presentParams);
				
				device.DeviceReset += new System.EventHandler(this.OnResetDevice);
				device.DeviceLost += new EventHandler(this.OnLostDevice);

				this.OnResetDevice(device, null);
				initializedDirect3D = true;
			}
			catch(Direct3DXException)
			{
				return false;
			}

			return true;
		}

		public void OnResizingDevice()
		{
			if(initializedDirect3D)
			{
				pause = false;
				Reset_Present_Params();
				device.Reset(presentParams);
			}
		}

		private void Reset_Present_Params()
		{
			DisplayMode mode = new DisplayMode();

			presentParams[0].Windowed = true;
			presentParams[0].SwapEffect = SwapEffect.Discard;
			presentParams[0].BackBufferFormat = mode.Format;
			presentParams[0].BackBufferWidth = panel1.Width;
			presentParams[0].BackBufferHeight = panel1.Height;
			presentParams[0].EnableAutoDepthStencil = true;
			presentParams[0].AutoDepthStencilFormat = DepthFormat.D16;

			presentParams[1].Windowed = true;
			presentParams[1].SwapEffect = SwapEffect.Discard;
			presentParams[1].BackBufferFormat = mode.Format;
			presentParams[1].BackBufferWidth = panel2.Width;
			presentParams[1].BackBufferHeight = panel2.Height;
			presentParams[1].EnableAutoDepthStencil = true;
			presentParams[1].AutoDepthStencilFormat = DepthFormat.D16;
		}

		public void OnResetDevice(object sender, EventArgs e)
		{
			sc_0 = device.GetSwapChain(0);
			sc_1 = new SwapChain(device, presentParams[1]);
			device.RenderState.ZBufferEnable = true;
			device.RenderState.Ambient = System.Drawing.Color.White;
		}

		void SetupMatrices()
		{

			float scale = 1.0f; // The gun is gigantic, so let's scale it down a bit
			Vector3 pos = new Vector3(); // Let's display at 0, 0,
			Vector3 camPos = new Vector3(0.0f, 9.5f, 17.0f);
			Vector3 lookAt = new Vector3(); // We are facing 0, 0, 0, so we can see the model
			Vector3 camUp = new Vector3(0, 1, 0); // Up vector of the cam

			// Setup the camera
			device.Transform.Projection = Matrix.PerspectiveFovLH((float)Math.PI / 4, this.Width / this.Height, 1.0f, 1000.0f); 
			device.Transform.View = Matrix.LookAtLH(camPos, lookAt, camUp);

			// Display our model
			device.Transform.World = Matrix.Scaling(scale, scale, scale) * 
Matrix.Translation(0f, 0f, 0f)*Matrix.RotationY(Environment.TickCount/1000.0f); 

		}

		private void Render()
		{
			if (device == null)
				return;

			if (pause)
				return;

			if(x_file_list.Count > 0)
			{
				// panel1
				Surface pBackBuffer = sc_0.GetBackBuffer(0, BackBufferType.Mono);
				device.SetRenderTarget(0, pBackBuffer);
				//Clear the backbuffer to a blue color
				device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, System.Drawing.Color.DarkGray, 1.0f, 0);			
				device.BeginScene();
				// Setup the world, view, and projection matrices
				SetupMatrices();
        
				// Meshes are divided into subsets, one for each material. Render them in
				// a loop
				for( int i=0; i<meshMaterials.Length; i++ )
				{
					// Set the material and texture for this subset
					device.Material = meshMaterials;
					device.SetTexture(0, meshTextures);
    
					// Draw the mesh subset
					xMesh.DrawSubset(i);
				}

				if(active_panel == panel1)
					Draw_Active_Rect(panel1);

				//End the scene
				device.EndScene();
				sc_0.Present(panel1);
				//device.Present();
				pBackBuffer.ReleaseGraphics();

				// panel2
				Surface pBackBuffer2 = sc_1.GetBackBuffer(0, BackBufferType.Mono);
				device.SetRenderTarget( 0, pBackBuffer2 );


				//Clear the backbuffer to a blue color
				device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, System.Drawing.Color.DarkGray, 1.0f, 0);
				device.BeginScene();
				// Setup the world, view, and projection matrices
				SetupMatrices();
        
				// Meshes are divided into subsets, one for each material. Render them in
				// a loop
				for( int i=0; i<meshMaterials.Length; i++ )
				{
					// Set the material and texture for this subset
					device.Material = meshMaterials;
					device.SetTexture(0, meshTextures);
    
					// Draw the mesh subset
					xMesh.DrawSubset(i);
				}
				
				if(active_panel == panel2)
					Draw_Active_Rect(panel2);

				//End the scene
				device.EndScene();
				//device.Present();

				sc_1.Present(panel2);
				pBackBuffer2.ReleaseGraphics();

				//pause = true;
			}
		}




this is the result: [Edited by - Coder on October 23, 2005 4:41:17 PM]
Advertisement
1. Please read the faqs GDNET FAQ, Forum FAQ.
2. If your targets have different aspect ratios you will need to build and use different projection matricies or you will see distortion. Make sure the second argument passed to PerspectiveFovLH is correct -- it should be the the width/height of your target area.
ok i've correct it, but the bad drawing problem persist.
The viewport born of the same size, but i get the problem when i resize the second making it bigger.
Do i wrong something about PresentParameter, or release somehing or what?
On this line:

device.Transform.Projection = Matrix.PerspectiveFovLH((float)Math.PI / 4, this.Width / this.Height, 1.0f, 1000.0f);

instead of using the with and height of the control (I am assuming that that is what 'this' refers to in this context) to generate your aspect ratio try using the width and height of viewport. You should be able to get the viewport from the device (so long as it is not a pure device).

device.Transform.Projection = Matrix.PerspectiveFovLH((float)Math.PI / 4, device.Viewport.Width / device.Viewport.Height, 1.0f, 1000.0f);

If the either viewport changes shape you will have to generate a new projection matrix. If the two viewports are different shapes they will need diffrent projection matricies.

hope this helps.
Yes turnpast i've told you i've correct my code infact my new one is:
		void SetupMatrices(int w, int h)		{			float scale = 1.0f; // The gun is gigantic, so let's scale it down a bit			Vector3 pos = new Vector3(); // Let's display at 0, 0,			Vector3 camPos = new Vector3(0.0f, 9.5f, 17.0f);			Vector3 lookAt = new Vector3(); // We are facing 0, 0, 0, so we can see the model			Vector3 camUp = new Vector3(0, 1, 0); // Up vector of the cam			// Setup the camera			device.Transform.Projection = Matrix.PerspectiveFovLH((float)Math.PI / 4, w / h, 1.0f, 1000.0f); 			device.Transform.View = Matrix.LookAtLH(camPos, lookAt, camUp);			// Display our model			device.Transform.World = Matrix.Scaling(scale, scale, scale) * Matrix.Translation(0f, 0f, 0f)*Matrix.RotationY(Environment.TickCount/1000.0f); 		}

now the problem persist :(
Have you tried recreating the back buffers to match the sizes of the viewports? If that is not it I don't have any idea.

Good luck.
this is the code i use to draw so recreating the backbuffer:
				// panel1				Surface pBackBuffer = sc_0.GetBackBuffer(0, BackBufferType.Mono);				device.SetRenderTarget(0, pBackBuffer);				//Clear the backbuffer to a blue color				device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, System.Drawing.Color.DarkGray, 1.0f, 0);							device.BeginScene();				// Setup the world, view, and projection matrices				SetupMatrices(panel1.Width, panel1.Height);        				// Meshes are divided into subsets, one for each material. Render them in				// a loop				for( int i=0; i<meshMaterials.Length; i++ )				{					// Set the material and texture for this subset					device.Material = meshMaterials;					device.SetTexture(0, meshTextures);					// Draw the mesh subset					xMesh.DrawSubset(i);				}				if(active_panel == panel1)					Draw_Active_Rect(panel1);				//End the scene				device.EndScene();				sc_0.Present(panel1);				//device.Present();				pBackBuffer.ReleaseGraphics();				// panel2				Surface pBackBuffer2 = sc_1.GetBackBuffer(0, BackBufferType.Mono);				device.SetRenderTarget( 0, pBackBuffer2 );				//Clear the backbuffer to a blue color				device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, System.Drawing.Color.DarkGray, 1.0f, 0);				device.BeginScene();				// Setup the world, view, and projection matrices				SetupMatrices(panel2.Width, panel2.Height);        				// Meshes are divided into subsets, one for each material. Render them in				// a loop				for( int i=0; i<meshMaterials.Length; i++ )				{					// Set the material and texture for this subset					device.Material = meshMaterials;					device.SetTexture(0, meshTextures);    					// Draw the mesh subset					xMesh.DrawSubset(i);				}								if(active_panel == panel2)					Draw_Active_Rect(panel2);				//End the scene				device.EndScene();				//device.Present();				sc_1.Present(panel2);				pBackBuffer2.ReleaseGraphics();				//pause = true;


Do I make it correctly?
what differences came from swap chain or viewports?
When you initalize the device you set the sixe of the backbuffer:

presentParams[0].BackBufferWidth = panel1.Width;
presentParams[0].BackBufferHeight = panel1.Height;

When you resize you may need to call Reset() on the device with with these properties updated to reflect the new size of the viewport.
i repait that yes, i just do it!!

This topic is closed to new replies.

Advertisement