1 Mesh Generation

There are many tutorials about OpenGL that use different frameworks. It is very unfriendly to the beginners. The first tutorial I read is using GLUT which is outdated. Later I knew glfw and glad are the most popular frameworks used today. I wasted a lot of time on it. The details of the codes about OpenGL are recorded here, we edit the codes from the tutorial.

In the tutorial, it shows how to draw a rectangle that is formed by 2 triangles. So, drawing a water surface mesh we have to draw many rectangles. And the height of the mesh(Z) is the height of the water surface.
The size of the mesh is 100 and we have 10000 nodes/cells. The range of nodes position is from -5 to 5 in the XY plane. The height is initialized as 0 which we would update them later. Besides, we need two arrays to store the heights of the water surface.

static GLfloat nwater1[SIZE_WATER][SIZE_WATER] = {0.0f};
static GLfloat nwater2[SIZE_WATER][SIZE_WATER] = {0.0f};

An array to store all the information(5 attributes: the XYZ coordinates and UV coordinates). The size of it is 50000.

static GLfloat wdata[SIZE_WATER*SIZE_WATER*5] = {0.0f};

According to that array, we can bind the VBO and VAO. And we would update the data of the arrayvertices.

glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 5, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);

We try to add texture to each rectangle first. The correctness of UV coordinates of the nodes are extremely important, or we would fail to see the result we want. And the XYZ coordinates too. The following steps would be based on this mesh we now define. It could be much more convenient to use the class to encapsulate it. Or we have to compute the location in the array to get the data we want to modify.
Our indices of the mesh start from the left bottom corner: 1 2 … 100. The line above is 101 102 … 200. The rectangle is divided like this. It would be used in shape assemble step.

9900    ...  10000
.              .
.              .
.              .
101-102-103...200
 | / | / |     |
 1 - 2 - 3 ...100
for(int i = 0; i < SIZE_WATER*SIZE_WATER*5; i++)
    {
        int ii = i % 5;
        int xi = (i / 5) % SIZE_WATER;
        int yi = i / (SIZE_WATER*5);
        if(ii == 0)
        {
            wdata[i] = x + xi * det;
            
        }
        else if(ii == 1)
        {
            wdata[i] = y + yi * det;
        }
        else if(ii == 2)
        {
            int x = xi;
            int y = yi;
            if(x == 0 || y==0 || x == SIZE_WATER-1 || y == SIZE_WATER-1)
                continue;
            
            wdata[i] = nwater2[x][y];
        }
        
        else if(ii == 3)
        {
            if(xi%2==0)
                wdata[i] = 0.0f;
            else
                wdata[i] = 1.0f;
        }
        
        else if(ii == 4)
        {
            if(yi%2==0)
                wdata[i] = 0.0f;
            else
                wdata[i] = 1.0f;
        }
    }

The mesh:

mesh01.png

留下评论

通过 WordPress.com 设计一个这样的站点
从这里开始