Sign in to follow this  
Fallen_Angel

Problem adding a quad to my scene

Recommended Posts

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

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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);

Share this post


Link to post
Share on other sites
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).

Share this post


Link to post
Share on other sites
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]

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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).

Share this post


Link to post
Share on other sites
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...

Share this post


Link to post
Share on other sites
Ok, managed to find the problem. It was being caused by the health bars that I have at the top of the screen. Basically I was creating a material colour for them and applying it to the device which was effecting my texture. I have changed my code to draw the texture first and the bars after and everything is looking fine. Time to go and create another problem for myself :)

Thanks again guys for the help on this.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this