Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Hardware independent rendering 1

Status
Not open for further replies.

dalchri

Programmer
Apr 19, 2002
608
0
0
US
I have an app that renders 3D view of the planets and moons in our solar system. This app doesn't do any animations, only still shots so performance is no issue.

I've broken this app twice now only by changing drivers on my video card. The symptoms include light green lines that extend across my screen and appear to be triggered by code that writes text to the screen.

My instinct was to use a software device but I can only get a hardware device to work.

My topmost priority is getting consistent, dependable results out of this app on any computer. How do I go about this?
 
I've had problems like that before. Once I sent an incorrect parameter to DrawIndexedPrimitive and it didn't care, then I sent the program to a friend and it restarted his computer. Different video cards can be messed up by different things. Chances are you are doing something wrong somewhere. Try posting code that is associated with the text if you can't figure out what the problem is. It's far more likely that you are doing something wrong than that your drivers are broken.
 
Thanks for your help. I'll try to narrow it down. The defects are visual and... kind of hard to describe.

I have to point out that I have used the Reference DeviceType and it works fine.

For example, I've got a geodesic sphere that casts a shadow. The shadow is a series of triangle pairs pointing directly away from the only point light in the scene. The defect I see looks like a ring of the vertices at the end of the shadow.

Another defect is light green, blue, pink horizontal lines that come and go. These lines appear behind the objects in the scene.

Another defect appears to be one of the buffers not clearing properly. For example, I draw text labels on some of the moons to identify them. If I resize my window, you'll see part of the text label at the old location of the text label before the resize.

I've had similar problems like this before and I solved it with CreateFlags.FpuPreserve. Something I'm not sure is if DirectX is up to handling the large range of sizes and distances I'm working with. My Perspective Projection can only be 1º wide at most as compared to a normal 90º view. This is because my object sizes and distances are to scale, just like you'd be looking at them up in the sky.

Here goes with the code. Its not working code because I'll try to concentrate on the parameters that I'm using and vertex types:

Code:
//Device creation-------------------------
		PresentParameters prm = new PresentParameters();

		prm.Windowed = true;
		prm.SwapEffect = SwapEffect.Discard;
		prm.EnableAutoDepthStencil = true; 
		prm.AutoDepthStencilFormat = DepthFormat.D24S8;
		prm.BackBufferCount = 1;
		prm.BackBufferFormat = Format.X8R8G8B8;
		prm.BackBufferHeight = pnlMoon.ClientRectangle.Bottom - pnlMoon.ClientRectangle.Top;
		prm.BackBufferWidth = pnlMoon.ClientRectangle.Right - pnlMoon.ClientRectangle.Left;

//pnlMoon is a panel on my form used to display the renderings

		m_dev = new Device(
			0, DeviceType.Hardware, pnlMoon, 
			CreateFlags.SoftwareVertexProcessing |
			CreateFlags.FpuPreserve, 
			prm);
		m_dev.DeviceReset += new System.EventHandler(this.OnResetDevice);

//I found CreateFlags.FpuPreserve necessary because DirectX
//has trouble telling if a moon is in front of or behind a
//planet without the extra precision in the Z buffer

//OnReset-------------------------------------
//Only one light (the sun) that does not drop off with distance
		if (this.WindowState != FormWindowState.Minimized) {
			m_dev.RenderState.Lighting = true;
			m_dev.RenderState.ZBufferEnable = true;
			m_dev.RenderState.SourceBlend = Blend.SourceAlpha;
			m_dev.RenderState.DestinationBlend = Blend.InvSourceAlpha;

			m_dev.Lights[0].Type = LightType.Point;
			m_dev.Lights[0].Diffuse = Color.White;
			m_dev.Lights[0].Attenuation0 = 1;
			m_dev.Lights[0].Attenuation1 = 0;
			m_dev.Lights[0].Attenuation2 = 0;
			m_dev.Lights[0].Enabled = true;
//The location of the light is set later
		}

