1

我正在创建一个程序,允许我在 3 个空间中绘制点,使用 Catmull-Rom 样条线连接它们,然后围绕样条线绘制一个圆柱体。我正在使用GL_TRIANGLES_STRIP以短间隔连接围绕样条线绘制的点圈,希望将它们全部连接到样条线周围的圆柱体中。

我已经设法在这些间隔处绘制完整的点圆,使用GL_POINTS,并将它们正确定位到关于 Frenet 框架的线。不幸的是,要使用GL_TRIANGLE_STRIP,我相信我需要在一组两个点之间一次绘制一个点。

我遇到的问题是,glMultMatrixglBegin. 下面的代码将绘制一个点圈,但在原点,glMultMatrix我用来平移和定位点圈的glbegin. 有针对这个的解决方法吗?

  //The matrixes that are applied to the circle of points
  GLfloat M1[16]={
    N1.x(),N1.y(),N1.z(),0,
    B1.x(),B1.y(),B1.z(),0,
    T1.x(),T1.y(),T1.z(),0,
    fromPoint->x,fromPoint->y,fromPoint->z,1
  };

  GLfloat M2[16]={
    N2.x(),N2.y(),N2.z(),0,
    B2.x(),B2.y(),B2.z(),0,
    T2.x(),T2.y(),T2.z(),0,
    toPoint->x,toPoint->y,toPoint->z,1
  };

  glBegin(GL_TRIANGLE_STRIP);
  GLfloat x, y;
  GLfloat radius = 0.4f;
  GLint pointCount = 180;
  for (GLfloat theta = 0; theta < 2*M_PI; theta += (2*M_PI)/pointCount) {
    x = radius * cos(theta);
    y = radius * sin(theta);

    // Now push a matrix, multiply it, draw a point and pop the matrix
    glPushMatrix();
    glMultMatrixf(& M1[0]);
    // Draw the point here
    glVertex3f(x, y, 0);
    glPopMatrix();

    // Do the same again for the second section
    glPushMatrix();
    glMultMatrixf(& M2[0]);
    glVertex3f(x, y, 0);
    glPopMatrix();
  }
  glEnd();
4

2 回答 2

5

我遇到的问题是 glMultMatrix 在 glBegin 内似乎不起作用

不足为奇:

在 glBegin 和 glEnd 之间只能使用 GL 命令的子集。这些命令是 glVertex、glColor、glSecondaryColor、glIndex、glNormal、glFogCoord、glTexCoord、glMultiTexCoord、glVertexAttrib、glEvalCoord、glEvalPoint、glArrayElement、glMaterial 和 glEdgeFlag。此外,可以使用 glCallList 或 glCallLists 来执行仅包含上述命令的显示列表。 如果在 glBegin 和 glEnd 之间执行了任何其他 GL 命令,则设置错误标志并忽略该命令。

glMultMatrix() 之前 glBegin()

//The matrixes that are applied to the circle of points
GLfloat M1[16]=
{
    N1.x(),N1.y(),N1.z(),0,
    B1.x(),B1.y(),B1.z(),0,
    T1.x(),T1.y(),T1.z(),0,
    fromPoint->x,fromPoint->y,fromPoint->z,1
};

GLfloat M2[16]=
{
    N2.x(),N2.y(),N2.z(),0,
    B2.x(),B2.y(),B2.z(),0,
    T2.x(),T2.y(),T2.z(),0,
    toPoint->x,toPoint->y,toPoint->z,1
};

GLfloat x, y;
GLfloat radius = 0.4f;
GLint pointCount = 180;
for (GLfloat theta = 0; theta < 2*M_PI; theta += (2*M_PI)/pointCount) 
{
    x = radius * cos(theta);
    y = radius * sin(theta);

    // Now push a matrix, multiply it, draw a point and pop the matrix
    glPushMatrix();
    glMultMatrixf(& M1[0]);
    // Draw the point here
    glBegin(GL_POINTS);
    glVertex3f(x, y, 0);
    glEnd();
    glPopMatrix();

    // Do the same again for the second section
    glPushMatrix();
    glMultMatrixf(& M2[0]);
    glBegin(GL_POINTS);
    glVertex3f(x, y, 0);
    glEnd();
    glPopMatrix();
}

或者在客户端应用变换,然后将一大块顶点交给 OpenGL 以一次性渲染。

编辑:或者将那些矩阵乘法完全拉到循环之外:

GLfloat x, y;
GLfloat radius = 0.4f;
GLint pointCount = 180;

glPushMatrix();
glMultMatrixf(& M1[0]);
glBegin(GL_POINTS);
for (GLfloat theta = 0; theta < 2*M_PI; theta += (2*M_PI)/pointCount) 
{
    x = radius * cos(theta);
    y = radius * sin(theta);

    // Draw the point here
    glVertex3f(x, y, 0);
}
glEnd();
glPopMatrix();

glPushMatrix();
glMultMatrixf(& M2[0]);
glBegin(GL_POINTS);
for (GLfloat theta = 0; theta < 2*M_PI; theta += (2*M_PI)/pointCount) 
{
    x = radius * cos(theta);
    y = radius * sin(theta);

    // Draw the point here
    glVertex3f(x, y, 0);
}
glEnd();
glPopMatrix();
于 2013-12-12T20:30:02.077 回答
0

您还可以使用顶点数组来保存所有信息,然后将数据推送到 openGL:

GLFloat[] points = new GLFloat[3*pointCount];

for (GLfloat theta = 0; theta < 2*M_PI; theta += (2*M_PI)/pointCount) 
{
    points[0+off] = radius * cos(theta);
    points[1+off] = radius * sin(theta);
    points[2+off] = 0;
    off+=3;
}

glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, points);

glPushMatrix();
glMultMatrixf(& M1[0]);
glDrawArrays(GL_POINTS, 0, pointCount);
glPopMatrix();

glPushMatrix();
glMultMatrixf(& M2[0]);
glDrawArrays(GL_POINTS, 0, pointCount);
glPopMatrix();

glDisableClientState(GL_VERTEX_ARRAY);
delete[] points;
于 2013-12-13T09:17:26.173 回答