Это звучит как идеальная ситуация для списков отображения OpenGL. То, как вы их используете, - это сначала запросить у OpenGL идентификатор отображаемого списка:
GLuint draw_id = glGenLists(1);
(Вы можете запросить несколько последовательных идентификаторов одновременно, но в этом случае мы запрашиваем только 1)
Затем в первый раз во время процедуры рисования вызовите glNewList:
glNewList(draw_id, GL_COMPILE);
<do compute intensive drawing here>
glEndList();
Обратите внимание, что на самом деле это не будет отображать вашу форму (вы можете использовать GL_COMPILE_AND_EXECUTE в glNewList, который будет отображать вашу форму, но это обычно не рекомендуется)
Теперь, когда вам нужно нарисовать ваш объект:
< set up your OpenGL matrices >
glCallList(draw_id);
И, наконец, когда вы закончите с этим, вы можете использовать glDeleteLists.
Отображение списков на самом деле может ускорить рендеринг, поскольку можно выполнить некоторые оптимизации и удалить все накладные расходы на вызовы функций.
Технически, списки отображения OpenGL устарели (но не удалены!) В OpenGL 3.0 и выше (вместе с glTranslate, glVertex glBegin ... grrr), но они все еще должны работать в обозримом будущем. Чтобы быть надежным в будущем, вы должны использовать массивы вершин, но это немного сложнее.