Рекламный щит в LWJGL

Я пытался сделать рекламный щит с помощью LWJGL, и мне это частично удалось. Квадроцикл появляется и смотрит в камеру, когда я стрейфую. Однако, как только я поворачиваю камеру по любой из осей, квадроцикл также перемещается по осям по-разному. Вот код, который я использую:

/***************************************************************************************************************************************************************************************************
 * All rendering happens here...
 **************************************************************************************************************************************************************************************************/
private void render() {

    GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT); // Clear The Screen And The Depth Buffer
    GL11.glLoadIdentity(); // Reset The View

    //GL11.glLight(GL11.GL_LIGHT1, GL11.GL_POSITION, lightPosition); // Position The Light

    GL11.glRotatef(360.0f - yrot, 0, 1.0f, 0);
    GL11.glRotatef(lookupdown, 1.0f, 0, 0);

    GL11.glTranslatef(-xpos, 0, -zpos);


    GL11.glCallList(blocksList);
    GL11.glCallList(tilesList);
    GL11.glCallList(roofList);

    /* Render billboards */
    Billboard bb = lvLoader.currentLevel.billboards[0];
    GL11.glPushMatrix();
    GL11.glRotatef(360.0f - yrot, 0, -1.0f, 0);
    GL11.glRotatef(lookupdown, -1.0f, 0, 0);
    GL11.glBegin(GL11.GL_QUADS);
    GL11.glVertex3f(bb.origin.x + 0.5f, bb.origin.y + 0.5f, bb.origin.z);
    GL11.glVertex3f(bb.origin.x - 0.5f, bb.origin.y + 0.5f, bb.origin.z);
    GL11.glVertex3f(bb.origin.x - 0.5f, bb.origin.y - 0.5f, bb.origin.z);
    GL11.glVertex3f(bb.origin.x + 0.5f, bb.origin.y - 0.5f, bb.origin.z);
    GL11.glEnd();
    GL11.glPopMatrix();

Вот функции, управляющие lookupdown и yrot.

if (Keyboard.isKeyDown(Keyboard.KEY_UP)) { // Is PageUp Being Pressed?
        lookupdown -= 1.0f; // Rotate The Secene Downwards
    }

    if (Keyboard.isKeyDown(Keyboard.KEY_DOWN)) { // Is PageDown Being Pressed?
        lookupdown += 1.0f; // Rotate The Scene Upwards
    }

    if (Keyboard.isKeyDown(Keyboard.KEY_RIGHT))
    {
        yrot -= 1.5f; // Rotate The Scene To The Left
    }

    if (Keyboard.isKeyDown(Keyboard.KEY_LEFT))
    {
        yrot += 1.5f; // Rotate The Scene To The Left
    }

    if (Keyboard.isKeyDown(Keyboard.KEY_W))
    {
        adjustXZ((float) Math.sin(yrot * piover180) * 0.05f, (float) Math.cos(yrot * piover180) * 0.05f, false, false);
    }

    if (Keyboard.isKeyDown(Keyboard.KEY_S))
    {
        adjustXZ((float) Math.sin(yrot * piover180) * 0.05f, (float) Math.cos(yrot * piover180) * 0.05f, true, true);
    }

    if (Keyboard.isKeyDown(Keyboard.KEY_D))
    {
        adjustXZ((float) Math.sin((yrot-90) * piover180) * 0.05f, (float) Math.cos((yrot-90) * piover180) * 0.05f, false, false);
    }

    if (Keyboard.isKeyDown(Keyboard.KEY_A))
    {
        adjustXZ((float) Math.sin((yrot+90) * piover180) * 0.05f, (float) Math.cos((yrot+90) * piover180) * 0.05f, false, false);
    }

private void adjustXZ(float x, float z, boolean xAdd, boolean zAdd)
{
    if (collisionCheck(x, z, xAdd, zAdd))
        return;

    if (xAdd)
        xpos += x;
    else if (!xAdd)
        xpos -= x;

    if (zAdd)
        zpos += z;
    else if (!zAdd)
        zpos -= z;
}

person Myzreal    schedule 23.11.2011    source источник
comment
Не могли бы вы немного пояснить, где вы берете yrot и lookupdown? Похоже, что это могут быть значения для камеры, но трудно быть уверенным без дополнительной информации.   -  person vaughandroid    schedule 23.11.2011
comment
Да, они управляют камерой. Добавил их в основной пост.   -  person Myzreal    schedule 23.11.2011


Ответы (1)


Я не знаком с LWJGL, поэтому я не уверен на 100%, что он ожидает, но, исходя из моего опыта работы с другими 3D API, похоже, что у вас есть матричные преобразования в неправильном порядке.

Попробуйте изменить код следующим образом:

GL11.glPushMatrix();
GL11.glTranslatef(bb.origin.x, bb.origin.y, bb.origin.z); // Translation here
GL11.glRotatef(360.0f - yrot, 0, -1.0f, 0);
GL11.glRotatef(lookupdown, -1.0f, 0, 0);
GL11.glBegin(GL11.GL_QUADS);
GL11.glVertex3f(0.5f, 0.5f, 0); // No translation here anymore
GL11.glVertex3f(0.5f, 0.5f, 0;
GL11.glVertex3f(0.5f, 0.5f, 0);
GL11.glVertex3f(0.5f, 0.5f, 0);
GL11.glEnd();

Отдельно стоит отметить, что вы не используете обычную технику рекламного щита. Вместо того, чтобы рекламные щиты всегда были обращены к камере, они всегда должны быть перпендикулярны камере. Это будет заметно для объектов рекламного щита рядом с краями пирамиды обзора. Тем не менее, я оставлю это на ваше усмотрение!

person vaughandroid    schedule 24.11.2011
comment
Спасибо, это решило проблему. Мне действительно нужно лучше понять, как работают переводы и повороты в openGL. Может быть у вас есть статьи на эту тему? Перпендикулярных билбордов, я думаю, будет достаточно для моего небольшого проекта, но я буду исследовать этот вопрос дальше. Спасибо за ваше время! - person Myzreal; 24.11.2011
comment
Извините, не уверен, что смогу помочь с поиском статей/руководств. Давненько я не работал напрямую с OpenGL, так как я больше программист геймплея, чем программист графики. Тем не менее, есть много всего, просто погуглите, и рано или поздно вы наткнетесь на сайт или два с достойными учебными пособиями, которые соответствуют вашему стилю обучения и уровню опыта ... Удачи! - person vaughandroid; 24.11.2011