glMultMatrix не работает внутри glBegin()

Я создаю программу, которая позволяет мне строить точки в 3-х местах, соединять их с помощью сплайна Кэтмулла-Рома, а затем рисовать цилиндр вокруг сплайна. я использую GL_TRIANGLES_STRIP соединять круги точек, нарисованные вокруг Сплайна, через короткие промежутки времени, надеюсь, соединить их все вместе в Цилиндр вокруг Сплайна.

Мне удалось нарисовать полные круги точек на этих интервалах, используя GL_POINTS и правильно ориентируйте их по линии относительно рамки Френе. К сожалению, использовать GL_TRIANGLE_STRIP Я считаю, что мне нужно построить точки по одному между набором из двух кругов точек.

У меня проблема в том, что glMultMatrix кажется, не работает, когда внутри glBegin, Код ниже нарисует круг точек, но в начале координат и 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();

2 ответа

Решение

У меня проблема в том, что 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();

Вы также можете использовать массив вершин для хранения всей информации, а затем отправить данные в 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;
Другие вопросы по тегам