То есть N
- это количество точек на окружности круга, а M
- это количество точек на высоту ...
LOL в вашем GetUV
вы вычисляете cu,su,cv,sv
, но не используете их, вместо этого вы снова используете те же вызовы sin
и cos
. если я вижу это правильно, u=<0,1>
отображает окружность круга / цилиндра (плоскость XZ), а v=<0,1>
отображает высоту (Y). Но похоже, что сама функция работает как следует (чуть медленнее, чем это возможно) из-за этого неточного M_PI
использования, которое может вызвать артефакты.
Первая проблема Я вижу это
vert[i + j*(N+1)].c = glm::normalize( vert[i + j*(N+1)].p );
Я бы избавился от этой линии, поскольку она создаст конус ... который вам больше не нужен (кстати, очень странный и медленный метод создания конуса)
Также i + j*(N+1)
уродлив, вместо этого я бы сделал:
for (int ix=0,j=0; j<=M; j++)
for (int i=0; i<=N; i++,ix++)
{
float u = i/(float)N;
float v = j/(float)M;
vert[ix].p = GetUV(u, v);
}
Следующая проблема Вы получили неправильное использование методов Draw ... так как вам нужна сетка точек вместо двух кругов, вы разделили материал на GL_TRIANGLE_FAN
и GL_TRIANGLES
. Это было почти правильно, но вы должны иметь:
2x GL_TRIANGLE_FAN
по одному на каждую базу
1x GL_TRIANGLES
или GL_QUADS для остальных
так как вы хотите использовать индексы, в основном проще / быстрее использовать все в качестве треугольников и правильно заполнять буфер индексов, чтобы вы получили только один вызов отрисовки. К сожалению, мы не видим ту часть кода, где вы вычисляете индексы ...
Почему N+1
и M+1
баллов? Вам не нужно дублировать первую точку в vert[]
, вместо этого вы можете сделать это в индексах ...
Надеюсь, что часть кода, связанная с VBO , верна ...
Также помните, что грани другого круга должны иметь точки в обратном порядке, поэтому GL_CULL_FACE
будет правильно отбирать грани ...
[Edit1] C ++ пример
В любом случае, если вы хотите использовать последние нормалы, вы должны также дублировать заглавные буквы из-за различных нормалей на краю ... Если я соберу все вместе в моем стиле кодирования, я получу это:
//---------------------------------------------------------------------------
const int M=20; // points per circle circumference
const int N=10; // point per cylinder height
const int pnts=3*((M*(N+2))+2); // 3* number of points
const int facs=3*M*(N+N+2); // 3* number of indices
float pnt[pnts]; // (x,y,z) position per each point
float nor[pnts]; // (x,y,z) normal per each point
int fac[facs]; // (i0,i1,i2) indices per each TRIANGLE
//---------------------------------------------------------------------------
void cylinder_init(float r,float h)
{
int i,j,ix,i0,i1,i2,i3;
float x,y,z,a,da,dz;
// compute position and normals
ix=0;
dz=h/double(N-1);
da=2.0*M_PI/double(M);
for (z=-0.5*h,j=0;j<N;j++,z+=dz) // circles
for (a=0.0,i=0;i<M;i++,a+=da)
{
x=cos(a);
y=sin(a);
pnt[ix]=r*x; nor[ix]=x; ix++;
pnt[ix]=r*y; nor[ix]=y; ix++;
pnt[ix]=z; nor[ix]=0.0; ix++;
}
pnt[ix]= 0.0; nor[ix]= 0.0; ix++; // top cap
pnt[ix]= 0.0; nor[ix]= 0.0; ix++;
pnt[ix]=+0.5*h; nor[ix]=+1.0; ix++;
for (j=ix-3*(M+1),i=0;i<M;i++)
{
pnt[ix]=pnt[j]; nor[ix]= 0.0; ix++; j++;
pnt[ix]=pnt[j]; nor[ix]= 0.0; ix++; j++;
pnt[ix]=pnt[j]; nor[ix]=+1.0; ix++; j++;
}
pnt[ix]= 0.0; nor[ix]= 0.0; ix++; // bottom cap
pnt[ix]= 0.0; nor[ix]= 0.0; ix++;
pnt[ix]=-0.5*h; nor[ix]=-1.0; ix++;
for (j=0,i=0;i<M;i++)
{
pnt[ix]=pnt[j]; nor[ix]= 0.0; ix++; j++;
pnt[ix]=pnt[j]; nor[ix]= 0.0; ix++; j++;
pnt[ix]=pnt[j]; nor[ix]=-1.0; ix++; j++;
}
// compute triangle indices
ix=0; i0=M-1; i1=0; i2=i0+M; i3=i1+M; // circles
for (j=0;j<N-1;j++,i0+=M,i2+=M)
for (i=0;i<M;i++,i0=i1,i1++,i2=i3,i3++)
{
fac[ix]=i0; ix++;
fac[ix]=i1; ix++;
fac[ix]=i2; ix++;
fac[ix]=i2; ix++;
fac[ix]=i1; ix++;
fac[ix]=i3; ix++;
}
i2=M*N; i0=i2+M; i1=i2+1; // top cap
for (i=0;i<M;i++,i0=i1,i1++)
{
fac[ix]=i0; ix++;
fac[ix]=i1; ix++;
fac[ix]=i2; ix++;
}
i2+=M+1; i0=i2+M; i1=i2+1; // bottom cap
for (i=0;i<M;i++,i0=i1,i1++)
{
fac[ix]=i2; ix++;
fac[ix]=i1; ix++;
fac[ix]=i0; ix++;
}
}
//---------------------------------------------------------------------------
И предварительный просмотр:
Вы просто используете одно рисование с GL_TRIANGLES
для всего буфера индексов fac[facs]
.