Как освободить память, выделенную в обратном вызове GLU_TESS_COMBINE

Я использую GLUtesselator для заполнения некоторых невыпуклых многоугольников.

Это работало довольно хорошо, но с некоторыми полигонами это жаловался что ему нужна функция объединения, поэтому я предоставил очень простой обратный вызов GLU_TESS_COMBINE, который выделяет новую вершину и просто копирует координаты (это 2D со сплошными цветами, поэтому мне не нужно интерполировать значения RGB или что-либо еще):

void CALLBACK tessCombine( GLdouble coords[3], GLdouble * vertex_data[4], GLfloat weight[4], GLdouble **outData )
{
GLdouble *vertex = new GLdouble[3];
vertex[0] = coords[0];
vertex[1] = coords[1];
vertex[2] = coords[2];
*outData = vertex;
}

Теперь все отображается так, как ожидалось, но, очевидно, утечка памяти. Документы говорят:

Выделите другую вершину, […] освободите память через некоторое время после
вызывая gluTessEndPolygon.

Но во всех примерах, которые я нашел, они не показывают, как обращаться с памятью. Обратные вызовы являются свободными функциями, и нет никакого способа освободить выделенную там память, не так ли?

Единственный способ, которым я могу придумать, — это сохранить их где-нибудь, а затем удалить их самостоятельно. Это правильный путь?

1

Решение

Заглянуть в это руководство по тесселяции OpenGL.

Дело не в том, чтобы выделять какую-либо память в обратном вызове (иначе вы получите утечку памяти). Вместо этого вы должны скопировать данные вершин в ячейку памяти в обратном вызове (как это делается в пример). Откуда вы копируете данные вершин, это зависит от вас.

Так выглядит функция обратного вызова в их пример :

void CALLBACK tessCombineCB(const GLdouble newVertex[3], const GLdouble *neighborVertex[4],
const GLfloat neighborWeight[4], GLdouble **outData)
{
// copy new intersect vertex to local array
// Because newVertex is temporal and cannot be hold by tessellator until next
// vertex callback called, it must be copied to the safe place in the app.
// Once gluTessEndPolygon() called, then you can safly deallocate the array.
vertices[vertexIndex][0] = newVertex[0];
vertices[vertexIndex][1] = newVertex[1];
vertices[vertexIndex][2] = newVertex[2];

// compute vertex color with given weights and colors of 4 neighbors
// the neighborVertex[4] must hold required info, in this case, color.
// neighborVertex was actually the third param of gluTessVertex() and is
// passed into here to compute the color of the intersect vertex.
vertices[vertexIndex][3] = neighborWeight[0] * neighborVertex[0][3] +   // red
neighborWeight[1] * neighborVertex[1][3] +
neighborWeight[2] * neighborVertex[2][3] +
neighborWeight[3] * neighborVertex[3][3];
vertices[vertexIndex][4] = neighborWeight[0] * neighborVertex[0][4] +   // green
neighborWeight[1] * neighborVertex[1][4] +
neighborWeight[2] * neighborVertex[2][4] +
neighborWeight[3] * neighborVertex[3][4];
vertices[vertexIndex][5] = neighborWeight[0] * neighborVertex[0][5] +   // blue
neighborWeight[1] * neighborVertex[1][5] +
neighborWeight[2] * neighborVertex[2][5] +
neighborWeight[3] * neighborVertex[3][5];// return output data (vertex coords and others)
*outData = vertices[vertexIndex];   // assign the address of new intersect vertex

++vertexIndex;  // increase index for next vertex
}
3

Другие решения

Других решений пока нет …