Thread: Displaying a heightmap

  1. #1
    Darkness Prevails Dark_Phoenix's Avatar
    Join Date
    Oct 2006
    Location
    Houston, Texas
    Posts
    174

    Displaying a heightmap

    So I am having problems getting what should be a simple program running right. This simply loads and displays a heightmap. It works fine with a 32 bit index buffer(which my old vid card does not support) but when I try to add functionality for 16 bit I get a seg fault that I cannot find. Let me see if I can give all the relavent code....
    Code:
    /**********************************************************************************
      Summary    : Create a new Terrain object
      Returns    : TRUE on success, FALSE on failure
      Parameters : 
        pDevice        - D3D Device
        rawFile        - Name of the height map file
        terrainTexture - Texture file name
    **********************************************************************************/
    bool cTerrain::Initialize(LPDIRECT3DDEVICE9 pDevice, 
                              char *RawFile, char *TerrainTexture) {
        Release();
     
        // Load height map
        char path[MAX_PATH] = {0};
        cUtility::GetMediaFile(RawFile, path);
        std::ifstream HeightMap;
        HeightMap.open(path, std::ios::binary);
        if (HeightMap.fail() ) {
            SHOWERROR("Could not open HeightMap file.", __FILE__, __LINE__);
            return false;
        }
        // Get number of vertices
        HeightMap.seekg(0, std::ios::end);
        m_numVertices = HeightMap.tellg();
        HeightMap.seekg(0, std::ios::beg);
        // Allocate memory and read the data
        m_pHeight = new UCHAR[m_numVertices];
        HeightMap.read( (char*)m_pHeight, m_numVertices);
        HeightMap.close();
        // Generate vertices
        UINT width = (int)sqrt( (float)m_numVertices);
        cuCustomVertex::PositionTextured* pVertices = NULL; 
        cTriangleStrip::GenerateVerticesWithHeight(&pVertices, width, 
                                                   width, m_pHeight);
        m_vb.CreateBuffer(pDevice, m_numVertices, D3DFVF_XYZ | D3DFVF_TEX1, 
                          sizeof(cuCustomVertex::PositionTextured) );
        m_vb.SetData(m_numVertices, pVertices, 0);
        // Generate indices
        /*int*/USHORT* pIndices = NULL;
        m_numIndices = cTriangleStrip::GenerateIndices(&pIndices, width, width);
        m_ib.CreateBuffer(pDevice, m_numIndices, D3DFMT_INDEX32);
        m_ib.SetData(m_numIndices, pIndices, 0);
        m_vb.SetIndexBuffer(&m_ib);
     
        cUtility::GetMediaFile(TerrainTexture, path); 
        if (FAILED(D3DXCreateTextureFromFile(pDevice, path, &m_pTexture) ) ) {
            SHOWERROR("Unable to load terrain textures.", __FILE__, __LINE__);
            return false;
        }
        return true;
    }
    in blue is where I am going from 32 bit to 16 bit.
    Code:
    /**********************************************************************************
      Summary    : Generates 16-bit indices for an indexed triangle strip
      Returns    : Number on indices
      Parameters : 
        [in/out] pIndices            - Array to be filled up.
        [in]     verticesAlongWidth  - Number of vertices along the width
        [in]     verticesAlongLength - Number of vertices along the length
    **********************************************************************************/
    int cTriangleStrip::GenerateIndices(USHORT** ppIndices, 
                                             int verticesAlongWidth, 
                                             int verticesAlongLength) {
        int numIndices = (verticesAlongWidth * 2) * 
            (verticesAlongLength - 1) + (verticesAlongLength - 2);
        SAFE_DELETE_ARRAY(*ppIndices);
        *ppIndices = new USHORT[numIndices];
        int index = 0;
        for (int z = 0; z < verticesAlongLength - 1; z++) {
            // Even rows move left to right, odd rows move right to left.
            if (z % 2 == 0) {
                // Even row
                int x;
                for (x = 0; x < verticesAlongWidth; x++) {
                    (*ppIndices)[index++] = (USHORT)(x + (z * verticesAlongWidth));
                    (*ppIndices)[index++] = 
                        (USHORT)(x + (z * verticesAlongWidth) + verticesAlongWidth);
                }
                // Insert degenerate vertex if this isn't the last row
                if (z != verticesAlongLength - 2) {
                    (*ppIndices)[index++] = (USHORT)(--x + (z * verticesAlongWidth));
                }
            } else {
                // Odd row
                int x;
                for (x = verticesAlongWidth - 1; x >= 0; x--) {
                    (*ppIndices)[index++] = (USHORT)(x + (z * verticesAlongWidth));
                    (*ppIndices)[index++] = 
                        (USHORT)(x + (z * verticesAlongWidth) + verticesAlongWidth);
                }
                // Insert degenerate vertex if this isn't the last row
                if (z != verticesAlongLength - 2) {
                    (*ppIndices)[index++] = (USHORT)(++x + (z * verticesAlongWidth));
                }
            }
        } 
        return numIndices;
    }
    the 32 bit version of this function works fine, and simply goes from USHORT to int
    Code:
    /**********************************************************************************
      Summary    : Creates an Index Buffer
      Returns    : TRUE on success, False on failure
      Parameters : 
        pDevice    - Device to create the buffer with
        numIndices - Number of indices to put in the index buffer
        format     - D3DFMT_INDEX32 for 32-bit indices, D3DFMT_INDEX16 for 16-bit
        dynamic    - TRUE for dynamic buffer, FALSE for static buffer
    **********************************************************************************/
    bool cIndexBuffer::CreateBuffer(LPDIRECT3DDEVICE9 pDevice, UINT numIndices, 
                                    D3DFORMAT format, bool dynamic) {
        Release();
        m_numIndices = numIndices;
        // Dynamic buffers can't be in D3DPOOL_MANAGED
        D3DPOOL pool = (dynamic ? D3DPOOL_DEFAULT : D3DPOOL_MANAGED);
        UINT size = ( (format == D3DFMT_INDEX32) ? sizeof(UINT) : sizeof(USHORT) );
        DWORD usage = 
            (dynamic ? D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC : D3DUSAGE_WRITEONLY);
        if(FAILED(pDevice->CreateIndexBuffer(m_numIndices * size, usage, format, 
                                             pool, &m_pIB, NULL) ) ) {
            SHOWERROR("CreateIndexBuffer failed.", __FILE__, __LINE__);
            return false;
        }
        return true;
    }
    /**********************************************************************************
      Summary    : Fill up the Index Buffer
      Returns    : TRUE on success, False on failure
      Parameters : 
        numIndices - Number of indices being put in the buffer.
        pIndices   - Pointer to the vertex data
        dwFlags    - Lock flags
    **********************************************************************************/
    bool cIndexBuffer::SetData(UINT numIndices, void *pIndices, DWORD flags) {
        if (m_pIB == NULL) {
            return false;
        }
        char *pData;
        D3DINDEXBUFFER_DESC desc;
        m_pIB->GetDesc(&desc);
        UINT size = ((desc.Format == D3DFMT_INDEX32) ? sizeof(UINT) : sizeof(USHORT));
        // Lock the index buffer
        if (FAILED(m_pIB->Lock(0, 0, (void**)&pData, flags) ) ) {
            return false;
        }
        memcpy(pData, pIndices, numIndices * size);
        // Unlock index buffer
        if (FAILED(m_pIB->Unlock() ) ) {
            return false;
        }
        return true;
    }
    the seg fault comes up here

    the .raw file I am using for the heightmap was downloaded from an online tutorial, and I think that it may be in 32 bit format. If that is the case, and correct me if I am wrong, I think I will need two 16 bit buffers to store the heightmap but I am unsure how to go about using two index buffers for one object...
    Using Code::Blocks and Windows XP

    In every hero, there COULD be a villain!

  2. #2
    Darkness Prevails Dark_Phoenix's Avatar
    Join Date
    Oct 2006
    Location
    Houston, Texas
    Posts
    174
    OK, so I fixed the seg fault, but now all I am getting is a blank, black screen. I am wondering if I am loading and rendering the .raw file and the texture correctly.
    Here is where I load the files
    Code:
    bool cTerrain::Initialize(LPDIRECT3DDEVICE9 pDevice, char *RawFile, char*TerrainTexture) {
        Release();
        
        // Load height map
        char path[MAX_PATH] = {0};
        cUtility::GetMediaFile(RawFile, path);
        std::ifstream HeightMap;
        HeightMap.open(path, std::ios::binary);
        if (HeightMap.fail() ) {
            SHOWERROR("Could not open HeightMap file.", __FILE__, __LINE__);
            return false;
        }
    
        // Get number of vertices
        HeightMap.seekg(0, std::ios::end);
        m_numVertices = HeightMap.tellg();
        HeightMap.seekg(0, std::ios::beg);
    
        // Allocate memory and read the data
        m_pHeight = new UCHAR[m_numVertices];
        HeightMap.read( (char*)m_pHeight, m_numVertices);
        HeightMap.close();
    
        // Generate vertices
        UINT width = (int)sqrt( (float)m_numVertices);
        cuCustomVertex::PositionTextured* pVertices = NULL; 
        cTriangleStrip::GenerateVerticesWithHeight(&pVertices, width, 
                                                   width, m_pHeight);
        m_vb.CreateBuffer(pDevice, m_numVertices, D3DFVF_XYZ | D3DFVF_TEX1, 
                          sizeof(cuCustomVertex::PositionTextured) );
        m_vb.SetData(m_numVertices, pVertices, 0);
    
        // Generate indices
        USHORT* pIndices = NULL;
        m_numIndices = cTriangleStrip::GenerateIndices(&pIndices, width, width);
        m_ib.CreateBuffer(pDevice, m_numIndices, D3DFMT_INDEX16);
        m_ib.SetData(m_numIndices, pIndices, 0);
        m_vb.SetIndexBuffer(&m_ib);
        
        cUtility::GetMediaFile(TerrainTexture, path); 
        if (FAILED(D3DXCreateTextureFromFile(pDevice, path, &m_pTexture) ) ) {
            SHOWERROR("Unable to load terrain textures.", __FILE__, __LINE__);
            return false;
        }
        return true;
    }
    My TriangleStrip and CustomVertex
    Code:
    void cTriangleStrip::GenerateVerticesWithHeight
                                        (cuCustomVertex::PositionTextured** ppVertices, 
                                         int verticesAlongWidth, 
                                         int verticesAlongLength, UCHAR* pHeight) {
        SAFE_DELETE_ARRAY(*ppVertices);
        *ppVertices = new cuCustomVertex::PositionTextured
            [verticesAlongLength * verticesAlongWidth];
        for (int z = 0; z < verticesAlongLength; z++) {
            for ( int x = 0; x < verticesAlongWidth; x++ ) {
                float halfWidth =  ((float)verticesAlongWidth  - 1.0f) / 2.0f;
                float halfLength = ((float)verticesAlongLength - 1.0f) / 2.0f;
                (*ppVertices)[z * verticesAlongLength + x] = 
                    cuCustomVertex::PositionTextured(
                                          (float)x - halfWidth, 
                                          (float)pHeight[z * verticesAlongLength + x], 
                                          (float)z - halfLength,
                                          (float)x / (verticesAlongWidth - 1), 
                                          (float)z / (verticesAlongLength - 1) );
            }
        }
        return;
    }
    typedef struct PositionTextured
    {
    public:
        PositionTextured() : X(0), Y(0), Z(0), Tu(0), Tv(0) {}
        PositionTextured( float x, float y, float z, float tu, float tv ) 
            : X(x), Y(y), Z(z), Tu(tu), Tv(tv) {}
        float X, Y, Z;
        float Tu, Tv;
    } PositionTextured;
    My vertex and Index Buffers
    Code:
    bool cVertexBuffer::CreateBuffer(LPDIRECT3DDEVICE9 pDevice, UINT numVertices, 
                                     DWORD FVF, UINT VertexSize, bool dynamic) {
        Release(); 
        m_numVertices = numVertices; 
        m_FVF         = FVF; 
        m_VertexSize  = VertexSize; 
    
        // Dynamic buffers can't be in D3DPOOL_MANAGED 
        D3DPOOL pool = dynamic ? D3DPOOL_DEFAULT : D3DPOOL_MANAGED; 
        DWORD usage = 
            dynamic ? D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC : D3DUSAGE_WRITEONLY; 
        if(FAILED(pDevice->CreateVertexBuffer(m_numVertices * m_VertexSize, 
                                              usage, m_FVF, pool, &m_pVB, NULL) ) ) { 
            SHOWERROR("CreateVertexBuffer failed.", __FILE__, __LINE__); 
            return false; 
        } 
        return true; 
    }
    bool cIndexBuffer::CreateBuffer(LPDIRECT3DDEVICE9 pDevice, UINT numIndices, 
                                    D3DFORMAT format, bool dynamic) {
        Release();
        m_numIndices = numIndices;
    
        // Dynamic buffers can't be in D3DPOOL_MANAGED
        D3DPOOL pool = (dynamic ? D3DPOOL_DEFAULT : D3DPOOL_MANAGED);
        UINT size = ( (format == D3DFMT_INDEX32) ? sizeof(UINT) : sizeof(USHORT) );
        DWORD usage = 
            (dynamic ? D3DUSAGE_WRITEONLY | D3DUSAGE_DYNAMIC : D3DUSAGE_WRITEONLY);
    
        if(FAILED(pDevice->CreateIndexBuffer(m_numIndices * size, usage, format, 
                                             pool, &m_pIB, NULL) ) ) {
            SHOWERROR("CreateIndexBuffer failed.", __FILE__, __LINE__);
            return false;
        }
        return true;
    }
    And here is where I render it
    Code:
    void cGameApp::RenderFrame(LPDIRECT3DDEVICE9 pDevice, float ElapsedTime) {
        sprintf(m_fps, "%.2f fps", m_pFramework->GetFPS() );
    
        pDevice->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 
                       D3DCOLOR_XRGB(100, 200, 255), 1.0f, 0); 
        pDevice->BeginScene();
    
        m_terrain.Render(pDevice);
    
        // Display framerate and instructions
        m_pTextSprite->Begin(D3DXSPRITE_ALPHABLEND | D3DXSPRITE_SORT_TEXTURE);
        m_font.Print(m_fps, 5, 5, D3DCOLOR_XRGB(255, 0, 0), m_pTextSprite);
        if (m_showInstructions) {
            m_font.Print(g_instruct,5,20, D3DCOLOR_XRGB(255, 255, 255), m_pTextSprite);
        } else {
            m_font.Print("Hit F12 to view the instructions.", 5, 20, 
                         D3DCOLOR_XRGB(255, 255, 255), m_pTextSprite);
        }
        m_pTextSprite->End();
    
        pDevice->EndScene();
        pDevice->Present(0, 0, 0, 0);
        return;
    }
    void cTerrain::Render(LPDIRECT3DDEVICE9 pDevice) {
        pDevice->SetTransform(D3DTS_WORLD, GetTransform() );
        pDevice->SetTexture(0, m_pTexture);
        m_vb.Render(pDevice, m_numIndices - 2, D3DPT_TRIANGLESTRIP);
        return;
    }
    I would appreciate it if anyone could offer any suggestions as to what I am doing wrong as this is really starting to irritate me
    Using Code::Blocks and Windows XP

    In every hero, there COULD be a villain!

  3. #3
    Its hard... But im here swgh's Avatar
    Join Date
    Apr 2005
    Location
    England
    Posts
    1,688
    Bubba may be able to offer you advise on this, send him a private message or wait for his reply
    Double Helix STL

  4. #4
    Darkness Prevails Dark_Phoenix's Avatar
    Join Date
    Oct 2006
    Location
    Houston, Texas
    Posts
    174
    Quote Originally Posted by swgh
    Bubba may be able to offer you advise on this
    Yeah, I've noticed Bubba is pretty experienced with DirectX.
    Using Code::Blocks and Windows XP

    In every hero, there COULD be a villain!

  5. #5
    Darkness Prevails Dark_Phoenix's Avatar
    Join Date
    Oct 2006
    Location
    Houston, Texas
    Posts
    174
    Well, I am getting some results.... I actually have an image displayed now, but only in fullscreen mode. in windowed mode I still get only a blank screen.

    The image still is not displaying right, somewhat distorted on the right side

    Also, my FPS went from 220-230 dowm to 14! Maybe I just need a new vid card, give me an excuse to spend some money
    Attachment 6989
    Using Code::Blocks and Windows XP

    In every hero, there COULD be a villain!

  6. #6
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Quote Originally Posted by Dark_Phoenix
    I actually have an image displayed now, but only in fullscreen mode. in windowed mode I still get only a blank screen.
    That sounds like a setup issue more than anything. Can you display simple primitives in windowed mode?
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  7. #7
    Darkness Prevails Dark_Phoenix's Avatar
    Join Date
    Oct 2006
    Location
    Houston, Texas
    Posts
    174
    That sounds like a setup issue more than anything
    Yeah, that what I thought too..
    Can you display simple primitives in windowed mode
    Yup. Right now I have functionality for primitives, texture mapping, meshes, some basic lighting and I have touched on DirectInput a little. I have tested all of it in windowed and fullscreen with no problems....
    Using Code::Blocks and Windows XP

    In every hero, there COULD be a villain!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 12
    Last Post: 04-12-2009, 05:49 PM
  2. Problem Displaying a Struct
    By rockstarpirate in forum C++ Programming
    Replies: 16
    Last Post: 05-05-2008, 09:05 AM
  3. Need Help Displaying A Pattern.
    By slickwilly440 in forum C++ Programming
    Replies: 4
    Last Post: 10-05-2005, 11:01 AM
  4. Displaying Arrays
    By mr_spanky202 in forum C Programming
    Replies: 3
    Last Post: 04-07-2003, 02:22 PM
  5. Need codes for displaying figures in descending mode.
    By rbaba in forum C++ Programming
    Replies: 0
    Last Post: 12-14-2001, 08:47 PM