【问题标题】:How to generate a plane using GL_TRIANGLES?如何使用 GL_TRIANGLES 生成平面?
【发布时间】:2018-02-05 00:25:01
【问题描述】:

是否有一种算法可用于使用 GL_TRIANGLES 原始类型生成平面?

这是我当前的功能:

Mesh* Mesh::CreateMeshPlane(vec2 bottomleft, ivec2 numvertices, vec2 worldsize){

int numVerts = numvertices.x * numvertices.y;

float xStep = worldsize.x / (numvertices.x - 1);
float yStep = worldsize.y / (numvertices.y - 1);

VertexFormat* verts = new VertexFormat[numVerts];

for (int y = 0; y < numvertices.y; y++)
{
    for (int x = 0; x < numvertices.x; x++)
    {           
        verts[x + (y * numvertices.x)].pos.x = bottomleft.x + (xStep * x);
        verts[x + (y * numvertices.x)].pos.y = bottomleft.y + (yStep * y);
        verts[x + (y * numvertices.x)].pos.z = 0;
    }
}

Mesh* pMesh = new Mesh();
pMesh->Init(verts, numVerts, indices, 6, GL_STATIC_DRAW);

glPointSize(10.0f);
pMesh->m_PrimitiveType = GL_POINTS;

delete[] verts;

return pMesh;}

我只是不确定如何在 for 循环中实现索引以便能够知道要绘制哪些点。

我认为我需要知道的:

每个正方形由 2 个三角形组成,每个正方形需要 6 个索引

目前我是从左下角开始画的

我需要知道传入的数字中有多少个正方形

【问题讨论】:

  • 对于像这样的情况,我手头有一个记事本和一支笔——画一个草图来可视化它。
  • 每当我画一个平面时,我只画一个有 4 个顶点的 GL_TRIANGLE_STRIP(做一个正方形),然后我使用模型矩阵来画一个更大的平面
  • 我不确定你在问什么。您想知道如何为您在循环中生成的三角形生成索引吗?
  • 所以目前在我的双循环中,我只是根据我传入的内容使用 GL_POINTS 创建一个点网格。我想要做的是使用我绘制的顶点out 在创建一个正方形平面的索引列表中,其中每个正方形由 2 个三角形(6 个索引)组成

标签: c++ opengl mesh


【解决方案1】:

可能是这样的:

int width = 4;
int length = 6;
int height = 1;

std::vector<float> planeVertices;

for (int x = 0; x < width - 1; x++) {
    for (int z = 0; z < length - 1; z++) {
        planeVertices.push_back(x);
        planeVertices.push_back(height);
        planeVertices.push_back(z);

        planeVertices.push_back(x);
        planeVertices.push_back(height);
        planeVertices.push_back(z + 1);

        planeVertices.push_back(x + 1);
        planeVertices.push_back(height);
        planeVertices.push_back(z + 1);


        planeVertices.push_back(x);
        planeVertices.push_back(height);
        planeVertices.push_back(z);

        planeVertices.push_back(x + 1);
        planeVertices.push_back(height);
        planeVertices.push_back(z);

        planeVertices.push_back(x + 1);
        planeVertices.push_back(height);
        planeVertices.push_back(z + 1);
    }
}

...

unsigned int VBO, VAO;
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);

glBindVertexArray(VAO);

glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, planeVertices.size() * sizeof(float), planeVertices.data(), GL_STATIC_DRAW);

glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), 0);
glEnableVertexAttribArray(0);

...

glDrawArrays(GL_TRIANGLES, 0, (width - 1) * (length - 1) * 6);

此代码创建一个std::vector&lt;float&gt; 并向其添加平面顶点。嵌套的for 循环为平面的每个单位添加两个三角形(因此,width 为 4,length 为 6,平面将是 4 个单位乘以 6 个单位,由 6 * 4 * 2 = 48 个三角形)。平面的高度由height 变量设置。这只会生成平面,但一个简单的变换可以让您根据需要旋转和缩放它。

警告:此代码未经测试。

【讨论】:

    【解决方案2】:

    为了结束这个问题,我是这样做的:

    Mesh* Mesh::CreateMeshPlane(vec3 bottomleft, ivec2 numvertices, vec2 
    worldsize, vec2 texturerepetition)
    {
        int numVerts = numvertices.x * numvertices.y;
        int numFaces = (numvertices.x - 1) * (numvertices.y - 1);
        int numIndices = numFaces * 6;
    
        float xStep = worldsize.x / (numvertices.x - 1);
        float yStep = worldsize.y / (numvertices.y - 1);
        float zStep = worldsize.y / (numvertices.y - 1);
    
        float uStep = texturerepetition.x / (numvertices.x - 1);
        float vStep = texturerepetition.y / (numvertices.y - 1);
    
        VertexFormat* verts = new VertexFormat[numVerts];
        unsigned int* indices = new unsigned int[numIndices];
    
        for (int y = 0; y < numvertices.y; y++)
        {
            for (int x = 0; x < numvertices.x; x++)
            {
                verts[x + (y * numvertices.x)].pos.x = bottomleft.x + (xStep * x);
                verts[x + (y * numvertices.x)].pos.y = bottomleft.y;
                verts[x + (y * numvertices.x)].pos.z = bottomleft.z + (zStep * y);
    
                verts[y * numvertices.x + x].uv.x = uStep * x;
                verts[y * numvertices.x + x].uv.y = vStep * y;
            }
        }
    
        int offset = 0;
    
        for (int i = 0; i < numIndices; i++)
        {
            // The bottom left index of the current face
            // + the offset to snap back when we hit the edge
            unsigned int cornerIndex = i/6 + offset;
    
            // If we reach the edge we increase the offset so that it goes to the next bottom left
            if ((cornerIndex + 1)%numvertices.x == 0)
            {
                offset++;
                cornerIndex++; // Adding new offset to the bottom left
            }
    
            // First triangle
            indices[i] = (unsigned int)cornerIndex;
            i++;
            indices[i] = (unsigned int)cornerIndex + numvertices.x;
            i++;
            indices[i] = (unsigned int)cornerIndex + numvertices.x + 1;
            i++;
    
            // Second triangle
            indices[i] = (unsigned int)cornerIndex;
            i++;
            indices[i] = (unsigned int)cornerIndex + numvertices.x + 1;
            i++;
            indices[i] = (unsigned int)cornerIndex + 1;
        }
    
        //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
    
        Mesh* pMesh = new Mesh();
        pMesh->Init(verts, numVerts, indices, numIndices, GL_STATIC_DRAW);
    
        delete[] verts;
    
        return pMesh;
    }
    

    工作流程: 1.计算我需要的面数,然后是索引数 2. 当我们意识到我们到达顶点数组的边缘时,创建一个添加到cornerIndex的偏移量(通过使用模数numvertices.y) 3. 做简单的数学运算,根据cornerIndex以正确的顺序绘制角

    注意事项: 1. 我使用 GL_TRIANGLES 作为原始类型进行绘图 2.从左下到右上绘制 3. 因此,cornerIndex 是我们正在绘制的当前正方形的左下角

    希望有人能从中受益!

    【讨论】:

      猜你喜欢
      • 2012-09-17
      • 2015-01-17
      • 1970-01-01
      • 2017-01-29
      • 2017-05-17
      • 1970-01-01
      • 1970-01-01
      • 2014-03-15
      • 2011-07-14
      相关资源
      最近更新 更多