使用 glDrawElements、索引缓冲区并启用 GL_CULL_FACE 绘制横向圆柱体
Draw cylinder lateral with glDrawElements, Index Buffer and enabled GL_CULL_FACE
我需要这个:
我必须使用 glDrawElements
和这个:glEnable(GL_CULL_FACE)
。
我尝试了什么:
...
glm::vec3 CMyApp::GetCylinderUV(float u, float v)
{
u *= 2* 3.1415f;
float r = 1;
return glm::vec3(r * cosf(u), 2 * v, r * sinf(u));
}
...
glEnable(GL_CULL_FACE);
...
Vertex vert[(N+1)*(M+1)];
for (int i=0; i<=N; ++i)
for (int j=0; j<=M; ++j)
{
float u = i/(float)N;
float v = j/(float)M;
vert[i + j*(N + 1)].p = GetCylinderUV(u, v);
vert[i + j*(N+1)].c = glm::normalize( vert[i + j*(N+1)].p );
}
...
GLushort indices[3*2*(N)*(M)];
for (int i=0; i<N; ++i)
for (int j=0; j<M; ++j)
{
// (i,j+1)
// o-----o(i+1,j+1)
// |\ | a = p(u_i, v_i)
// | \ | b = p(u_{i+1}, v_i)
// | \ | c = p(u_i, v_{i+1})
// | \ | d = p(u_{i+1}, v_{i+1})
// | \|
// (i,j) o-----o(i+1, j)
indices[6*i + j*3*2*(N) + 0] = (i) + (j)* (N+1);
indices[6*i + j*3*2*(N) + 1] = (i+1) + (j)* (N+1);
indices[6*i + j*3*2*(N) + 2] = (i) + (j+1)*(N+1);
indices[6*i + j*3*2*(N) + 3] = (i+1) + (j)* (N+1);
indices[6*i + j*3*2*(N) + 4] = (i+1) + (j+1)*(N+1);
indices[6*i + j*3*2*(N) + 5] = (i) + (j+1)*(N+1);
}
glDrawElements( GL_TRIANGLES,
3*2*(N)*(M),
GL_UNSIGNED_SHORT,
0);
糟糕的结果:
但它可以通过删除 glEnable(GL_CULL_FACE);
来修复,但我必须使用它。
根据您的几何图形,您可以使用两个绘图通道(并保持 glEnable(GL_CULL_FACE)
)来完成此操作。
- Pass1 - 用
glFrontFace(GL_BACK)
渲染。这将呈现 tube 的 "back" 部分
- Pass2 - 用
glFrontFace(GL_FRONT)
渲染。这将渲染管的 "front" 部分。
希望对您有所帮助!
我终于找到了问题的答案:
- 在
GetCylinderUV
中我否定了你:u *= -2 * 3.1415f;
。需要把侧面翻出来。
我需要这个:
我必须使用 glDrawElements
和这个:glEnable(GL_CULL_FACE)
。
我尝试了什么:
...
glm::vec3 CMyApp::GetCylinderUV(float u, float v)
{
u *= 2* 3.1415f;
float r = 1;
return glm::vec3(r * cosf(u), 2 * v, r * sinf(u));
}
...
glEnable(GL_CULL_FACE);
...
Vertex vert[(N+1)*(M+1)];
for (int i=0; i<=N; ++i)
for (int j=0; j<=M; ++j)
{
float u = i/(float)N;
float v = j/(float)M;
vert[i + j*(N + 1)].p = GetCylinderUV(u, v);
vert[i + j*(N+1)].c = glm::normalize( vert[i + j*(N+1)].p );
}
...
GLushort indices[3*2*(N)*(M)];
for (int i=0; i<N; ++i)
for (int j=0; j<M; ++j)
{
// (i,j+1)
// o-----o(i+1,j+1)
// |\ | a = p(u_i, v_i)
// | \ | b = p(u_{i+1}, v_i)
// | \ | c = p(u_i, v_{i+1})
// | \ | d = p(u_{i+1}, v_{i+1})
// | \|
// (i,j) o-----o(i+1, j)
indices[6*i + j*3*2*(N) + 0] = (i) + (j)* (N+1);
indices[6*i + j*3*2*(N) + 1] = (i+1) + (j)* (N+1);
indices[6*i + j*3*2*(N) + 2] = (i) + (j+1)*(N+1);
indices[6*i + j*3*2*(N) + 3] = (i+1) + (j)* (N+1);
indices[6*i + j*3*2*(N) + 4] = (i+1) + (j+1)*(N+1);
indices[6*i + j*3*2*(N) + 5] = (i) + (j+1)*(N+1);
}
glDrawElements( GL_TRIANGLES,
3*2*(N)*(M),
GL_UNSIGNED_SHORT,
0);
糟糕的结果:
但它可以通过删除 glEnable(GL_CULL_FACE);
来修复,但我必须使用它。
根据您的几何图形,您可以使用两个绘图通道(并保持 glEnable(GL_CULL_FACE)
)来完成此操作。
- Pass1 - 用
glFrontFace(GL_BACK)
渲染。这将呈现 tube 的 "back" 部分
- Pass2 - 用
glFrontFace(GL_FRONT)
渲染。这将渲染管的 "front" 部分。
希望对您有所帮助!
我终于找到了问题的答案:
- 在
GetCylinderUV
中我否定了你:u *= -2 * 3.1415f;
。需要把侧面翻出来。