//Rendering---------------------------------------
//I use indexed PositionNormalTextured vertices
//to draw the moons and the planet
		m_dev.Clear(ClearFlags.Target | ClearFlags.ZBuffer | ClearFlags.Stencil, 
			pnlMoon.BackColor, 1f, 0);
		m_dev.BeginScene();

		m_dev.Transform.Projection = Matrix.PerspectiveFovLH( 
			intSign1 * pnlMoon.Height / plt.Zoom, 
			((float) intSign2 * pnlMoon.Width) / pnlMoon.Height, 
			(float) (Form.Factor * (plt.r - 0.25)),  (float) (Form.Factor * (plt.r + 0.25)));
//Clipping planes are set up slighty in front of and behind
//of the planet and its moons


		if (this.Vertices == null) {
			Shape.Geodesic(
				this.Radius, this.Flattening, 
				m_bytOrder, out m_vrt, out m_sht);
			m_vbf = new VertexBuffer(
				typeof(CustomVertex.PositionNormalTextured), 
				this.Vertices.Length, this.Device, Usage.WriteOnly, 
				CustomVertex.PositionNormalTextured.Format, 
				Pool.Default);
			m_vbf.Created += 
				new EventHandler(this.OnCreateVertexBuffer);
			m_idx = new IndexBuffer(
				typeof(short), this.Indices.Length, this.Device, 0, Pool.Default);
		}
		if (m_blnLoad) {
			m_vbf.SetData(this.Vertices, 0, 0);
			m_idx.SetData(this.Indices, 0, 0);
		}

		this.Device.Transform.World = this.World;
		this.Device.Material = this.Material;
		this.Device.SetTexture(0, m_txt);
		this.Device.Indices = m_idx;
		this.Device.SetStreamSource(0, m_vbf, 0);
		this.Device.VertexFormat = CustomVertex.PositionNormalTextured.Format;
			this.Device.DrawIndexedPrimitives(
				PrimitiveType.TriangleList, 0, 0, this.Vertices.Length, 0, this.Indices.Length / 3);	

		m_dev.EndScene();
		m_dev.Present();

I have omitted the code that draws the text labels and the shadows to try to keep this digestable. Thank you again for looking over this!
 
Ok, I did narrow it down to one line of code:

Code:
this.Device.SetTexture(0, m_txt);
this.Device.Indices = m_idx;
this.Device.SetStreamSource(0, m_vbf, 0);
this.Device.VertexFormat = CustomVertex.PositionNormalTextured.Format;
//This line causes the problem
//If I draw this as a TriangleList instead, there is no problem
//Perhaps you shouldn't user PositionNormalTextured vertices???
this.Device.DrawIndexedPrimitives(
   PrimitiveType.PointList, 0, 0, this.Vertices.Length, 0, this.Indices.Length);

Some of the moons I draw with a texture, others I draw with just a single point colored white.

The ones that I draw with a texture have a problem though. If I zoom out too far, they turn into a point, but are too dim to be seen properly. My solution was to draw them as a point list when they drop below 4 pixels in size on the screen rather than as a triangle list. They would retain the coloration of the texture and remain bright enough to look good.

Should I not be using PositionNormalTextured vertices with a call to a PointList DrawPrimitives?

I'm pretty sure that I've got the dimensions right so that I'm not overruning my buffer. After all, the exact same buffer works fine with a call to a DrawPrimitives with a TriangleList. (I use this.Indices.Length / 3 for that call)

A bigger question. How do I know that once I get this out on someone else's computer with a different video card that I don't find more problems?

I think what I might do is just lengthen my normals or try to crank up my light when I draw the moons.
 
>> Should I not be using PositionNormalTextured vertices with a call to a PointList DrawPrimitives?

I'm not sure if that is an invalid format for points. I've never read anything that said it was, but it is a very odd format. It is wierd to think of points having a normal, at least. Are you disabling lighting before rendering the points? If not, you probably should try it and see if that fixes it. I'm not sure how lighting would work with points. Anyway, if that doesn't work I would recommend, as you suggest, cranking up your lights when you render the moons.

>> How do I know that once I get this out on someone else's computer with a different video card that I don't find more problems?

You don't! You'll just have to test it on many different computers and see if it doesn't work correctly on some of them.
 
Guess that's why there's a list of supported video cards on the side of most game software boxes.

Thanks for the help!
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top