C++/DX9 Beginner: Simple cube app not displaying cube (Code included)

I'm basically working through the tutorials on a DX9 book, trying to stay afloat with a limited knowledge of C++.  I have my Window creation and Direct3D initialisation working and am now moving on to displaying a coloured cube.  However, when I execute my program, the cube does not appear.

The basic structure of my WinMain() is:

      - Create window (returning HWND)
      - Init DX9 (returning IDirect3DDevice9*)
      - Load cube vertexes/indexes into buffers (returning bool) (bool createCubeObject() -- see below)
      - Enter MessageLoop
          - Handle WM_QUIT
          - Handle WM_xxx
          - Display cube (bool doDisplayScene() -- see below)
      - End MessageLoop
      - Cleanup (void killBuffers() -- see below)

The buffers seem to be created, the Device->Clear's as expected, but the cube does not display.  I expect it's just a scope error but I can't seem to spot it.

Either way, the code follows:

      //// DIRECTIVES ///////////////////////////////////////////////////////////////
      #include <d3dx9.h>
      #include ".\initGlobals.h"

      //// PROTOTYPES ///////////////////////////////////////////////////////////////
      bool createCubeObject(IDirect3DDevice9 *device);
      bool doDisplayBuffer(IDirect3DDevice9 *device);
      void killBuffers();

      //// USER DEFINED TYPES ///////////////////////////////////////////////////////
      struct Vertex
            Vertex(float x, float y, float z)
                  x = x;      y = y;      z = z;
                  c = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f);

            Vertex(float x, float y, float z, float r, float g, float b, float a)
                  x = x;      y = y;      z = z;
                  c = D3DXCOLOR(r, g, b, a);

            float                        x, y, z;
            DWORD                        c;
            static const DWORD      fvf;

      const DWORD      Vertex::fvf      = (D3DFVF_XYZ | D3DFVF_DIFFUSE);

      //// PRIVATE VARIABLES ////////////////////////////////////////////////////////
      static IDirect3DVertexBuffer9      *D3DVertexBuffer      = 0;
      static IDirect3DIndexBuffer9      *D3DIndexBuffer            = 0;

      bool createCubeObject(IDirect3DDevice9 *device)

            Vertex      *v;
            WORD      *i;

            //// CREATE MEMORY BUFFERS TO STORE CUBE GEOMETRY /////////////////////////
            if (device->CreateVertexBuffer(8 * sizeof(Vertex),
                                                         0) != D3D_OK)
                  MessageBox(NULL, "Cannot create vertex buffer", "Error", MB_ICONSTOP | MB_OK);
                  return false;
            if (device->CreateIndexBuffer(36 * sizeof(WORD),
                                                        0) != D3D_OK)
                  MessageBox(NULL, "Cannot create vertex buffer", "Error", MB_ICONSTOP | MB_OK);
                  return false;

            //// STORE CUBE POINT GEOMETRY ////////////////////////////////////////////
            D3DVertexBuffer->Lock(0, 0, (void**)&v, 0);

                  v[0] = Vertex(-1.0f, -1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f);
                  v[1] = Vertex(-1.0f,  1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f);
                  v[2] = Vertex( 1.0f,  1.0f, -1.0f, 1.0f, 1.0f, 0.0f, 1.0f);
                  v[3] = Vertex( 1.0f, -1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 1.0f);
                  v[4] = Vertex(-1.0f, -1.0f,  1.0f, 0.0f, 1.0f, 1.0f, 1.0f);
                  v[5] = Vertex(-1.0f,  1.0f,  1.0f, 0.0f, 0.0f, 1.0f, 1.0f);
                  v[6] = Vertex( 1.0f,  1.0f,  1.0f, 1.0f, 0.0f, 1.0f, 1.0f);
                  v[7] = Vertex( 1.0f, -1.0f,  1.0f, 1.0f, 1.0f, 1.0f, 1.0f);


            //// STORE FACE GEOMETRY //////////////////////////////////////////////////
            D3DIndexBuffer->Lock(0, 0, (void**)&i, 0);

                  i[0]  = 0;      i[1]  = 1;      i[2]  = 2;            // ) Front
                  i[3]  = 0;      i[4]  = 2;      i[5]  = 3;            // ) face

                  i[6]  = 4;      i[7]  = 6;      i[8]  = 5;            // ) Back
                  i[9]  = 4;      i[10] = 7;      i[11] = 6;            // ) face

                  i[12] = 4;      i[13] = 5;      i[14] = 1;            // ) Left
                  i[15] = 4;      i[16] = 1;      i[17] = 0;            // ) face

                  i[18] = 3;      i[19] = 2;      i[20] = 6;            // ) Right
                  i[21] = 3;      i[22] = 6;      i[23] = 7;            // ) face

                  i[24] = 1;      i[25] = 5;      i[26] = 6;            // ) Top
                  i[27] = 1;      i[28] = 6;      i[29] = 2;            // ) face

                  i[30] = 4;      i[31] = 0;      i[32] = 3;            // ) Bottom
                  i[33] = 4;      i[34] = 3;      i[35] = 7;            // ) face


            return true;


      bool doDisplayBuffer(IDirect3DDevice9 *device)
            if ((D3DVertexBuffer == 0) || (D3DIndexBuffer == 0))
                  MessageBox(NULL, "Display buffers empty", "Error", MB_ICONINFORMATION | MB_OK);
                  return false;
                                                                              //If buffers not populated, don't do anything

            //// INITIALISE IMAGE STREAM //////////////////////////////////////////////
            device->Clear(0, 0,                                                                        //No dirty rectangles
                                D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,                        //Things to clear
                                0xffffffff,                                                            //Colour to clear to
                                1.0f, 0);                                                                  //Reset Z-Buffer & Stencil

            device->SetStreamSource(0, D3DVertexBuffer, 0, sizeof(Vertex));

            //// PLACE/TARGET CAMERA //////////////////////////////////////////////////
            D3DXVECTOR3            vCamPos( 0.0f,  0.0f, -5.0f);
            D3DXVECTOR3            vCamAim( 0.0f,  0.0f,  0.0f);
            D3DXVECTOR3            vCamUp ( 0.0f,  1.0f,  0.0f);

            D3DXMATRIX            mView, mProj, mWorld;

            D3DXMatrixLookAtLH                  (&mView, &vCamPos, &vCamAim, &vCamUp);
            D3DXMatrixIdentity                  (&mWorld);
            D3DXMatrixPerspectiveFovLH      (&mProj,
                                                       D3DX_PI * 0.5f,                              //Field of View (90deg)
                                                       (float)(giScrWidth / giScrHeight),      //Aspect ratio
                                                       1.0f, 1000.0f);                              //Distance to near/far

            device->SetTransform(D3DTS_VIEW, &mView);
            device->SetTransform(D3DTS_PROJECTION, &mProj);
            device->SetTransform(D3DTS_WORLD, &mWorld);

            //// DRAW PRIMITIVES //////////////////////////////////////////////////////

                  device->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,                  //Type of primitives
                                                             0,                                                //Base vertex adder
                                                             0, 8,                                          //Start vertex / # vertices
                                                             0, 12);                                    //Start index / # primitives


            device->Present(0, 0, 0, 0);

            return true;


      void killBuffers(void)
            if (D3DVertexBuffer != 0)      D3DVertexBuffer->Release();
            if (D3DIndexBuffer != 0)      D3DIndexBuffer->Release();

