[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now


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

Posted on 2004-12-01
Medium Priority
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
  • 2
  • 2
LVL 16

Author Comment

ID: 12736862
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...


Accepted Solution

HoweverComma earned 2000 total points
ID: 12760686
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

ID: 12767887
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!!

Expert Comment

ID: 12769030
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.


Featured Post

Prep for the ITIL® Foundation Certification Exam

December’s Course of the Month is now available! Enroll to learn ITIL® Foundation best practices for delivering IT services effectively and efficiently.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

What is RenderMan: RenderMan is a not any particular piece of software. RenderMan is an industry standard, defining set of rules that any rendering software should use, to be RenderMan-compliant. Pixar's RenderMan is a flagship implementation of …
Performance in games development is paramount: every microsecond counts to be able to do everything in less than 33ms (aiming at 16ms). C# foreach statement is one of the worst performance killers, and here I explain why.
This Micro Tutorial will teach you how to add a cinematic look to any film or video out there. There are very few simple steps that you will follow to do so. This will be demonstrated using Adobe Premiere Pro CS6.
With just a little bit of  SQL and VBA, many doors open to cool things like synchronize a list box to display data relevant to other information on a form.  If you have never written code or looked at an SQL statement before, no problem! ...  give i…

873 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