Hello Everyone,
I am working on an isometric game pseudo 3D but using Direct3D. Primarily I am using one call to draw everything... (Sprite.Draw). Infact I even use only one sprite to draw all the images to the screen and have written all other collision detection and transforms myself using surface level operations... The only real hardware accelerated feature I am taking advantage of is color and alpha blending.
Everything has been going fantastic and I am getting ready for a preview release in a few weeks but then I decided to test it on two more machines to make sure everything worked. Almost everything did... but some images are not being drawn to the screen correctly they will have shaded lines under or around them that were not there when running on my dev machine under the SDK (Everything draws perfectly on dev machine). (Oddly enough the lines appear as if they are on the same texture but 1 pixel down/over from the source image rectnagle). I am positive my source rectangles are correct and have verified this at run time by printing the variables out. I am not sure if this is a camera angle thing I have read other articles hinting at this but do not describe the problem well or provide a recommendation. I am getting really frustrated with this one... Hopefully someone can help me get rid of these lines... Below is some additional facts:
Thanks for all your help it is greatly appreciated
-SDK Version: February 2006
-Test Machine Versions: Redist from February 2006 SDK
-Screenshot: Screen Shot
Initialization and Drawing Code:
//Image Drawing Code:
private void DrawImage(Microsoft.DirectX.Direct3D.Texture Surf,System.Drawing.Rectangle SourceRect, int LocX, int LocY)
{
if (Surf != null)
{
System.Drawing.Rectangle imgrect = this.CheckClipBounds(SourceRect, ref LocX, ref LocY);
if (imgrect.Width > 0 && imgrect.Height > 0)
{
Vector3 drawLoc = new Vector3((float)LocX, (float)LocY, 0.0f);
d3dSprite.Draw(Surf, imgrect, Vector3.Empty, drawLoc, System.Drawing.Color.FromArgb(255, 255, 255, 255));
}
}
}
//Initialization
public bool InitializeXScreen(System.Windows.Forms.Control BoundWindow, bool window)
{
try
{
//Common DirectX setup calls...
PresentParameters presentParams = new PresentParameters();
presentParams.Windowed = window;
presentParams.SwapEffect = SwapEffect.Discard;
if (!window)
{
presentParams.BackBufferWidth = this.Width;//D3D.Manager.Adapters.Default.CurrentDisplayMode.Width;
presentParams.BackBufferHeight= this.Height;//D3D.Manager.Adapters.Default.CurrentDisplayMode.Height;
presentParams.BackBufferCount = 1;
presentParams.FullScreenRefreshRateInHz = D3D.Manager.Adapters.Default.CurrentDisplayMode.RefreshRate;
presentParams.BackBufferFormat = D3D.Manager.Adapters.Default.CurrentDisplayMode.Format;//D3D.Format.Unknown;//D3D.Manager.Adapters.Default.CurrentDisplayMode.Format;//Format.Unknown;
}
else
{
presentParams.PresentationInterval = PresentInterval.One;
presentParams.BackBufferFormat = D3D.Manager.Adapters.Default.CurrentDisplayMode.Format;
}
presentParams.AutoDepthStencilFormat = DepthFormat.D16;
presentParams.EnableAutoDepthStencil = true;
// Store the default adapter
int adapterOrdinal = D3D.Manager.Adapters.Default.Adapter;
CreateFlags flags = CreateFlags.SoftwareVertexProcessing;
D3D.Caps caps = D3D.Manager.GetDeviceCaps(adapterOrdinal, D3D.DeviceType.Hardware);
// Do we support hardware vertex processing
if (caps.DeviceCaps.SupportsHardwareTransformAndLight)
// Replace the software vertex processing
flags = CreateFlags.HardwareVertexProcessing;
displayDevice = new D3D.Device(0, D3D.DeviceType.Hardware, BoundWindow, flags, presentParams);
d3dSprite = new Sprite(ScreenDevice);
fon = new Microsoft.DirectX.Direct3D.Font(displayDevice,gdiFont);
//device.DeviceReset += new System.EventHandler(this.OnResetDevice);
//OnResetDevice(device, null);
}
catch (DirectXException)
{
return false;
//MessageBox.Show("Exception is " + e.ErrorString);
// Catch any errors and return a failure
}
fonts = new System.Collections.SortedList(); //Initialize font list
return true;
}
//From Image Loader class all D3D specific Code
public void Load()
{
if (!IsLoaded())
{
ImageInformation inf = TextureLoader.ImageInformationFromFile(FileName);
this.Width = inf.Width;
this.Height = inf.Height;
surf = TextureLoader.FromFile(GameInstance.GlobalScreen.ScreenDevice, FileName, inf.Width, inf.Height,
1, 0, Format.A8R8G8B8, Pool.Managed, Filter.Point, Filter.Point, (int)(tcolorkey | 0xff000000));
}
}

