Положение движущегося 2D объекта openGL - PullRequest
1 голос
/ 10 марта 2011

У меня есть объект, движущийся вперед и назад по оси x, однако я не могу расположить его дальше прямо вдоль оси x.

это мой код, как мне это сделать?

float moveRad = 0.0;
        moveRad = moveBee * (PI/180.0);     
        moveBee += 0.1;

        glPushMatrix();
            glTranslatef(50.0 * sinf(moveRad), -100,0);
            e[0] = new Platform(0, 0, 0, 40, 33, 40, 33, 00, textures[23], (50.0 * sinf(moveRad)), -100);
        glPopMatrix();

Platform.cpp создает объект примерно так:

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();

Ответы [ 4 ]

3 голосов
/ 11 марта 2011

У меня такое чувство, что вы страдаете от неправильного представления о том, как работает 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. Я написал это подробно, чтобы дать вам представление о том, как его использовать и как оно работает.

0 голосов
/ 10 марта 2011

У меня такое чувство, что вы не знаете точно, что делает ваш код (поправьте меня, если я ошибаюсь).Если вы хотите переместить его вправо, просто добавьте сюда число.

glTranslatef (50.0 * sinf (moveRad) + 30 , -100,0);

Я обновлю свой ответ, если потребуется.

0 голосов
/ 10 марта 2011

Я думаю, что ваша проблема - '50 .0 * sinf (moveRad)' - она ​​будет колебаться между -50 и 50. Попробуйте добавить значение вместо или как его умножение.

0 голосов
/ 10 марта 2011

Почему бы вам не настроить масштабирование оси X в вашем вызове на glTranslatef?

glTranslatef(amplitude * sinf(moveRad), -100,0);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...