У меня такое чувство, что вы страдаете от неправильного представления о том, как работает OpenGL. Вы написали «Platform.cpp создает объект примерно так:» и во фрагменте кода, прежде чем я вижу, вы создаете экземпляр некоторого класса Plattform, окруженного операциями стека матрицы OpenGL. Я подозреваю, что вы предполагали, что OpenGL каким-то образом "сохранит" этот "объект". Это не так, как работает OpenGL Вы думаете с точки зрения графа сцены. OpenGL - это не граф сцены.
OpenGL - это API рисования. Звонки
glBegin(GL_QUADS);
glTexCoord2f(0.0, 0.0); glVertex2f(x1,y1);
glTexCoord2f(0.0, 1.0); glVertex2f(x2,y2);
glTexCoord2f(1.0, 1.0); glVertex2f(x3,y3);
glTexCoord2f(1.0, 0.0); glVertex2f(x4,y4);
glEnd();
нарисуйте квад на экране. Опять же: они рисуют . После того, как эти команды были введены, они исчезли и были забыты OpenGL. Матрицы преобразования OpenGL используются для преобразования входных данных команд рисования. Но опять же нет никакой настойчивости. Команды рисования должны быть выполнены для каждого нарисованного кадра. Сначала я подумал, что смогу переписать часть вашего кода, но его нужно переписать, если можно так выразиться.
Типичная программа OpenGL выглядит следующим образом (я свободно опускаю все определения классов и типов и ожидаю некоторого здравого смысла при интерпретации имен переменных, членов и методов).
/* draw_scene is called on every iteration of the program main loop or
the drawing callback handler to update the screen */
void Scene::draw_scene(ScreenInfo si)
{
glViewport(si.viewport.x, si.viewport.y, si.viewport.width, si.viewport.height);
glClearColor(this->clear.r, this->clear.g, this->clear.b, this->clear.a);
glClearDepth(this->clear.d);
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glDepthMask(GL_TRUE);
glClear( (this->clear.color ? GL_COLOR_BUFFER_BIT) |
(this->clear.depth ? GL_DEPTH_BUFFER_BTT) );
std::list<SceneObjects*> objects_by_distance =
sort_objects_by_direction(scene->objects,
scene->active_camera->position
scene->active_camera->direction);
SceneObjects *closest_object = objects_by_distance.front();
SceneObjects *farthest_object = objects_by_distance.back();
float near_clip = max(NEAR_CLIP_LIMIT,
length(closest_object->position - scene->active_camera->position)
- closest_object->bounding_sphere.radius );
float far_clip = min(FAR_CLIP_LIMIT,
length(farthest_object->position - scene->active_camera->position)
+ farthest_object->bounding_sphere.radius );
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
switch( scene->projection.type ) {
case Projection::perspective: {
gluPerspective( scene->projection.fov,
(float)si.viewport.width/(float)si.viewport.height,
near_clip, far_clip);
} break;
case Projection::orthographic: {
float aspect = (float)si.viewport.width/(float)si.viewport.height;
glOrtho( -0.5 * scene->projection.size * aspect, 0.5 * scene->projection.size * aspect
-0.5 * scene->projection.size 0.5 * scene->projection.size );
} break;
}
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
/* I normally disregard using gluLookAt, but in this case I use it
to show as much as possible! */
gluLookAt( scene->active_camera->position.x, scene->active_camera->position.y, scene->active_camera->position.z,
scene->active_camera->position.x + scene->active_camera->direction.x,
scene->active_camera->position.y + scene->active_camera->direction.y,
scene->active_camera->position.z + scene->active_camera->direction.z,
scene->active_camera->up.x, scene->active_camera->up.y, scene->active_camera->up.z );
for_each(scene->objects.begin(), scene->objects.end(), draw_object)
}
void draw_object(SceneObject *object)
{
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glTranslatef(object->position.x, object->position.y, object->position.z);
glRotatef(object->rotation.axis.angle, object->rotation.axis.x, object->rotation.axis.y, object->rotation.axis.z);
GLfloat *(vertex_ptr[3][3]) = object->mesh->vertices;
GLuint *vertex_indices = object->mesh->face_vertex_indices;
#ifdef USE_IMMEDIATE_MODE
glBegin(GL_TRIANGLES);
for(int i = 0; i < object->mesh->face_count; i++) {
glNormalfv(&vertex_ptr[vertex_indices[i]][0]);
glTexCoord3fv(&vertex_ptr[vertex_indices[i]][1]);
glVertex3fv(&vertex_ptr[vertex_indices[i]][2]);
glNormalfv(&vertex_ptr[vertex_indices[i+1]][0]);
glTexCoord3fv(&vertex_ptr[vertex_indices[i+1]][1]);
glVertex3fv(&vertex_ptr[vertex_indices[i+1]][2]);
glNormalfv(&vertex_ptr[vertex_indices[i+2]][0]);
glTexCoord3fv(&vertex_ptr[vertex_indices[i+2]][1]);
glVertex3fv(&vertex_ptr[vertex_indices[i+2]][2]);
}
glEnd();
#else
glEnableClientState(GL_NORMAL_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnableClientState(GL_VERTEX_ARRAY);
/* This is direct vertex array mode.
A more modern approach is using Vertex Buffer Objects, which reused this
API, but adds further function calls. */
glNormalPointer(GL_FLOAT, 3*3*sizeof(GLfloat), &vertex_ptr[0][0]);
glTexCoordPointer(3, GL_FLOAT, 3*3*sizeof(GLfloat), &vertex_ptr[0][1]);
glVertexPointer(3, GL_FLOAT, 3*3*sizeof(GLfloat), &vertex_ptr[0][2]);
glDrawElements(GL_TRIANGLES, object->mesh->face_count*3, GL_UNSIGNED_INT, vertex_indices);
#endif
glPopMatrix();
}
Это самый простой способ серьезно использовать OpenGL. Я написал это подробно, чтобы дать вам представление о том, как его использовать и как оно работает.