-2

I need to generate procedural terrain using Noise (using Perlin noise) in OpenGL. Each time the application runs a new terrain, it needs to be generated using a new seed. (Do not use external library.) Is there a method/requirement needed when making a class for noise terrains. What functions/calculation i need to call and in which order ?

PS: I use Visual Studio 2019.

// Copy the array data into a float array, and scale and offset the heights.
    mHeightmap.resize(NumRows * NumCols, 0);
    for( int i = 0; i < NumRows * NumCols; ++i)
    {
        mHeightmap[i] = (float)in[i] * HeightScale;
    }

// A height for each vertex
{
    std::vector<unsigned char> in(NumRows * NumCols);

    // Open the file.
    std::ifstream inFile;
    inFile.open(heightmapName.c_str(), std::ios_base::binary);

    if (inFile)
    {
        // Read the RAW bytes.
        inFile.read((char*)&in[0], (std::streamsize)in.size());

        // Done with file.
        inFile.close();
    }

    // Copy the array data into a float array, and scale and offset the heights.
    mHeightmap.resize(NumRows * NumCols, 0);
    for( int i = 0; i < NumRows * NumCols; ++i)
    {
        mHeightmap[i] = (float)in[i] * HeightScale;
    }

void Terrain::CreateVAO()
{
    std::vector<GLfloat> vertices;
    vertices.reserve(NumCols * NumRows * 8);
    

    float invTwoDX = 1.0f / (2.0f * CellSpacing);
    float invTwoDZ = 1.0f / (2.0f * CellSpacing);

    //vertices 
    for ( int z = 0; z < NumRows; z++)
    {
        for ( int x = 0; x < NumCols; x++)
        {
            
            //vertex data
            int i = z * NumCols + x;
            vertices.push_back((float)x*CellSpacing);
            vertices.push_back(mHeightmap[i]);
            vertices.push_back((float)z * CellSpacing);

            //normal data

            glm::vec3 _N = { 0.0f,1.0f, 0.0f };

            if(z >= 1 && z < NumRows -1 && x >= 1 && z < NumCols - 1)
            { 
                float t = mHeightmap[(z - 1) * NumCols + x];
                float b = mHeightmap[(z + 1) * NumCols + x];
                float l = mHeightmap[z * NumCols + x - 1];
                float r = mHeightmap[z * NumCols + x + 1];

                glm::vec3 tanZ(0.0f, (b - t) * invTwoDZ, 1.0f);
                glm::vec3 tanX(1.0f, (r - l) * invTwoDX, 0.0f);

                glm::vec3 _C, _N;
                _C = glm::cross(tanZ, tanX);
                _N = glm::normalize(_C);

                
            }
            
            vertices.push_back(_N.x);
            vertices.push_back(_N.y);
            vertices.push_back(_N.z);


            vertices.push_back((float)x);
            vertices.push_back((float)z);


        }
    }
    

    std::vector<GLuint> indices;
    vertices.reserve((NumCols-1)*(NumRows -1)*6);
    //indices
    for ( int z = 0; z < NumRows-1; z++)
    {
        for ( int x = 0; x < NumCols-1; x++)
        {
            GLint a = z * NumCols + x;
            GLint b = (z +1) * NumCols + x;
            GLint c = z * NumCols + (x+1);
            GLint d = (z+1) * NumCols + (x+1);

            indices.push_back(c);
            indices.push_back(a);
            indices.push_back(b);

            indices.push_back(c);
            indices.push_back(b);
            indices.push_back(d);
        
        }
    }
    indexcount = indices.size();


    GLuint VBO, EBO;


    glGenVertexArrays(1, &VAO);
    glBindVertexArray(VAO);

    glGenBuffers(1, &EBO);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(GLuint), indices.data(), GL_STATIC_DRAW);

    glGenBuffers(1, &VBO);
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, vertices.size()*sizeof(GLfloat), vertices.data(), GL_STATIC_DRAW);

    glVertexAttribPointer(
        0,
        3,
        GL_FLOAT,
        GL_FALSE,
        8 * sizeof(GLfloat), //Strude of the single vertex(pos)
        (GLvoid*)0); //Offset from beginning of Vertex
    glEnableVertexAttribArray(0);

    glVertexAttribPointer(
        1,
        3,
        GL_FLOAT,
        GL_FALSE,
        8 * sizeof(GLfloat), //Strude of the single vertex(pos+color)
        (GLvoid*)(3 * sizeof(GLfloat))); //Offset from beginning of Vertex
    glEnableVertexAttribArray(1);

    glVertexAttribPointer(
        2,
        2, //2 float component for coordinates
        GL_FLOAT,
        GL_FALSE,
        8 * sizeof(GLfloat), //Strude of the single vertex(pos+color+texture)
        (GLvoid*)(6 * sizeof(GLfloat)));//Offset from beginning of Vertex
    glEnableVertexAttribArray(2);
Heyji
  • 1,113
  • 8
  • 26
  • 2
    Where is your work? – Geno C Oct 31 '20 at 06:32
  • i just put it up, unless you want me to send it in a zip file – Loki Satou Oct 31 '20 at 08:31
  • @Loki Satou, your question is too broad. It is as if you were asking "what shall I do to build my own website ? Here is my html code..." You should narrow you problem down to something simpler, and ask a more concrete question. To do that, you can edit your own question. It seems your question is more about how to use Perlin Noise functions. If so, you might want to clarify what library those function are issued from, and what their manual do not state which leads you to a question on Stack Overflow (S.O.) – Heyji Oct 31 '20 at 21:46
  • Where is your part of research? – armagedescu Nov 01 '20 at 18:26

1 Answers1

1

I'm not sure if I see usage of Perlin noise in your code. Try this lightweight, easy to integrate library: https://github.com/Auburn/FastNoise which has Perlin and tons of other useful stuff like a visualizer. Usage is as simple as noise.GetNoise((float)x, (float)y); which you can plug into your height function