如何释放GLUT_TESS_COMBINE回调中分配的内存

How to free memory allocated in GLU_TESS_COMBINE callback

本文关键字:回调 COMBINE 分配 内存 TESS 释放 GLUT 何释放      更新时间:2023-10-16

我正在使用GLUEtesselator来填充一些非凸多边形。

它工作得很好,但对于一些多边形,它抱怨它需要一个组合函数,所以我提供了一个非常简单的GLUTESS_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。

但在我发现的所有例子中,它们都没有说明如何处理记忆。回调是自由函数,没有办法释放分配在那里的内存,是吗?

我唯一能想到的方法就是把它们存储在某个地方,然后自己删除。这是正确的方法吗?

看看这个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
}