Archived

This topic is now archived and is closed to further replies.

Squirell

Terrain Generation

Recommended Posts

Im trying to create 100 squares in a 10x10 layout. I render these onto the screen and i apply the texture. This is so that once i accomplish this i only have to raise and lower the z values to make a simple terrain. Anyway, my program executes fine but it doesnt display anything on the screen. Im assuming there is something wrong with my vertex buffer. Could someone please help me. Here is the code InitialiseVertexBuffer()
struct CUSTOMVERTEX
{
    FLOAT x, y, z; 
    FLOAT tu, tv; 
};

#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_TEX1)

HRESULT InitialiseVertexBuffer()
{       
    VOID* pVertices;
    CUSTOMVERTEX pcvVertices[600];
    
    int SquareSize = 10;
    int SquareNumber = 10;
    
    //Loop through for each sqaure

    //100 squares total (10x10)

    int i=0;
    for(int loopA=0; loopA < SquareNumber; loopA++) {
        for(int loopB=0; loopB <SquareNumber; loopB++) {
            //Vertex 1

            pcvVertices[i].x = loopB*10;
            pcvVertices[i].y = loopA*10;
            pcvVertices[i].z = 0;
            pcvVertices[i].tu = 0;
            pcvVertices[i].tv = 0;
            
            i += 1;
            
            //Vertex 2

            pcvVertices[i].x = loopB*10+10;
            pcvVertices[i].y = loopA*10+10;
            pcvVertices[i].z = 0;
            pcvVertices[i].tu = 1;
            pcvVertices[i].tv = 1;
            
            i += 1;
            
            //Vertex 3

            pcvVertices[i].x = loopB*10;
            pcvVertices[i].y = loopA*10+10;
            pcvVertices[i].z = 0;
            pcvVertices[i].tu = 0;
            pcvVertices[i].tv = 1;
            
            i += 1;
            
            //Vertex 4

            pcvVertices[i].x = loopB*10;
            pcvVertices[i].y = loopA*10;
            pcvVertices[i].z = 0;
            pcvVertices[i].tu = 0;
            pcvVertices[i].tv = 0;
            
            i += 1;
            
            //Vertex 5

            pcvVertices[i].x = loopB*10+10;
            pcvVertices[i].y = loopA*10;
            pcvVertices[i].z = 0;
            pcvVertices[i].tu = 1;
            pcvVertices[i].tv = 0;
            
            i += 1;
            
            //Vertex 6

            pcvVertices[i].x = loopB*10+10;
            pcvVertices[i].y = loopA*10+10;
            pcvVertices[i].z = 0;
            pcvVertices[i].tu = 1;
            pcvVertices[i].tv = 1;
            
            i += 1;
        }
    }
    
    //Terrain will be "flat"along xy plane, z value will be adjusted to obtain hills

    /*CUSTOMVERTEX cvVertices[] =
    { 
        //Square
        {0.0f, 0.0f, 0.0f , 0.0f, 0.0f,}, //Vertex 0 - Blue 
        {0.0f, -10.0f, 0.0f, 1.0f, 0.0f,}, //Vertex 1 - Red 
        {-10.0f, 0.0f, 0.0f, 0.0f, 1.0f,}, //Vertex 2 - Red 
        
        {0.0f, -10.0f, 0.0f, 1.0f, 0.0f,}, //Vertex 1 - Red 
        {-10.0f, -10.0f, 0.0f,  1.0f, 1.0f,}, //Vertex 0 - Blue 
        {-10.0f, 0.0f, 0.0f, 0.0f, 1.0f,},//Vertex 2 - Red 


    };*/

    //Create the vertex buffer from our device.

    if(FAILED(g_pD3DDevice->CreateVertexBuffer(600 * sizeof(CUSTOMVERTEX),
                                               0, D3DFVF_CUSTOMVERTEX,
                                               D3DPOOL_DEFAULT, &g_pVertexBuffer, NULL)))
    {
        WriteToLog("Failed to create Vertex Buffer");
        return E_FAIL;
    }


    //Get a pointer to the vertex buffer vertices and lock the vertex buffer

    if(FAILED(g_pVertexBuffer->Lock(0, sizeof(pcvVertices), &pVertices, 0)))
    {
        WriteToLog("Failed to lock vertex buffer");
        return E_FAIL;
    }

    //Copy our stored vertices values into the vertex buffer

    memcpy(pVertices, pcvVertices, sizeof(pcvVertices));

    //Unlock the vertex buffer

    g_pVertexBuffer->Unlock();
    
    WriteToLog("Vertex Buffer Initilized");
    WriteToLog(" ");

    return S_OK;
}
Render()
void Render()
{
    if(g_pD3DDevice == NULL)
    {
        return;
    }

    //Clear the backbuffer to black

    g_pD3DDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
    
    //Begin the scene

    g_pD3DDevice->BeginScene();
    
    //Setup the camera and perspective matrices

    SetupCamera();
    SetupPerspective();


    //Rendering our objects

    g_pD3DDevice->SetStreamSource(0, g_pVertexBuffer, 0, sizeof(CUSTOMVERTEX));
    g_pD3DDevice->SetFVF(D3DFVF_CUSTOMVERTEX);
    g_pD3DDevice->SetTexture(0, g_pTexture);
    g_pD3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
    
    g_pD3DDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 200); 


    //End the scene

    g_pD3DDevice->EndScene();
    
    //Filp the back and front buffers so that whatever has been rendered on the back buffer

    //will now be visible on screen (front buffer).

    g_pD3DDevice->Present(NULL, NULL, NULL, NULL);
}
SetupCamera() and SetupPerspective()
void SetupCamera()
{
    //Here we will setup the camera.

    //The camera has three settings: "Camera Position", "Look at Position" and "Up Direction"

    //We have set the following:

    //Camera Position: (0, 0, -30)

    //Look at Position: (0, 0, 0)

    //Up direction: Y-Axis.

    D3DXMATRIX matView;
    D3DXVECTOR3 camera, look, up;
    camera = D3DXVECTOR3(0.0f, 0.0f,-300.0f);
    look = D3DXVECTOR3(0.0f, 0.0f, 0.0f);
    up = D3DXVECTOR3(0.0f, 1.0f, 0.0f);
    
    D3DXMatrixLookAtLH(&matView, &camera, //Camera Position

                                 &look, //Look At Position

                                 &up); //Up Direction

    g_pD3DDevice->SetTransform(D3DTS_VIEW, &matView);
}

