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

Posted on 2004-12-01
Last Modified: 2013-12-08
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.  


Question by:jimbobmcgee
    LVL 16

    Author Comment

    Don't worry, I got the answer from someone at  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...

    LVL 7

    Accepted Solution

    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.
    LVL 16

    Author Comment

    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!!
    LVL 7

    Expert Comment

    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.


    Write Comment

    Please enter a first name

    Please enter a last name

    We will never share this with anyone.

    Featured Post

    How your wiki can always stay up-to-date

    Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
    - Increase transparency
    - Onboard new hires faster
    - Access from mobile/offline

    Artificial Intelligence comes in many forms, and for game developers, Path-Finding is an important ability for making an NPC (Non-Playable Character) maneuver through terrain.  A* is a particularly easy way to approach it.  I’ll start with the algor…
    Recently, in one of the tech-blogs I usually read, I saw a post about the best-selling video games through history. The first place in the list is for the classic, extremely addictive Tetris. Well, a long time ago, in a galaxy far far away, I was…
    Migrating to Microsoft Office 365 is becoming increasingly popular for organizations both large and small. If you have made the leap to Microsoft’s cloud platform, you know that you will need to create a corporate email signature for your Office 365…
    Polish reports in Access so they look terrific. Take yourself to another level. Equations, Back Color, Alternate Back Color. Write easy VBA Code. Tighten space to use less pages. Launch report from a menu, considering criteria only when it is filled…

    779 members asked questions and received personalized solutions in the past 7 days.

    Join the community of 500,000 technology professionals and ask your questions.

    Join & Ask a Question

    Need Help in Real-Time?

    Connect with top rated Experts

    14 Experts available now in Live!

    Get 1:1 Help Now