我中有你從OpenGL的工作原理的誤解遭受的感覺。你寫了「Platform.cpp創建對象,就像這樣:」,然後在代碼片段中看到你正在創建一些被OpenGL矩陣堆棧操作包圍的Plattform類的實例。我懷疑你認爲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的最基本的方法。我詳細地寫了這篇文章,告訴你如何使用它以及它是如何工作的。