Code behaves differently on 3 different computers. ?
I have a C# application that displays fairly simple 3d models (mostly lines and a few faces). I am using Managed DirectX 9 August 2005. On one computer (the development machine) the program runs fine. On another computer, the lines don't draw (it's a call to drawIndexedPrimitives, type lineList) but the meshes do draw...and on two other computers, when I open the Form that has the 3d control, the computer freezes (before the form ever opens) and must be shutdown with the power switch. I know this is a question with not much detail...but I'm not sure how much detail is needed to be helpful. It's such a spastic issue, I'm not even sure where to begin debugging. Any suggestions at all would be very helpful.
Thanks.
[737 byte] By [
efindley] at [2007-12-17]
What graphics cards do the three PCs have ?
The development machine (the one that works) has an NVIDIA Quadro FX 3000
the one that doesn't draw any lines has a Mobile Intel 915GM/GMS, 910GML Express Chipset
And one of the ones that crashes is a Mobility Radeon 7500.
all of them have up to date drivers.
Let me try to add a little more detail to this problem description. The primitives that do not draw (on the machine that draws some and not others) all seem to be calls drawIndexedPrimitives. The calls to drawPrimitives all draw fine.
I'm wondering if there are problems with drawIndexedPrimitives. The 3d drawing in this app was developed by two different people (myself being one of them) and so some of the drawing methods and styles are different. It's an MDI Windows form app and we have two different 3d view windows. One draws the model as a whole, the other focuses in on a smaller portion of the model and allows user input to draw some objects. The 3d view that shows the whole model has no calls to drawIndexedPrimitives and it will open just fine without crashing a computer. The window that crashes the computer has several calls to indexedPrimitives. I'm kind of thinking out loud here coming up with differences between the two forms and therefore maybe the reason for the crash.
I hope this is a little more informative about what's going on in my app and will help someone shed some light on my problem.
Thanks again.
It's very likely that the code you're using to draw has an error in it. Different vendors handle things differently and I seem to recall that NVIDIA is more tolerant about incorrect values being passed to an indexed draw.
If you want to show a code snippet I can probably help more.
First things first. Just to make sure, does the program run correctly on all 3 machines using the reference rasterizer? The refrast bypasses the hardware (but, obviously, runs very slowly since it's all software rendering)
Okay...I changed the device type to reference and it worked on the Radeon, but not on the mobile Intel. The mobile intel is the machine that doesn't draw the lines if they're indexed. For that machine, I had to build an install. The radeon is a development machine, so the project was run from inside the IDE. I don't know if that makes a difference. I don't know a lot about DirectX (I had to jump in with both feet for this project, so I'm learning as I go.) Just for kicks, I changed the device type to software and it didn't work on the mobile intel either. Both reference type and software type give me a null reference error when I try to start directX.
But I did learn that changing the type to reference made the machine that crashed originally no longer crash.
Some code:
This is what is done when we draw line strips. It resides in a method called DrawShape.
| |
// build vertex buffer Point3d[] points = shape.ToPointArray(); int numVerts = points.Length; VertexBuffer vb = new VertexBuffer( typeof(CustomVertex.PositionColored), numVerts, this.device, Usage.WriteOnly, CustomVertex.PositionColored.Format, Pool.Managed); // build index buffer int[] indices = new int[numVerts+1]; for (int i=0; i < numVerts; i++) { indices[ i ] = i; } indices[numVerts] = 0; IndexBuffer ib = new IndexBuffer( typeof(int), indices.Length, this.device, Usage.WriteOnly, Pool.Managed); ib.SetData(indices,0,LockFlags.None); // set vertices CustomVertex.PositionColored[] data = (CustomVertex.PositionColored[])vb.Lock( 0, typeof(CustomVertex.PositionColored), LockFlags.None, numVerts); for (int i=0; i < numVerts; i++) { Point3d point = points[ i ]; data[ i ].Color = color.ToArgb(); data[ i ].X = (float)point.X; data[ i ].Y = (float)point.Y; data[ i ].Z = (float)point.Z; } vb.Unlock(); // draw outline of shape this.device.RenderState.FillMode = FillMode.WireFrame; this.device.SetStreamSource(0, vb, 0); this.device.Indices = ib; this.device.VertexFormat = CustomVertex.PositionColored.Format; this.device.DrawIndexedPrimitives( PrimitiveType.LineStrip, 0,0,numVerts,0,numVerts); ib.Dispose(); vb.Dispose(); |
The other call to drawIndexedPrimitives is a line list...we are drawing a bounding box.
| |
int numVerts = 8; VertexBuffer vb = new VertexBuffer( typeof(CustomVertex.PositionColored), numVerts, this.device, Usage.WriteOnly, CustomVertex.PositionColored.Format, Pool.Managed); // build index buffer int[] indices = {0,1,1,2,2,3,3,0,0,4,1,5,2,6,3,7,4,5,5,6,6,7,7,4}; IndexBuffer ib = new IndexBuffer( typeof(int), indices.Length, this.device, Usage.WriteOnly, Pool.Managed); ib.SetData(indices,0,LockFlags.None); // set vertices CustomVertex.PositionColored[] data = (CustomVertex.PositionColored[])vb.Lock( 0, typeof(CustomVertex.PositionColored), LockFlags.None, numVerts); // color for (int i=0; i < numVerts; i++) { data[ i ].Color = this.boundingBoxColor.ToArgb(); } // geometry data[0].X = data[1].X = data[4].X = data[5].X = (float)this.stairway.Bounds.xmin; data[2].X = data[3].X = data[ 6 ].X = data[7].X = (float)this.stairway.Bounds.xmax; data[0].Y = data[3].Y = data[4].Y = data[7].Y = (float)this.stairway.Bounds.ymin; data[1].Y = data[2].Y = data[5].Y = data[ 6 ].Y = (float)this.stairway.Bounds.ymax; data[0].Z = data[1].Z = data[2].Z = data[3].Z = this.zmin; data[4].Z = data[5].Z = data[ 6 ].Z = data[7].Z = this.zmax; vb.Unlock(); this.device.RenderState.FillMode = FillMode.WireFrame; this.device.SetStreamSource(0, vb, 0); this.device.Indices = ib; this.device.VertexFormat = CustomVertex.PositionColored.Format; this.device.DrawIndexedPrimitives( PrimitiveType.LineList, 0,0,numVerts,0,12); ib.Dispose(); vb.Dispose(); |
I think these are the only two ways drawIndexedPrimitives is called.
I don't have my Managed docs here, but isn't the last parameter to DrawIndexedPrimitives supposed to be the number of primitives, yet you have a line where it's set to numVerts. So it may be that you're trying to render of the end of your buffers. Well, in this function we're drawing a closed polygon (wireframe) so the number of vertices is equal to the number of lines.
well, brute force testing has resulted in my solving the problem of the disappearing lines. I changed my index buffers from type int to type short and presto!...it worked. Now I'd like to know why this happened. Any ideas?
I'm still working on the crashing problem, though.
Thanks for all the suggestions so far.
w.r.t to the index buffers... isn't an "int" 32bits and a "short" 16bits? they would correspond to different IB formats. Support for a 32bit index buffer is relatively rare - particularly when you've mentioned such old hardware (and integrated variants). You really should enumerate all the features you're using during application load

hth
Jack
Neither the intel 915G nor the Radeon 7500 support 32-bit indices. You need to check D3DCAPS9:
MaxVertexIndex:
Maximum size of indices supported for hardware vertex processing. It is possible to create 32-bit index buffers by specifying D3DFMT_INDEX32; however, you will not be able to render with the index buffer unless this value is greater than 0x0000FFFF.
cgraus wrote: |
| What graphics cards do the three PCs have ? |
|