Problem adding a quad to my scene

Started by
9 comments, last by Fallen_Angel 19 years, 4 months ago
I've just recently finished going through te Managed DirectX 9 book and I'm starting to write my own program. So far everything's been going fine following the book as I've managed to get basic functionality working with several models being drawn with keyboard movement. I am now trying to add a simple quad that will cover the screen to use as the floor for my objects to move on but am having no luck getting it to display properly in my scene. The code in the book works fine however the second that I use it in my program it starts to go all weird. I have even set up a new project only keeping the code required to draw a basic window and the quad using my scene parameters yet I seem to get a bunch of random lines being drawn rather than a quad as desired. Any idea where I am going wrong here?

private Device deviceGraphics = null;
private MatrixStack ms = new MatrixStack();
private VertexBuffer vbLevel = null;
float angle = 0.0f;

public void InitializeGraphics()
{
	//Set up device presentation parameters
	PresentParameters presentParams = new PresentParameters();
	Format current = Manager.Adapters[0].CurrentDisplayMode.Format;
	presentParams.Windowed = true;
	presentParams.SwapEffect = SwapEffect.Discard;
	presentParams.AutoDepthStencilFormat = DepthFormat.D16;
	presentParams.EnableAutoDepthStencil = true;
	presentParams.BackBufferFormat = current;
	presentParams.BackBufferCount = 1;
	presentParams.BackBufferWidth = this.Width;
	presentParams.BackBufferHeight = this.Height;
	//Set up device
	int adapterOrdinal = Manager.Adapters.Default.Adapter;
	CreateFlags flags = CreateFlags.SoftwareVertexProcessing;
	//Check for pure hardware device support
	Caps caps = Manager.GetDeviceCaps(adapterOrdinal, DeviceType.Hardware);
	if (caps.DeviceCaps.SupportsHardwareTransformAndLight)
		flags = CreateFlags.HardwareVertexProcessing;
	//Check if pure device is supported
	if (caps.DeviceCaps.SupportsPureDevice)
		flags |= CreateFlags.PureDevice;
	//Create device and device reset hook
	deviceGraphics = new Device(adapterOrdinal, DeviceType.Hardware, this, flags, presentParams);
	deviceGraphics.DeviceReset += new System.EventHandler(this.OnDeviceReset);
	OnDeviceReset(deviceGraphics, null);
	//Create vertex buffer
	vbLevel = new VertexBuffer(typeof(CustomVertex.PositionTextured), 6, deviceGraphics, 
Usage.Dynamic | Usage.WriteOnly, CustomVertex.PositionTextured.Format, Pool.Default);
	vbLevel.Created += new EventHandler(this.OnVertexBufferCreate);
	OnVertexBufferCreate(vbLevel, null);
}

private void OnVertexBufferCreate(object sender, EventArgs e)
{
	VertexBuffer buffer = (VertexBuffer)sender;
	CustomVertex.PositionColored[] verts = new CustomVertex.PositionColored[6];
	verts[0] = new CustomVertex.PositionColored(-1.0f, 1.0f, 1.0f, Color.Lime.ToArgb());
	verts[1] = new CustomVertex.PositionColored(1.0f, 1.0f, -1.0f, Color.Red.ToArgb());
	verts[2] = new CustomVertex.PositionColored(-1.0f, 1.0f, -1.0f, Color.Lime.ToArgb());
	verts[3] = new CustomVertex.PositionColored(-1.0f, 1.0f, 1.0f, Color.Lime.ToArgb());
	verts[4] = new CustomVertex.PositionColored(1.0f, 1.0f, 1.0f, Color.Lime.ToArgb());
	verts[5] = new CustomVertex.PositionColored(1.0f, 1.0f, -1.0f, Color.Blue.ToArgb());
	buffer.SetData(verts, 0, LockFlags.None);
}

private void OnDeviceReset(object sender, EventArgs e)
{
	Device dev = (Device)sender;
	dev.Transform.Projection = Matrix.OrthoLH(this.Width/10, this.Height/10, 1.0f, 1000.0f);
	dev.Transform.View = Matrix.LookAtLH(new Vector3(0, 0, 100.0f), new Vector3(), new Vector3(0,1,0));
	dev.RenderState.Lighting = false;
}

protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
{
	deviceGraphics.Clear(ClearFlags.Target | ClearFlags.ZBuffer, System.Drawing.Color.Black, 1.0f, 0);
	deviceGraphics.BeginScene();
	deviceGraphics.VertexFormat = CustomVertex.PositionColored.Format;
	deviceGraphics.RenderState.NormalizeNormals = true;
	DrawGameLevel();
	deviceGraphics.EndScene();
	deviceGraphics.Present();
	this.Invalidate();
}

private void DrawGameLevel()
{
	deviceGraphics.SetStreamSource(0, vbLevel, 0);
	angle += 10.0f;
	ms.Push();
	ms.RotateAxis(new Vector3(0,1,0), Geometry.DegreeToRadian(angle));
	deviceGraphics.SetTransform(TransformType.World, ms.Top);
	ms.Pop();
	deviceGraphics.RenderState.FillMode = FillMode.WireFrame;
	deviceGraphics.DrawPrimitives(PrimitiveType.TriangleList, 0, 2);
}


Thanks
Advertisement
Well I managed to work this one out eventually by starting again and working my way up. I have come across another problem though...it never ends. This is how my ground now looks with the texture applied. However when I move the exact same code over into my game, this is the result. I've been through the code and can't see anything obvious that would conflict. Is there some setting that I could be missing
You're not setting tex-coords at all (from what I could see).

You need to set texcoords in order to use textures.
Sirob Yes.» - status: Work-O-Rama.
Yes, first you're going to need to add texture coordinates to it, so you'll likely want to define it as PositionNormalTextured. Secondly, since it's just a quad you can reduce the size of it by using a TriangleStrip. This will cut it down from 6 points to 4 points. Finally, you setting all your Y values to be 1... this will work but as soon as you try and start moving the quad around you'll run into problems since it is not centered on the origin. A quad should only be drawn in a 2 dimensional plane. Here is the code I use with my quad, if it helps.

			// Create a quad			CustomVertex.PositionNormalTextured[] quad = new CustomVertex.PositionNormalTextured[4]				{					new CustomVertex.PositionNormalTextured(					-1.0f, 0.0f, 1.0f,					0.0f, 1.0f, 0.0f,					0, 0),					new CustomVertex.PositionNormalTextured(					1.0f, 0.0f, 1.0f,					0.0f, 1.0f, 0.0f,					1, 0),					new CustomVertex.PositionNormalTextured(					-1.0f, 0.0f, -1.0f,					0.0f, 1.0f, 0.0f,					0, 1),					new CustomVertex.PositionNormalTextured(					1.0f, 0.0f, -1.0f,					0.0f, 1.0f, 0.0f,					1, 1)				};			vb = new VertexBuffer(typeof(CustomVertex.PositionNormalTextured),				4, device, Usage.Dynamic | Usage.WriteOnly, 				CustomVertex.PositionNormalTextured.Format, Pool.Default);			vb.SetData(quad, 0, LockFlags.None);
