1 网格构建 Mesh Generation


OpenGL有点乱,但是跟着教程还是能做出能看的东西。
教程用的库都不一样,非常坑。
首先是调库的包,萌新看glu glm glut glad glew glfw这些库完全懵逼,glu网上看起来不多,glut是个老的库(过时了),一般用glfwglad就行了还有glm这个数学包。OpenGL 的东西不在这里细写了,直接拿教程改改就行。

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.


OpenGL教程里面是画一个矩形,一个矩形由两个三角形组成。水面网格就是要画一堆矩形,每个网格的高度就是水面的高度。
画一个长宽都是100的正方形网格,一共10000个网格,网格空间xy坐标范围-5到5,每个网格边长0.1,高度初始化为0。水面高度要更新,所以需要两个存储水面高度的数组。

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};

先开一个数组来存储这些网格的位置数据,存储每个点的xyz坐标和纹理的uv坐标,一共5个属性,这个数组大小就有50000。

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};

根据上面的数组属性来绑定VBO和VAO。然后我们要往数组vertices里面写数据了。

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);

先尝试给每个矩形都贴一张图,这里纹理坐标需要对应正确,否则纹理和网格显示都有问题。(给网格直接给贴一个大图目前有点问题)而且网格的位置坐标不能写串。后面的所有步骤都根据这个网格定义的数据结构来进行计算。这里用类封装一下会更方便,不用类的话之后每次都得计算一下才能获得要修改的数据。最后把这个数据写到那个数组里去。这里用的wdata
我们的网格标号从左下角开始0 1 ... 100,往上一层是101 102 ... 200。三角形是根据矩形的左下右上分割开的。形状装配那步会用上。

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:


1 网格构建 Mesh Generation_第1张图片
mesh01.png

你可能感兴趣的:(1 网格构建 Mesh Generation)