void SetupPerspective()
{
    //Here we specify the field of view, aspect ration and near and far clipping planes.

    D3DXMATRIX matProj;
    D3DXMatrixPerspectiveFovLH(&matProj, D3DX_PI/4, 1.0f, 1.0f, 500.0f);
    g_pD3DDevice->SetTransform(D3DTS_PROJECTION, &matProj);
}
Thank you in advance

Share this post


Link to post
Share on other sites
What I can suggest is the following:

A. Draw one square.
B. Draw 2 squares with a loop.
B. Draw 2x2 squares with a loop.
C. Draw all 10x10 squares.

If you get stuck again, try and find the exact piece that is giving you trouble.


[edited by - OrenGL on April 22, 2004 3:20:26 PM]

Share this post


Link to post
Share on other sites
A couple of suggestions:

1) I didn''t see where you set your world transform (presumably to 0,0,0).
2) Are you culling CCW or CW? In this case, you''d want it to be CW.
3) Did you turn Lighting off?

Chris

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
You need to create your terrain in the (x,z) plane instead of the (x,y) plane. The (x,z) plane is the horizontal one going in and out of your screen (so-to-speak.) The (x,y) plane is the vertical plane running up and down your screen (i.e. It is your screen).

If you really want to keep your terrain in the (x,y) plane then you need to modify your camera so that negative z is the "up" vector. I personally prefer (x,z) terrain using the y axis as the height.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
I should add that you will also have to modify the camera position vector so that it uses "-y" as the position.

Another way to correct this is, once you have generated your (x,y) terrain, rotate all of those vertices 90 degrees around the x axis to the (x,z) plane.

The easiest route would be to simlpy generate your terrain in the (x,z) plane to begin with. (i.e. x = ???, y = 0, z = ???)

Share this post


Link to post
Share on other sites
I''ve just completed doing essentially the same exact thing you are working on, though I have no intention of modifying height. Mine is strictly for a 2d top down engine, but I can inject some assistance I believe, as I actually have mine running right now.

1. DirectX coords have Z going in/out of the screen. I don''t know what AP is talking about, but you want your camera position on the -Z axis, and your tiles layed out in the x,y plane. That is exactly what I''m doing and it is what the Direct3D tutorials do.

2. As was said, make sure lighting is turned off, or at best you''ll just get black quads rendered.

3. Your Render stage. With my setup, I am rendering each textured quad with seperate DrawPrimitive calls. I have my vertex buffer filled with the quad locations very similar to what you''ve done (except my quads are just 1.0x1.0, made the calculations easier). In my Render stage though I set up another loop and make a DrawPrimitive call indexed into my vertbuffer to just render the two tris that make up each quad. I have to do this because I''m rendering them as individual tiles with seperate textures, and I set the appropriate texture in the loop before calling DrawPrimitive.

4. As was said (again), set up your world transform. I don''t know if this is absolutely necessary, but set it up and you won''t have to worry whether or not it is.

5. The order you assign the corners of your textured quad is critical. I think I have mine set up rendering as a triangle strip, and that required the points in the following order... lower left, upper left, lower right, upper right. Direct3D wants the vertex list in an order that allows it to draw the triangles in clockwise order. The first triangle in a strip is drawn vert 0, 1, 2. The second triangle in the strip, to maintain clockwise order, is drawn either 1, 3, 2 or 2, 1, 3. I''m not immediately familiar with the order required for a triangle list, but it looks like you''ve got the vertices set up to render both triangles in clockwise order. You should still double check that, and draw it out on paper for a triple check. If the vertices are out of order, it won''t render. You may also want to look into using strips instead as well. This allows you to render your quad with just the four corner points, and avoids using two duplicate vertices. You just need to specify the quad corners in the order I listed above.

I can send you my own code later tonight if you want. I''m still learning this stuff myself as well, so the code is a bit messy and unclean/unprotected, but it works.

Share this post


Link to post
Share on other sites
Sending me code would be incredibly helpful if you can. Although I''ll probably modify it to render along xz plane, because that will make it better for my purposes (camera moves above terrain at like 20 on y axis tilted downwards).

Share this post


Link to post
Share on other sites