If anyone can spot it, I'd be most grateful.  


LVL 16
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

jimbobmcgeeAuthor Commented:
Don't worry, I got the answer from someone at www.gamedev.net.  If anyone cares:

     x = x;     y = y;     z = z;

should read

     this->x = x;     this->y = y;     this->z = z;

As a side game, however, the first person who even acknowledges this question can have all the points...

Lol I'll bite, but so it doesn't appear that it is point passing or anything shady I'll explain why.
C/C++ hobbles me I like RAD environments but play with C++ on occasions.
You have to use "this" because it is a POINTER to the object.

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
jimbobmcgeeAuthor Commented:
Hehehe, I'm a VB6 man myself -- but I thought I'd take the plunge into C++ and DirectX in one go, as it's unlikely that I'll use either independantly.

It turns out that the book I'm using to learn Direct3D (Luna, Frank -- Introduction to 3D Game Programming with DirectX 9.0) has an interesting publishing error that sees all underscore characters removed from the code samples.

Since Luna prefixes his class members with an underscore, the line, x = x; y = y; z = z (that I'd copied from the book and, as such, couldn't spot) actually read _x = x; _y = y; _z = z.  But I chose the 'this' approach because I don't like starting variable names with anything other than a letter...

It has been suggested that VC++6.0 might ignore such lines as x = x in some attempt to (optimise/have the final say/ruin your day/delete as appropriate) but I don't know if that's true...

I hate pointers -- give me ByRef and ByVal any day!!
It may do that in optimizing. Even if those lines were left in there after compiled, it would not compile properly because the variable would not be assigned to the actual object, hence the pointer. I'm not a fan of C++, probably due to lack of experience Delphi though offers inline assembly, and is many many times faster than VB.

VB is much worse if you enable optimisation. It will take a line like this:
and disregard any order that you want to perform the calculations.
While testing in the IDE the program runs flawlessly, compile it and everything goes haywire.
It is documented in the KB, but you'd think with the 11 or 12 service packs that have been released since VB5 then VB6 they would have decided to fix this.
Instead the option is just leave it alone, and not to use compiler optimisation.

I guess a seasoned C++ programmer would have known that they were pointers right off, as in any language it wouldn't make sense to perform those assignments, unless you wanted to eat a couple of instruction cycles.

>>But I chose the 'this' approach because I don't like starting variable names with anything other than a letter...
THIS is a keyword  in C++ it is longhand for the _ character, it isn't really part of the variable name though.

It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Game Programming

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.