Sorry, I probably should have posted my updated code with the texture information. It basically creates a grid of quads and textures them correctly as shown in the first image in my pst above, however doesn't add the textures as shown in my second image. Anyway it is as follows:
public void InitializeGraphics(){	//Create vertex buffer	vbLevel = new VertexBuffer(typeof(CustomVertex.PositionTextured), 6, deviceGraphics,	Usage.Dynamic | Usage.WriteOnly, CustomVertex.PositionTextured.Format, Pool.Default);	vbLevel.Created += new EventHandler(this.OnVertexBufferCreate);	OnVertexBufferCreate(vbLevel, null);	texLevel1 = TextureLoader.FromFile(deviceGraphics, @"resources/level1.bmp");}private void OnVertexBufferCreate(object sender, EventArgs e){	VertexBuffer buffer = (VertexBuffer)sender;	CustomVertex.PositionTextured[] verts = new CustomVertex.PositionTextured[6];	verts[0] = new CustomVertex.PositionTextured(-5.0f, 0.0f, 5.0f, 0.0f, 0.0f);	verts[1] = new CustomVertex.PositionTextured(5.0f, 0.0f, -5.0f, 1.0f, 1.0f);	verts[2] = new CustomVertex.PositionTextured(-5.0f, 0.0f, -5.0f, 0.0f, 1.0f);	verts[3] = new CustomVertex.PositionTextured(-5.0f, 0.0f, 5.0f, 0.0f, 0.0f);	verts[4] = new CustomVertex.PositionTextured(5.0f, 0.0f, 5.0f, 1.0f, 0.0f);	verts[5] = new CustomVertex.PositionTextured(5.0f, 0.0f, -5.0f, 1.0f, 1.0f);	buffer.SetData(verts, 0, LockFlags.None);}private void DrawGameLevel(){	Texture tex = null;	deviceGraphics.SetStreamSource(0, vbLevel, 0);	tex = texLevel1;	for (int i = 0; i < 11; i++)	{		for (int j = 0; j < 7; j++)		{			ms.Push();			ms.RotateAxis(new Vector3(1.0f, 0.0f, 0.0f), Geometry.DegreeToRadian(90.0f));			ms.Translate((float)(46-(i*10)), (float)(25-(j*10)), 0.0f);			deviceGraphics.SetTransform(TransformType.World, ms.Top);			ms.Pop();			deviceGraphics.RenderState.Lighting = false;			deviceGraphics.SetTexture(0, tex);			deviceGraphics.DrawPrimitives(PrimitiveType.TriangleList, 0, 2);			deviceGraphics.RenderState.Lighting = true;		}	}}

Also rjackets, I tried using the code that you gave me but it only rendered half of the quad (only one triangle rather than both).
perhaps your backface culling is on? change it to CULLNONE (I don't know where it is in C#).

Also, try disabling lighting if it isn't already disabled.
Sirob Yes.» - status: Work-O-Rama.
Quote:
Also rjackets, I tried using the code that you gave me but it only rendered half of the quad (only one triangle rather than both).

Oh, sorry about that. I use the quads for particle effects so I have culling set to none -- that shouldn't really make a difference since all the normals are specified to be pointing up, but try this out anyway

device.RenderState.CullMode = Cull.None

should fix the problem. I'll also post the draw code here too -- is it possible you didn't switch from TringleList to TriangleStrip?

			device.VertexFormat = CustomVertex.PositionNormalTextured.Format;			device.SetStreamSource(0, vb, 0);			device.DrawPrimitives(PrimitiveType.TriangleStrip, 0, 2);

EDIT: I just checked did a test on my code and it wont render correctly if you have it set to Cull.Clockwise, but Cull.CounterClockwise works perfectly (which is the default I believe). I expect this probably means the problem is not with the culling state, but try setting it to none anyway.

[Edited by - rjackets on December 4, 2004 8:16:14 PM]
Quote:Original post by rjackets
is it possible you didn't switch from TringleList to TriangleStrip?


That was exactly my problem with only drawing half of the quad. I am still having the same problem however with drawing the texture. It shows up fine in my blank project but not in my game...time to start diging through that again from the start and seeing where the conflict is. Thanks heaps for the help so far.
Check what you set for all the texture stages. Perhaps you're setting one of them in your project and not setting it in the blank one and using the default value instead.

Also, make sure your lighting is off and that culling is set to none (I'm assuming it isn't drawing anything at all, and not a flat quad).
Sirob Yes.» - status: Work-O-Rama.
Quote:Check what you set for all the texture stages. Perhaps you're setting one of them in your project and not setting it in the blank one and using the default value instead.

That's the plan for tonight hopefully if I get some free time.
Quote:Also, make sure your lighting is off and that culling is set to none (I'm assuming it isn't drawing anything at all, and not a flat quad).

Lighting and culling is set up correctly. If you look at the second image that I posted before, the whole brown area is my grid of quads being rendered. I have tried this with three different textures (brown, green and grey). They turn up fine in the blank project but just appear as one colour in my game, either brown, green or grey. Which is what leads me to believe that it isn't a problem with my drawing but some value that I'm setting elsewhere that is effecting it. Too bad I'm stuck at work now and can't try to find out why...

This topic is closed to new replies.

Advertisement