   Direct3D bug
  HiAnyone know why the following code workswhen I set    d3ddev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, 16, 0, 8); i.e. draw top, front, bottom and back of cube.But not when I run it as follows (to draw all of the cube)    d3ddev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, 24, 0, 12); Note: this is taken from http://www.directxtutorial.com/Tutorial9/B-Direct3DBasics/dx9B9.aspx#stilland is not my code.So I'm wondering, why doesn't it work?// include the basic windows header files and the Direct3D header file#include <windows.h>#include <windowsx.h>#include <d3d9.h>#include <d3dx9.h>// define the screen resolution and keyboard macros#define SCREEN_WIDTH 800#define SCREEN_HEIGHT 600#define KEY_DOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)#define KEY_UP(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1)// include the Direct3D Library files#pragma comment (lib, "d3d9.lib")#pragma comment (lib, "d3dx9.lib")// global declarationsLPDIRECT3D9 d3d;LPDIRECT3DDEVICE9 d3ddev;LPDIRECT3DVERTEXBUFFER9 v_buffer = NULL;LPDIRECT3DINDEXBUFFER9 i_buffer = NULL;// function prototypesvoid initD3D(HWND hWnd);void render_frame(void);void cleanD3D(void);void init_graphics(void);void init_light(void);    // sets up the light and the materialstruct CUSTOMVERTEX {FLOAT X, Y, Z; D3DVECTOR NORMAL;};#define CUSTOMFVF (D3DFVF_XYZ | D3DFVF_NORMAL)// the WindowProc function prototypeLRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);// the entry point for any Windows programint WINAPI WinMain(HINSTANCE hInstance,    HINSTANCE hPrevInstance,    LPSTR lpCmdLine,    int nCmdShow){    HWND hWnd;    WNDCLASSEX wc;    ZeroMemory(&wc, sizeof(WNDCLASSEX));    wc.cbSize = sizeof(WNDCLASSEX);    wc.style = CS_HREDRAW | CS_VREDRAW;    wc.lpfnWndProc = WindowProc;    wc.hInstance = hInstance;    wc.hCursor = LoadCursor(NULL, IDC_ARROW);    wc.lpszClassName = L"WindowClass";    RegisterClassEx(&wc);    hWnd = CreateWindowEx(NULL, L"WindowClass", L"Our Direct3D Program", WS_OVERLAPPEDWINDOW, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, NULL, NULL, hInstance, NULL);    ShowWindow(hWnd, nCmdShow);    // set up and initialize Direct3D    initD3D(hWnd);    // enter the main loop:    MSG msg;    while(TRUE)    {   while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))   {  TranslateMessage(&msg;  DispatchMessage(&msg;   }   if(msg.message == WM_QUIT)  break;   render_frame();   if(KEY_DOWN(VK_ESCAPE))  PostMessage(hWnd, WM_DESTROY, 0, 0);    }    // clean up DirectX and COM    cleanD3D();    return msg.wParam;}// this is the main message handler for the programLRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){    switch(message)    {   case WM_DESTROY:  { PostQuitMessage(0); return 0;  } break;    }    return DefWindowProc (hWnd, message, wParam, lParam);}// this function initializes and prepares Direct3D for usevoid initD3D(HWND hWnd){    d3d = Direct3DCreate9(D3D_SDK_VERSION);    D3DPRESENT_PARAMETERS d3dpp;    ZeroMemory(&d3dpp, sizeof(d3dpp));    d3dpp.Windowed = TRUE;    d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;    d3dpp.hDeviceWindow = hWnd;    d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8;    d3dpp.BackBufferWidth = SCREEN_WIDTH;    d3dpp.BackBufferHeight = SCREEN_HEIGHT;    d3dpp.EnableAutoDepthStencil = TRUE;    d3dpp.AutoDepthStencilFormat = D3DFMT_D16;    // create a device class using this information and the info from the d3dpp stuct    d3d->CreateDevice(D3DADAPTER_DEFAULT,  D3DDEVTYPE_HAL,  hWnd,  D3DCREATE_SOFTWARE_VERTEXPROCESSING,  &d3dpp,  &d3ddev);    init_graphics();    // call the function to initialize the cube    init_light();    // call the function to initialize the light and material    d3ddev->SetRenderState(D3DRS_LIGHTING, TRUE);    // turn on the 3D lighting    d3ddev->SetRenderState(D3DRS_ZENABLE, TRUE);    // turn on the z-buffer    d3ddev->SetRenderState(D3DRS_AMBIENT, D3DCOLOR_XRGB(50, 50, 50));    // ambient light}// this is the function used to render a single framevoid render_frame(void){    d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);    d3ddev->Clear(0, NULL, D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);    d3ddev->BeginScene();    // select which vertex format we are using    d3ddev->SetFVF(CUSTOMFVF);    // set the view transform    D3DXMATRIX matView;    D3DXMatrixLookAtLH(&matView,    &D3DXVECTOR3 (0.0f, 8.0f, 25.0f),    // the camera position    &D3DXVECTOR3 (0.0f, 0.0f, 0.0f), // the look-at position    &D3DXVECTOR3 (0.0f, 1.0f, 0.0f));    // the up direction    d3ddev->SetTransform(D3DTS_VIEW, &matView);    // set the projection transform    D3DXMATRIX matProjection;    D3DXMatrixPerspectiveFovLH(&matProjection, D3DXToRadian(45), (FLOAT)SCREEN_WIDTH / (FLOAT)SCREEN_HEIGHT, 1.0f,    // the near view-plane 100.0f);    // the far view-plane    d3ddev->SetTransform(D3DTS_PROJECTION, &matProjection);    // set the world transform    static float index = 0.0f; index+=0.03f;    D3DXMATRIX matRotateY;    D3DXMatrixRotationY(&matRotateY, index);    d3ddev->SetTransform(D3DTS_WORLD, &(matRotateY));    // select the vertex and index buffers to use    d3ddev->SetStreamSource(0, v_buffer, 0, sizeof(CUSTOMVERTEX));    d3ddev->SetIndices(i_buffer);    // draw the cube    d3ddev->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, 24, 0, 12);d3ddev->EndScene();d3ddev->Present(NULL, NULL, NULL, NULL);}// this is the function that cleans up Direct3D and COMvoid cleanD3D(void){    v_buffer->Release();    i_buffer->Release();    d3ddev->Release();    d3d->Release();}// this is the function that puts the 3D models into video RAMvoid init_graphics(void){    // create the vertices using the CUSTOMVERTEX struct    CUSTOMVERTEX vertices[] =    {   { -3.0f, -3.0f, 3.0f, 0.0f, 0.0f, 1.0f, },    // side 1   { 3.0f, -3.0f, 3.0f, 0.0f, 0.0f, 1.0f, },   { -3.0f, 3.0f, 3.0f, 0.0f, 0.0f, 1.0f, },   { 3.0f, 3.0f, 3.0f, 0.0f, 0.0f, 1.0f, },   { -3.0f, -3.0f, -3.0f, 0.0f, 0.0f, -1.0f, },    // side 2   { -3.0f, 3.0f, -3.0f, 0.0f, 0.0f, -1.0f, },   { 3.0f, -3.0f, -3.0f, 0.0f, 0.0f, -1.0f, },   { 3.0f, 3.0f, -3.0f, 0.0f, 0.0f, -1.0f, },   { -3.0f, 3.0f, -3.0f, 0.0f, 1.0f, 0.0f, },    // side 3   { -3.0f, 3.0f, 3.0f, 0.0f, 1.0f, 0.0f, },   { 3.0f, 3.0f, -3.0f, 0.0f, 1.0f, 0.0f, },   { 3.0f, 3.0f, 3.0f, 0.0f, 1.0f, 0.0f, },   { -3.0f, -3.0f, -3.0f, 0.0f, -1.0f, 0.0f, },    // side 4   { 3.0f, -3.0f, -3.0f, 0.0f, -1.0f, 0.0f, },   { -3.0f, -3.0f, 3.0f, 0.0f, -1.0f, 0.0f, },   { 3.0f, -3.0f, 3.0f, 0.0f, -1.0f, 0.0f, },   { 3.0f, -3.0f, -3.0f, 1.0f, 0.0f, 0.0f, },    // side 5   { 3.0f, 3.0f, -3.0f, 1.0f, 0.0f, 0.0f, },   { 3.0f, -3.0f, 3.0f, 1.0f, 0.0f, 0.0f, },   { 3.0f, 3.0f, 3.0f, 1.0f, 0.0f, 0.0f, },   { -3.0f, -3.0f, -3.0f, -1.0f, 0.0f, 0.0f, },    // side 6   { -3.0f, -3.0f, 3.0f, -1.0f, 0.0f, 0.0f, },   { -3.0f, 3.0f, -3.0f, -1.0f, 0.0f, 0.0f, },   { -3.0f, 3.0f, 3.0f, -1.0f, 0.0f, 0.0f, },    };    // create a vertex buffer interface called v_buffer    d3ddev->CreateVertexBuffer(24*sizeof(CUSTOMVERTEX), 0, CUSTOMFVF, D3DPOOL_MANAGED, &v_buffer, NULL);    VOID* pVoid;    // a void pointer    // lock v_buffer and load the vertices into it    v_buffer->Lock(0, 0, (void**)&pVoid, 0);    memcpy(pVoid, vertices, sizeof(vertices));    v_buffer->Unlock();    // create the indices using an int array    int indices[] =    {   0, 1, 2,    // side 1   2, 1, 3,   4, 5, 6,    // side 2   6, 5, 7,   8, 9, 10,    // side 3   10, 9, 11,   12, 13, 14,    // side 4   14, 13, 15,   16, 17, 18,    // side 5   18, 17, 19,   20, 21, 22,    // side 6   22, 21, 23,    };    // create an index buffer interface called i_buffer    d3ddev->CreateIndexBuffer(36*sizeof(int),0,D3DFMT_INDEX32,D3DPOOL_MANAGED,&i_buffer,NULL);    // lock i_buffer and load the indices into it    i_buffer->Lock(0, 0, (void**)&pVoid, 0);    memcpy(pVoid, indices, sizeof(indices));    i_buffer->Unlock();}// this is the function that sets up the lights and materialsvoid init_light(void){    D3DLIGHT9 light;    // create the light struct    D3DMATERIAL9 material;    // create the material struct    ZeroMemory(&light, sizeof(light));    // clear out the light struct for use    light.Type = D3DLIGHT_DIRECTIONAL;    // make the light type 'directional light'    light.Diffuse = D3DXCOLOR(0.5f, 0.5f, 0.5f, 1.0f);    // set the light's color    light.Direction = D3DXVECTOR3(-1.0f, -0.3f, -1.0f);    d3ddev->SetLight(0, &light);    // send the light struct properties to light #0    d3ddev->LightEnable(0, TRUE);    // turn on light #0    ZeroMemory(&material, sizeof(D3DMATERIAL9));    // clear out the struct for use    material.Diffuse = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f);    // set diffuse color to white    material.Ambient = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f);    // set ambient color to white    d3ddev->SetMaterial(&material);    // set the globably-used material to &material}   
  There's a fairly large number of problems with that code, ranging from things that work but aren't guaranteed too (Relying on undefined behaviour), to things that will just crash outright if run on some hardware. That particular site is a terrible site to learn from; the articles might be easy to understand, but the code is just plain wrong. I've posted several times on these forums pointing out bugs in the directxtutorial source code, no doubt google will bring a few of them up.For the actual bug, what do you mean it "doesn't work"? Does it not draw anything? Does it crash? Anything from the Debug Runtimes?   ;  So when it works it draws a partial cube with missing sides, rotating and lit up.When I change it (as previously defined) to draw the whole cube, it crashes on startup. Stepping through code it appears to crash on the first call ofd3ddev->Present(NULL, NULL, NULL, NULL);So I'm guessing nothing is drawn.Yeah - I'm really not getting a good vibe from that site. It looks like a nice bare bones tutorial, but I really don't feel in control of my code. Not great.Any advice would be very much appreciated.So-I'm a good programmer, and am learning 3d as a hobby. Not massively into it, just wanted to give it a try.   ;Quote:Original post by lightingI'm a good programmerI know that I know nothing. Personally, I can't decide if I am a good programmer or not, because I don't know what I don't know yet.;Quote:Original post by lightingWhen I change it (as previously defined) to draw the whole cube, it crashes on startup. Stepping through code it appears to crash on the first call ofd3ddev->Present(NULL, NULL, NULL, NULL);So I'm guessing nothing is drawn.I'm going to guess that your device pointer is NULL. One of my main gripes with that site is that it doesn't teach you to check any of your return values. If CreateDevice() fails, then your device pointer will be NULL and you'll get a crash on that line (Or any other line that accesses your device pointer).The debug runtimes (See the link in my previous post) will give you an error message if CreateDevice or any other function fails, which will help you track down the cause.I've written a few articles of my own, which may be of interest to you.Tutorial 1Tutorial 2Tutorial 3Tutorial 4Tutorial 5Cheers,Steve   ;  How do you suppose you'll create a cube out of 24 indices?6 sides, 2 triangles per side, 3 vertices per triangle.6 sides * 2 triangles = 12 indices12 indices * 3 per triangle = 36;  EDIT: Never mind, don't wanna go off topic.   ;Quote:Original post by marius1930How do you suppose you'll create a cube out of 24 indices?6 sides, 2 triangles per side, 3 vertices per triangle.6 sides * 2 triangles = 12 indices12 indices * 3 per triangle = 36The 24 refers to the number of vertices used - which is 4 per face, 6 faces = 24. The number of indices is implicit given the primitive type and count.   