如何为圆环创建索引

How to create indexes for the torus

本文关键字:创建 索引      更新时间:2023-10-16

我正在将旧的固定函数管道代码移植到着色器,对于圆环几何体,我无法创建正确的索引。

旧代码

int CTorus::initevVertex2Ds()
{
const float twopi = 2.0 * M_PI;
// factor for texture coordinate per step in X/Y
const float fXtex = 1. / float(m_nCorners);
const float fYtex = 1. / float(m_nTesselation);
int i;
// go around cross section
for (i = 0; i < m_nTesselation; i++) {
register int base = i * m_nCorners;
register int baseTX = i * (m_nCorners+1);
// Y texture coordinate ...
m_texcoord[baseTX].x = fYtex * float(i);
// go around top view
const float f2Pi_i_corners = (twopi * float(i+m_nTesselation/2)) / float(m_nTesselation);
const float evVertex2D_z = m_fRadiusCrossSect * fsin(f2Pi_i_corners);
const float fXY = m_fRadiusTorus + m_fRadiusCrossSect * fcos(f2Pi_i_corners);
for (int j = 0; j < m_nCorners; j++) {
register int index = base + j;
const float fXj = fcos(twopi*float(j)/m_nCorners);
const float fYj = fsin(twopi*float(j)/m_nCorners);
m_GLVertex2D[index].x = fXY * fXj;  
m_GLVertex2D[index].y = fXY * fYj;   
m_GLVertex2D[index].z = evVertex2D_z;
m_texcoord[baseTX + j].y = 1. - fXtex * float(j);
m_texcoord[baseTX + j].x = m_texcoord[baseTX].x;
const float nx =  m_GLVertex2D[index].x - m_fRadiusTorus * fXj;
const float ny =  m_GLVertex2D[index].y - m_fRadiusTorus * fYj;
const float nz =  m_GLVertex2D[index].z;
const float n = fsqrt(nx*nx + ny*ny + nz*nz);
m_norm[index].x = nx/n;
m_norm[index].y = ny/n;
m_norm[index].z = nz/n;
}
m_texcoord[baseTX + m_nCorners].y = 0.; 
m_texcoord[baseTX + m_nCorners].x = m_texcoord[baseTX].x;
}
for (i=0; i<=m_nCorners; i++) {
m_texcoord[(m_nCorners+1)*m_nTesselation+i].y = m_texcoord[i].y;
m_texcoord[(m_nCorners+1)*m_nTesselation+i].x = 1.;
}
return 0;
}

这是我将其移植到着色器的代码,但我无法正确创建元素数组缓冲区的索引

void Torus::init()
{
const float twopi = 2.0 * M_PI;
// factor for texture coordinate per step in x/y
const float fXtex = 1.0 / float(m_nCorners);
const float fYtex = 1.0 / float(m_nTesselation);
int i;
for (i = 0; i < m_nTesselation; i++)
{
register int base = i * m_nCorners;
register int baseTX = i * (m_nCorners + 1);
// go around top view
const float f2Pi_i_corners = (twopi * float(i + m_nTesselation / 2)) / float(m_nTesselation);
const float evVertex2D_z = m_fRadiusCrossSect * sinf(f2Pi_i_corners);
const float fXY = m_fRadiusTorus + m_fRadiusCrossSect * cosf(f2Pi_i_corners);
for (int j = 0; j < m_nCorners; j++)
{
register int index = base + j;

const float fXj = cosf(twopi*float(j) / m_nCorners);
const float fYj = sinf(twopi*float(j) / m_nCorners);

data.push_back(fXY * fXj);
data.push_back(fXY * fYj);
data.push_back(evVertex2D_z);
const float nx = (fXY * fXj) - m_fRadiusTorus * fXj;
const float ny = (fXY * fYj) - m_fRadiusTorus * fYj;
const float nz = evVertex2D_z;
const float n = sqrt(nx*nx + ny * ny + nz * nz);
data.push_back(nx / n);
data.push_back(ny / n);
data.push_back(nz / n);
// Pushing texture coordinates
data.push_back(0.0);
data.push_back(0.0);
}
}
std::vector<unsigned int> stdvecIndex;
unsigned int index;
// Create the indexes
for (int i = 0; i < m_nTesselation; i++)
{
index = ((i + 1) % m_nTesselation) * m_nCorners;
stdvecIndex.push_back(index);
for (int j = 0; j < m_nCorners; j++)
{
index = i * m_nCorners + j;
stdvecIndex.push_back(index);
index = ((i + 1) % m_nTesselation) * m_nCorners + ((j + 1) % m_nCorners);
stdvecIndex.push_back(index);
}
index = i * m_nCorners;
stdvecIndex.push_back(index);
}
if (!isInited)
{
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glGenVertexArrays(1, &EBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, data.size() * sizeof(float), &data[0], GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, stdvecIndex.size() * sizeof(unsigned int), &stdvecIndex[0], GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)( 3 * sizeof(float)));
glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), (void*)(6 * sizeof(float)));
}
}

我尝试为缓冲区创建索引,但不幸的是,我得到了中间损坏的几何形状而不是圆环。

步幅(第 5 个(glVertexAttribPointer参数是错误的。stride指定连续通用顶点属性之间的字节偏移量。
属性的大小为 8 (xyznxnynzuv(。 因此,步幅必须8 * sizeof(float)而不是3 * sizeof(float)

glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float)));
glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float)));