   D3D 9 Strange "Ghost" artifact
  Hi All,Since leaving uni and getting a real job I haven't been around on these board a lot, mainly due to the complete lack of programming I have done outside of the office, however recently I decided to start learning 3D programming from a technical standpoint using native Direct X (In the past I have always used wrappers, Ogre, XNA etc).I have been following a few tutorials learning the syntax and how things fit together, and have come to the topic of lighting, I quickly hacked together my first lighted demo app and amnoticing a very strange occurance that I cannot explain and was hoping a fellow board member could enlighten me as to what is happening.The program is a simple app that sets up a cube, renders it and allows the user to interact using the keyboard to translate, rotate and scale it. With the D3DRS_LIGHTING renderstate set to false the app works fine, you are able to move the cube around with no problems, (Code listing 2 below). The problem occurs when I refactor the code slightly to turn D3DRS_LIGHTING on and setup one light. The app initially works fine, the cube is correctly lit throught the user moving it, however precicely 6 seconds after the program starts a second cube "Appears" at the origin, this cube then procceeds to play back the motions of the original cube precicely 6 seconds after they happened, mirroring all movements, scaling changes and rotations.Now barring that I may have accidently stubled upon AI which is currently playing tricks with me and may soon take over the world, I am failing to remove/add bits of code to track down what exactly is causing this strange occurance.Thanks a lot for any help,ScottCode listings for D3D9 setup [1], the program with no lighting[2] and the program with lighting and strange behaviour[3] follow, aswell as my typedefs for a few of D3D's types:#include "DeviceManager.h"#include "ApplicationDisplay.h"namespace XF{  namespace GFX  {DeviceManager::DeviceManager(){  d3d   = NULL;  d3dDevice = NULL;}bool  DeviceManager::Init(HWND hWnd, ApplicationDisplay &appDisp){  d3d = Direct3DCreate9(D3D_SDK_VERSION);  if(!d3d)    return false;  ZeroMemory(&d3dPP, sizeof(d3dPP));  d3dPP.Windowed  = !appDisp.Fullscreen();  d3dPP.SwapEffect= D3DSWAPEFFECT_DISCARD;  d3dPP.hDeviceWindow   = hWnd;  d3dPP.BackBufferFormat    = D3DFMT_X8R8G8B8;  d3dPP.BackBufferWidth = appDisp.WindowWidth();  d3dPP.BackBufferHeight    = appDisp.WindowHeight();  d3dPP.EnableAutoDepthStencil  = TRUE;  d3dPP.AutoDepthStencilFormat  = D3DFMT_D16;  if(FAILED(d3d->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dPP, &d3dDevice)))  {    return false;  }  d3dDevice->SetRenderState(D3DRS_ZENABLE, true);  return true;}void  DeviceManager::Destroy(){  d3dDevice->Release();  d3d->Release();}void  DeviceManager::BeginFrame(){  d3dDevice->Clear(0, NULL, D3DCLEAR_TARGET,  D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);  d3dDevice->Clear(0, NULL, D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);  d3dDevice->BeginScene();}void  DeviceManager::EndFrame(){  d3dDevice->EndScene();  d3dDevice->Present(NULL, NULL, NULL, NULL);}  }}#include "TestGameScreen.h"#define CUSTOMFVF (D3DFVF_XYZ | D3DFVF_DIFFUSE)struct CustomVertex{  float x, y, z;  DWORD diffuse;};bool  TestGameScreen::OnInit(){  CustomVertex vertices[] =  {    { -1.0f, 1.0f, -1.0f, D3DCOLOR_XRGB(0, 0, 255), },    { 1.0f, 1.0f, -1.0f, D3DCOLOR_XRGB(0, 255, 0), },    { -1.0f, -1.0f, -1.0f, D3DCOLOR_XRGB(255, 0, 0), },    { 1.0f, -1.0f, -1.0f, D3DCOLOR_XRGB(0, 255, 255), },    { -1.0f, 1.0f, 1.0f, D3DCOLOR_XRGB(0, 0, 255), },    { 1.0f, 1.0f, 1.0f, D3DCOLOR_XRGB(255, 0, 0), },    { -1.0f, -1.0f, 1.0f, D3DCOLOR_XRGB(0, 255, 0), },    { 1.0f, -1.0f, 1.0f, D3DCOLOR_XRGB(0, 255, 255), },  };  short indices[] ={    0, 1, 2,// side 1    2, 1, 3,    4, 0, 6,// side 2    6, 0, 2,    7, 5, 6,// side 3    6, 5, 4,    3, 1, 7,// side 4    7, 1, 5,    4, 5, 0,// side 5    0, 5, 1,    3, 7, 2,// side 6    2, 7, 6,};  app->device.GetDevice()->CreateVertexBuffer(    24 * sizeof(CustomVertex),    0,    CUSTOMFVF,    D3DPOOL_MANAGED,    &vBuffer,    NULL);  app->device.GetDevice()->CreateIndexBuffer(    36 * sizeof(short),    0,    D3DFMT_INDEX16,    D3DPOOL_MANAGED,    &iBuffer,    NULL);  void* voidPtr;  vBuffer->Lock(0, 0, (void**)&voidPtr, 0);  memcpy(voidPtr, vertices, sizeof(vertices));  vBuffer->Unlock();  iBuffer->Lock(0, 0, (void**)&voidPtr, 0);  memcpy(voidPtr, indices, sizeof(indices));  iBuffer->Unlock();  D3DXMatrixLookAtLH( &viewMatrix,   &XF::GFX::Vector3(0.0f, 0.0f, 10.0f),   &XF::GFX::Vector3Zero,   &XF::GFX::Vector3Up);  D3DXMatrixPerspectiveFovLH( &projMatrix, D3DXToRadian(45), (float)app->device.GetPresentationParameters().BackBufferWidth /   (float)app->device.GetPresentationParameters().BackBufferHeight, 1.0f, 100.0f);  position = XF::GFX::Vector3Zero;  rotation = XF::GFX::Vector3Zero;  scale= XF::GFX::Vector3One;  ZeroMemory(&light, sizeof(light));  light.Type    = D3DLIGHT_DIRECTIONAL;  light.Diffuse = D3DXCOLOR(0.5f, 0.5f, 0.5f, 1.0f);  light.Direction   = XF::GFX::Vector3(-1.0f, -0.3f, -1.0f);  app->device.GetDevice()->SetLight(0, &light);  app->device.GetDevice()->LightEnable(0, false);  ZeroMemory(&material, sizeof(XF::GFX::D3DMaterial));  material.Diffuse  = D3DXCOLOR(1.0f, 0.0f, 0.0f, 1.0f);  material.Ambient  = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f);  app->device.GetDevice()->SetMaterial(&material);  return true;}void  TestGameScreen::OnUpdate(float dT){  if(app->input.KeyDown(XF::Keys::Q))  {scale.x -= 1.0f * dT;scale.y -= 1.0f * dT;scale.z -= 1.0f * dT;  }  if(app->input.KeyDown(XF::Keys::R))  {scale.x += 1.0f * dT;scale.y += 1.0f * dT;scale.z += 1.0f * dT;  }  if(app->input.KeyDown(XF::Keys::Up))position.y += 0.5f * dT;  if(app->input.KeyDown(XF::Keys::Down))position.y -= 0.5f * dT;  if(app->input.KeyDown(XF::Keys::Left))position.x += 0.5f * dT;  if(app->input.KeyDown(XF::Keys::Right))position.x -= 0.5f * dT;  if(app->input.KeyDown(XF::Keys::W))rotation.z -= 0.5f * dT;  if(app->input.KeyDown(XF::Keys::E))rotation.z += 0.5f * dT;  if(app->input.KeyDown(XF::Keys::S))rotation.y -= 0.5f * dT;  if(app->input.KeyDown(XF::Keys:))rotation.y += 0.5f * dT;}void  TestGameScreen::OnDraw(){  app->device.GetDevice()->SetRenderState(D3DRS_LIGHTING, false);  //app->device.GetDevice()->SetRenderState(D3DRS_AMBIENT, D3DCOLOR_XRGB(50, 50, 50));  app->device.GetDevice()->SetFVF(CUSTOMFVF);  XF::GFX::Matrix positionMatrix;  D3DXMatrixTranslation(&positionMatrix,  position.x,  position.y,  position.z);  XF::GFX::Matrix rotationMatrix;  D3DXMatrixRotationYawPitchRoll( &rotationMatrix, rotation.y, rotation.x, rotation.z);  XF::GFX::Matrix scaleMatrix;  D3DXMatrixScaling(&scaleMatrix,   scale.x,   scale.y,   scale.z);  app->device.GetDevice()->SetTransform(D3DTS_WORLD,&(rotationMatrix * scaleMatrix * positionMatrix));  app->device.GetDevice()->SetTransform(D3DTS_VIEW, &viewMatrix);  app->device.GetDevice()->SetTransform(D3DTS_PROJECTION, &projMatrix);  app->device.GetDevice()->SetStreamSource(0, vBuffer, 0, sizeof(CustomVertex));  app->device.GetDevice()->SetIndices(iBuffer);  app->device.GetDevice()->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, 8, 0, 12);}void  TestGameScreen::OnDestroy(){  vBuffer->Release();  iBuffer->Release();}#include "TestGameScreen.h"#define CUSTOMFVF (D3DFVF_XYZ | D3DFVF_NORMAL)struct CustomVertex{  float x, y, z;  XF::GFX::Vector3  normal;};bool  TestGameScreen::OnInit(){  CustomVertex vertices[] =   {{ -1.0f, -1.0f, 1.0f, XF::GFX::Vector3(0.0f, 0.0f, 1.0f), },// side 1{ 1.0f, -1.0f, 1.0f,  XF::GFX::Vector3(0.0f, 0.0f, 1.0f), },{ -1.0f, 1.0f, 1.0f,  XF::GFX::Vector3(0.0f, 0.0f, 1.0f), },{ 1.0f, 1.0f, 1.0f,   XF::GFX::Vector3(0.0f, 0.0f, 1.0f), },{ -1.0f, -1.0f, -1.0f, XF::GFX::Vector3(0.0f, 0.0f, -1.0f), },// side 2{ -1.0f, 1.0f, -1.0f,  XF::GFX::Vector3(0.0f, 0.0f, -1.0f), },{ 1.0f, -1.0f, -1.0f,  XF::GFX::Vector3(0.0f, 0.0f, -1.0f), },{ 1.0f, 1.0f, -1.0f,   XF::GFX::Vector3(0.0f, 0.0f, -1.0f), },{ -1.0f, 1.0f, -1.0f, XF::GFX::Vector3(0.0f, 1.0f, 0.0f), },// side 3{ -1.0f, 1.0f, 1.0f,  XF::GFX::Vector3(0.0f, 1.0f, 0.0f), },{ 1.0f, 1.0f, -1.0f,  XF::GFX::Vector3(0.0f, 1.0f, 0.0f), },{ 1.0f, 1.0f, 1.0f,   XF::GFX::Vector3(0.0f, 1.0f, 0.0f), },{ -1.0f, -1.0f, -1.0f, XF::GFX::Vector3(0.0f, -1.0f, 0.0f), },// side 4{ 1.0f, -1.0f, -1.0f,  XF::GFX::Vector3(0.0f, -1.0f, 0.0f), },{ -1.0f, -1.0f, 1.0f,  XF::GFX::Vector3(0.0f, -1.0f, 0.0f), },{ 1.0f, -1.0f, 1.0f,   XF::GFX::Vector3(0.0f, -1.0f, 0.0f), },{ 1.0f, -1.0f, -1.0f,  XF::GFX::Vector3(1.0f, 0.0f, 0.0f), },// side 5{ 1.0f, 1.0f, -1.0f,   XF::GFX::Vector3(1.0f, 0.0f, 0.0f), },{ 1.0f, -1.0f, 1.0f,   XF::GFX::Vector3(1.0f, 0.0f, 0.0f), },{ 1.0f, 1.0f, 1.0f,XF::GFX::Vector3(1.0f, 0.0f, 0.0f), },{ -1.0f, -1.0f, -1.0f, XF::GFX::Vector3(-1.0f, 0.0f, 0.0f), },// side 6{ -1.0f, -1.0f, 1.0f,  XF::GFX::Vector3(-1.0f, 0.0f, 0.0f), },{ -1.0f, 1.0f, -1.0f,  XF::GFX::Vector3(-1.0f, 0.0f, 0.0f), },{ -1.0f, 1.0f, 1.0f,   XF::GFX::Vector3(-1.0f, 0.0f, 0.0f), },  };  short indices[] =   {0, 1, 2,// side 12, 1, 3,4, 5, 6,// side 26, 5, 7,8, 9, 10,// side 310, 9, 11,12, 13, 14,// side 414, 13, 15,16, 17, 18,// side 518, 17, 19,20, 21, 22,// side 622, 21, 23,  };  app->device.GetDevice()->CreateVertexBuffer(    24 * sizeof(CustomVertex),    0,    CUSTOMFVF,    D3DPOOL_MANAGED,    &vBuffer,    NULL);  app->device.GetDevice()->CreateIndexBuffer(    36 * sizeof(short),    0,    D3DFMT_INDEX16,    D3DPOOL_MANAGED,    &iBuffer,    NULL);  void* voidPtr;  vBuffer->Lock(0, 0, (void**)&voidPtr, 0);  memcpy(voidPtr, vertices, sizeof(vertices));  vBuffer->Unlock();  iBuffer->Lock(0, 0, (void**)&voidPtr, 0);  memcpy(voidPtr, indices, sizeof(indices));  iBuffer->Unlock();  D3DXMatrixLookAtLH( &viewMatrix,   &XF::GFX::Vector3(0.0f, 0.0f, 10.0f),   &XF::GFX::Vector3Zero,   &XF::GFX::Vector3Up);  D3DXMatrixPerspectiveFovLH( &projMatrix, D3DXToRadian(45), (float)app->device.GetPresentationParameters().BackBufferWidth /   (float)app->device.GetPresentationParameters().BackBufferHeight, 1.0f, 100.0f);  position = XF::GFX::Vector3Zero;  rotation = XF::GFX::Vector3Zero;  scale= XF::GFX::Vector3One;  ZeroMemory(&light, sizeof(light));  light.Type    = D3DLIGHT_DIRECTIONAL;  light.Diffuse = D3DXCOLOR(0.5f, 0.5f, 0.5f, 1.0f);  light.Direction   = XF::GFX::Vector3(-1.0f, -0.3f, -1.0f);  app->device.GetDevice()->SetLight(0, &light);  app->device.GetDevice()->LightEnable(0, true);  ZeroMemory(&material, sizeof(XF::GFX::D3DMaterial));  material.Diffuse  = D3DXCOLOR(1.0f, 0.0f, 0.0f, 1.0f);  material.Ambient  = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f);  app->device.GetDevice()->SetMaterial(&material);  return true;}void  TestGameScreen::OnUpdate(float dT){  if(app->input.KeyDown(XF::Keys::Q))  {scale.x -= 1.0f * dT;scale.y -= 1.0f * dT;scale.z -= 1.0f * dT;  }  if(app->input.KeyDown(XF::Keys::R))  {scale.x += 1.0f * dT;scale.y += 1.0f * dT;scale.z += 1.0f * dT;  }  if(app->input.KeyDown(XF::Keys::Up))position.y += 0.5f * dT;  if(app->input.KeyDown(XF::Keys::Down))position.y -= 0.5f * dT;  if(app->input.KeyDown(XF::Keys::Left))position.x += 0.5f * dT;  if(app->input.KeyDown(XF::Keys::Right))position.x -= 0.5f * dT;  if(app->input.KeyDown(XF::Keys::W))rotation.z -= 0.5f * dT;  if(app->input.KeyDown(XF::Keys::E))rotation.z += 0.5f * dT;  if(app->input.KeyDown(XF::Keys::S))rotation.y -= 0.5f * dT;  if(app->input.KeyDown(XF::Keys:))rotation.y += 0.5f * dT;}void  TestGameScreen::OnDraw(){  app->device.GetDevice()->SetRenderState(D3DRS_LIGHTING, true);  app->device.GetDevice()->SetRenderState(D3DRS_AMBIENT, D3DCOLOR_XRGB(50, 50, 50));  app->device.GetDevice()->SetFVF(CUSTOMFVF);  XF::GFX::Matrix positionMatrix;  D3DXMatrixTranslation(&positionMatrix,  position.x,  position.y,  position.z);  XF::GFX::Matrix rotationMatrix;  D3DXMatrixRotationYawPitchRoll( &rotationMatrix, rotation.y, rotation.x, rotation.z);  XF::GFX::Matrix scaleMatrix;  D3DXMatrixScaling(&scaleMatrix,   scale.x,   scale.y,   scale.z);  app->device.GetDevice()->SetTransform(D3DTS_WORLD,&(rotationMatrix * scaleMatrix * positionMatrix));  app->device.GetDevice()->SetTransform(D3DTS_VIEW, &viewMatrix);  app->device.GetDevice()->SetTransform(D3DTS_PROJECTION, &projMatrix);  app->device.GetDevice()->SetStreamSource(0, vBuffer, 0, sizeof(CustomVertex));  app->device.GetDevice()->SetIndices(iBuffer);  app->device.GetDevice()->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, 8, 0, 12);}void  TestGameScreen::OnDestroy(){  vBuffer->Release();  iBuffer->Release();}#include <Windows.h>#include <d3d9.h>#include <d3dx9.h>#ifndef XF_GFX_DX9TYPEDEFSANDDEFINES_H#define XF_GFX_DX9TYPEDEFSANDDEFINES_Hnamespace XF{  namespace GFX  {typedef LPDIRECT3D9Direct3D;typedef LPDIRECT3DDEVICE9   Direct3DDevice;typedef D3DPRESENT_PARAMETERS   PresentationParameters;typedef LPDIRECT3DVERTEXBUFFER9 VertexBuffer;typedef LPDIRECT3DINDEXBUFFER9  IndexBuffer;typedef D3DXMATRIXMatrix;static const Matrix MatrixIdentity = Matrix(1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f);typedef D3DXVECTOR3Vector3;static const Vector3 Vector3Zero  = Vector3(0.0f, 0.0f, 0.0f);static const Vector3 Vector3One   = Vector3(1.0f, 1.0f, 1.0f);static const Vector3 Vector3Up= Vector3(0.0f, 1.0f, 0.0f);static const Vector3 Vector3Down  = Vector3(0.0f, -1.0f, 0.0f);static const Vector3 Vector3Left  = Vector3(-1.0f, 0.0f, 0.0f);static const Vector3 Vector3Right = Vector3(1.0f, 0.0f, 0.0f);static const Vector3 Vector3In= Vector3(0.0f, 0.0f, 1.0f);static const Vector3 Vector3Out   = Vector3(0.0f, 0.0f, -1.0f);typedef D3DXVECTOR2Vector2;static const Vector2 Vector2Zero  = Vector2(0.0f, 0.0f);static const Vector2 Vector2One   = Vector2(1.0f, 1.0f);static const Vector2 Vector2Up= Vector2(0.0f, 1.0f);static const Vector2 Vector2Down  = Vector2(0.0f, -1.0f);static const Vector2 Vector2Left  = Vector2(-1.0f, 0.0f);static const Vector2 Vector2Right = Vector2(1.0f, 0.0f);typedef D3DLIGHT9  Light;typedef D3DMATERIAL9   D3DMaterial;  }}#endif
  Have you tried updating your graphics card drivers....seems like you have a ghost in the machine ;  Well I'm working on my laptop which at the tail end of last week had a fresh install of Windows 7, and then the 4 terrabytes of updates to everything that comes with it, including updates for the graphics drivers, I guess tomorro I could try seeing if my drivers are actually upto date. I could also try running on a different machine, I would have to get it set up tho.This is indeed bizarre.   ;  Let us know how you get on....it does seem to be very bizarre. Probably simple to fix though...once you know what it is ;  Ok, So I got home from work and decided to do some investigation, drivers upto date etc. I also noticed a distinct "flicker" in the window which was occuring at regular 6 second intervals. I started prodding and poking, removing and adding trying to narrow down what was causing the problem, I then noticed that in the version using no lighting the cube wasn't displaying correctly, only the front and back sides were visible.Anyway, I narrowed that down to the drawIndexedPrimitive call being incorrect:  app->device.GetDevice()->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, 8, 0, 12);Whereas actually there are 24 verices:  app->device.GetDevice()->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, 24, 0, 12);Fixing this call cause the problem to go away, what I don't understand is why it occured in the first place? Can anyone explain this?Thanks, Scott   ;  You told the graphics card that it only has to process 8 vertices, because only the first 8 in the vertex buffer are actually used. That value tells the driver how many vertices it needs to run through the vertex shader before it can assemble triangles from them. Using vertices outside that range is undefined behaviour, but I'd guess that the driver has some internal buffer that happens to be big enough for exactly 6 seconds worth of vertex data, and it just happened to be only partially filling it in some way which causes it to start recycling the old vertices when it's full.   ;You told the graphics card that it only has to process 8 vertices, because only the first 8 in the vertex buffer are actually used. That value tells the driver how many vertices it needs to run through the vertex shader before it can assemble triangles from them. Using vertices outside that range is undefined behaviour, but I'd guess that the driver has some internal buffer that happens to be big enough for exactly 6 seconds worth of vertex data, and it just happened to be only partially filling it in some way which causes it to start recycling the old vertices when it's full.That makes sense, a circular buffer of some sort, with the numbers being just right to give the effect, an interesting one definately!   ;  I blame the ghosts...though Evil Steve knows what he's talking about 