如何使用GL_TRIANGLES生成平面
How to generate a plane using GL_TRIANGLES?
有没有一种算法可以用来使用 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 个索引
目前我从左下角绘图
我需要知道从传入的数字中有多少个正方形
也许是这样的:
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<float>
并将平面顶点添加到其中。嵌套的 for
循环为平面的每个单位添加两个三角形(因此,width
为 4,length
为 6,平面将是 4 个单位乘以 6 个单位,将由 6 * 4 * 2 = 48 个三角形组成(。平面的高度由height
变量设置。这只会生成平面,但简单的变换可让您根据需要旋转和缩放它。
警告:此代码未经测试。
只是为了结束这个问题,这是我是如何做到的:
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. 创建一个偏移量,当我们意识到我们到达顶点数组的边缘时,该偏移量将添加到角索引(通过使用模数 numvertices.y(3. 做简单的数学运算,根据角索引以正确的顺序画角
笔记:1. 使用 GL_TRIANGLES 作为基元类型进行绘制2. 从左下角到右上角绘图3. 因此,角落索引是我们正在绘制的当前正方形的左下角
希望有人能发现这有帮助!
相关文章:
- 在 cpp 中的平面缓冲区中序列化对象
- 将平面阵列重塑为复杂的特征类型
- CGAL:在浏览平面地图时使用类型"标记"
- 平面缓冲区可以利用向量中的 0 吗?还是其他小波比哈尔变换更好?
- 他们如何将红外锁定像素转换为镜头前方 1m 的正常平面上的位置
- 如何找到两个棋盘平面之间的角度?
- 平面和球体光线追踪之间的交点
- 从矢量数组制作平面文件
- 从 TS 到C++的平面缓冲区不起作用
- 如何在C++中加快平面到打包/交错图形的速度?
- 从一组点C++平面插值
- 使用(非对象)API 时改变表数组C++而不重新创建整个平面缓冲区
- 使用createHillPlaneMesh处理地板平面
- 使用 CGAL 将多面体投影到 xy 平面
- 将嵌套的 std::arrays 视为具有链式 .data() 的单个平面数组
- 如何从平面缓冲区中反序列化联合结构的 void* 值的大小
- 使用平面缓冲区读取以前写入的二进制文件的数据
- D3DXPLANENERAMALAGE仅返回归一化平面或对其进行修改
- 如何在 RANSAC 平面估算器中包含自定义约束/排名?
- 平面缓冲区::表* 到 buffer_pointer