Bad Lines Appear with Sprite.Draw with Redist. but not with SDK
Santiagon
The "Alternate Pixel Center" setting is specific to the ATI drivers and is intended to only be enabled in order to work around buggy games that don't do texel alignment correctly. Unfortunately there are a lot of games that get this wrong, but it doesn't sound like your game is one of them. It's probably a problem with the Intel Extreme drivers, so you can try asking your users to upgrade the latest drivers and see if that fixes the problem. If that doesn't work your only solution may be to put a specific check in your code for these buggy Intel drivers and conditionally adjust your screen coordinates.
Atlantaazfinest
I will try Filter.Linear... I believe I have tried Filter.None on the loading of the textures but I will try again to be sure.
In regards to the camera you will have to forgive me as I am not so familier with the camera operations, (I am mainly a 2D programmer... What do I need to do to rotate the camera is it the device.Transform.World/View/Projection ) Basicly what should I call and what arguments (IE Camera Angle)should I use...
I believe the machines that do not like it both have Intel Extreame Onboard cards... My development machine is an ATI (non Onboard)... It just seems like such a basic function... forgive my frustration, I am just reaching the limitations of my graphics knowledge.
Thanks for your help and patience
bennettdan
Hi,
Thanks for pointing me to the article, but I am not using quads to render 2d sprites I do not believe that it applies to Sprite.Draw()... The function should encapsulate this functionality... Atleast none of the 2D using D3D examples I have seen have done anything special when drawing 2D sprites. The way it is documented is that you pass it an integer based rectangle of source coordinates and its supposed to render that rectangle from the source texture to the video card memory with no transformation. I am only a beginner when it comes to many of the 3D functions... (One reason I am trying to stick to the 2D ones).
It seems like there should be a "magic button" for this one... other 2D sprite examples I have run on the test machiens work fine, I do not understand I have compared the code dozens of time...
Thanks again
Chris
tamorgen
Well I found out a few things after doing some more research today.. Unfortunatlly I havent found a solution yet but Heres what I have found out after looking at various 2d examples provided from the MS SDK.
1. Even MS samples suffer from this defect..
2. Adjusting the destination Location X,Y +- 0.g where g is some floating point number < 1 causes the lines to move up or down but cant seem make them go away.
3. Found out why my PC does not do this... the problem is related to "Alternate Pixel Center"(it was disabled) I enabled this flag on my video D3D settings and it resulted in the same as the test PCs. The question is how do I always disable this at runtime on all pcs. (Note the intel extremes dont even have D3D properties associated with the card so you cant change it there).
But ultimately how do I fix this anymore ideas anyone.. Hopefully we are getting close to the solution... I feel like we are and Thank You for all your help guys
ruckazz
Maybe, or maybe not. I could stretch my texture quad in any direction, and even rotate it, and no artifacts would occur.
Only when I "inverted" the quad with non-orthonormal (or is it orthogonal ) texture UVs, would artifacts occur. That is, when I passed in a u0 that was greater than u1, or v0 greater than v1. As if the hardware couldn't get it right sampling a texture in reverse.
The articale you referred to seems to be discussing texturing issues just under normal conditions. Which like I said, I've never had problems with.
Appel
When I want to draw a textured quad (i.e. sprite) I have to supply uv coords. That's just so I could put many images in one texture.
Well, one day I wanted to flip the sprite, so I reversed the order of the u and v I sent in my draw function, depending on whether I wanted a hflip or vflip. And the weirdest thing happend: I would get one extra line on the right or bottom of my sprite that wasn't supposed to be there. Kinda like what it looks like your getting. And it wouldn't happen all the time. So I think it was hardware dependent, plus whatever I had my quad scaled to.
The way I fixed it was to conditionaly check if hflip is desired, and if so, pass in u1 - 0.001f, v0, u0, v1. Then no more extra lines.
I'm not sure what the equivelent fix is for those who use non-uv function calls, maybe to subtract half a pixel from your width and height parameters (if you're using floats)
tirengarfio
Yes you are correct, I've never had to do it with sprites either - it just looks like the symptoms matched.
I looked at the images you sent close up and if its not pixel/texel mapping problems there is certainly some odd filtering going on. e.g. look at the keys. In the good image the edges are crisp. In the bad images the edges are aliased. Same if you look at your rock textures - its as if they are being drawn fractional pixels away from where they are supposed to be. Yes this could be caused by bad camera position but that should be the same on both machines. If you change the camea position - zoom in/out can you get any artifacts on your 'good' machine
You could try changing the first Filter.Point to Filter.Linear or even filter.none (though this usually gives other kinds of artifacts).
(note that since you don't have any mipmaps generated the second Filter.Point can be changed to Filter.None - I dunno if it will have any effect though).
The other thing to look at is the video cards on the machines that it doesn't work on - are they both NVidia and your is ATI Look up the caps in the SDK spreadsheet and see if there is anything odd common on thos machines.
Sweed
It looks like a pixel/texl mismatch problem to me, though I can't explain why it doesn't happen on your machine. See directly mapping texels to pixels in the native SDK docs
Note that unless you switched to the debug runtimes in the control panel then you are running the retail DirectX assemblies on your machine too.
fubnuts
Changing the filter used when loading your texture shouldn't make any difference because you're not resize the texture. Instead you might want to trying changing the filter used when drawing your sprites. By default the sprite class uses ansiotopic filtering, you can try changing that to linear or point. If using linear filtering fixes the problem then it's probably caused by a driver bug, if using point filtering fixes the problem then you may only be masking the problem. To change filter used you need to do so after calling the sprite class's Begin() method.
Other things you can try are running using debug runtime and see if any interesting debug messages are generated by your code. Try using the reference device to see what it draws. Make sure you're calling BeginScene() and EndScene(). These methods don't do anything on ATI and NVIDIA cards, but they're crucial with Intel graphics.
ChangLuo
Adjusting the screen coordinates would be acceptable if this is limited to one brand of video cards... I am having trouble getting this solution to completely work. Please read on...
What is the best way to find out how much to precisely offset my screen coordinates by... Right now I am adjusting the destination X,Y coordinates only Z I left at 0.0.
I suspected -0.5f if this problem is related to a floating point rounding error, this works perfectlly on my dev machine with the "alternate pixel center" enabled but when I run this on my other test machine -0.5f only fixes half the problem (getting rid of the line under the mouse cursor) but still leaves the lines left on the map. I have tried over 1000 different floating point offsets randomly on it (to see the effects .5 has only a minor effect and lessons the space but does not eliminate it) nothing seems to really help the map grid that is appearing. Do I need to adjust the Z too Any ideas
Thanks again for all your help
Erick-Flores
It sounds like you weren't offsetting your x and y screen coordinates correctly like explained in the SDK documentation on correctly aligning texels to pixels that ZMan linked to above.