Link to home
Start Free TrialLog in
Avatar of jimbobmcgee
jimbobmcgeeFlag for United Kingdom of Great Britain and Northern Ireland

asked on

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(){}
            
            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),
                                                         D3DUSAGE_WRITEONLY,
                                                         Vertex::fvf,
                                                         D3DPOOL_MANAGED,
                                                         &D3DVertexBuffer,
                                                         0) != D3D_OK)
            {
                  MessageBox(NULL, "Cannot create vertex buffer", "Error", MB_ICONSTOP | MB_OK);
                  return false;
            }
            
            if (device->CreateIndexBuffer(36 * sizeof(WORD),
                                                        D3DUSAGE_WRITEONLY,
                                                        D3DFMT_INDEX16,
                                                        D3DPOOL_MANAGED,
                                                        &D3DIndexBuffer,
                                                        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);

            D3DVertexBuffer->Unlock();
            ///////////////////////////////////////////////////////////////////////////


            //// 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

            D3DIndexBuffer->Unlock();
            ///////////////////////////////////////////////////////////////////////////

            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));
            device->SetIndices(D3DIndexBuffer);
            device->SetFVF(Vertex::fvf);
            ///////////////////////////////////////////////////////////////////////////


            //// 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->BeginScene();

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

            device->EndScene();

            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.  

Thanks

J.
Avatar of jimbobmcgee
jimbobmcgee
Flag of United Kingdom of Great Britain and Northern Ireland image

ASKER

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

J.
ASKER CERTIFIED SOLUTION
Avatar of HoweverComma
HoweverComma

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
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!!
Avatar of HoweverComma
HoweverComma

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:
X=X*(Y+(Z/X)*(Z/Y))/360
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.