2016-07-12 9 views
0

Игра представляет собой нисходящую двумерную космическую корабль - подумайте о «Астероидах».Вращающаяся 2D-камера для заголовка космического корабля в OpenGL (OpenTK)

Box2Dx - это физический движок, и я расширил включенный DebugDraw на основе OpenTK, чтобы нарисовать дополнительные игровые объекты. Перемещение камеры таким образом, чтобы она всегда была сосредоточена на корабле игрока, а масштабирование и работа отлично работали. Тем не менее, мне действительно нужна камера, чтобы вращаться вместе с кораблем, поэтому она всегда обращена в одном направлении. То есть, корабль будет заморожен в центре экрана, а остальная часть игрового мира вращается вокруг него, когда он поворачивается.

Я пробовал адаптировать образцы кода, но ничего не работает. Лучшее, что я смог достичь, - это перекос и обрезание.

Рендер цикл:

 // Clear. 
     Gl.glClear(Gl.GL_COLOR_BUFFER_BIT | Gl.GL_DEPTH_BUFFER_BIT); 

     // other rendering omitted (planets, ships, etc.) 

     this.OpenGlControl.Draw(); 

вид Update - центры на корабле и должны вращаться, чтобы соответствовать его угол. На данный момент, я просто пытаюсь повернуть его на произвольный угол для доказательства концепции, но не кости:

public void RefreshView() 
    { 
     int width = this.OpenGlControl.Width; 
     int height = this.OpenGlControl.Height; 

     Gl.glViewport(0, 0, width, height); 

     Gl.glMatrixMode(Gl.GL_PROJECTION); 
     Gl.glLoadIdentity(); 

     float ratio = (float)width/(float)height; 

     Vec2 extents = new Vec2(ratio * 25.0f, 25.0f); 
     extents *= viewZoom; 

     // rotate the view 
     var shipAngle = 180.0f; // just a test angle for proof of concept 
     Gl.glRotatef(shipAngle, 0, 0, 0); 

     Vec2 lower = this.viewCenter - extents; 
     Vec2 upper = this.viewCenter + extents; 

     // L/R/B/T 
     Glu.gluOrtho2D(lower.X, upper.X, lower.Y, upper.Y); 

     Gl.glMatrixMode(Gl.GL_MODELVIEW); 
    } 

Теперь, я не уверен, очевидно, делает это неправильно. Степени в 0 и 180 будут поддерживать его правую сторону или переворачивать, но любая другая степень будет фактически увеличивать/уменьшать или вызывать только черноту, ничего не отображаться. Ниже приведены примеры:

Если угол корабль 0.0f, то игровой мир, как и ожидалось: enter image description here

Степень 180.0f переворачивает его вертикально ... кажется многообещающим: enter image description here

Степень 45 масштабируется и не вращается вообще ... это нечетно: enter image description here

Степень 90 возвращает все черное. Если вы никогда не видели черный цвет: enter image description here

Пожалуйста, помогите!

+1

https: //www.opengl.org/sdk/docs/man2/xhtml/glRotate.xml, похоже, указывает, что аргументы 2-4 'glRotatef' - это вектор, который вы вращаете. Когда вы введете '0, 0, 0', я бы предположил, что ваше поведение не определено. Вы попробовали «0, 0, 1' вместо этого? (при условии, что глубина находится в оси z) – pingul

+0

Вы применяете поворот к стеклу матрицы проекции. Кроме того, больше не следует использовать устаревшую конвейерную функцию. Если нет веских оснований для его использования, придерживайтесь профиля Core. – BDL

ответ

0

Во-первых, аргументы 2-4 являются осью, поэтому, пожалуйста, укажите их правильно, как указано в @pingul.

Важнее, что вращение применяется к матрице проекции.

// L/R/B/T 
    Glu.gluOrtho2D(lower.X, upper.X, lower.Y, upper.Y); 

В этой строке вашей матрица проекции ортогонального 2D в настоящее время умножается с предыдущим вращением и применена к проекционной матрице. Я считаю, что это не то, что вы хотите.

Решения будет переместить вызов вращения на место после того, как выбран режим матрицы вида модели, как показано ниже

// L/R/B/T 
    Glu.gluOrtho2D(lower.X, upper.X, lower.Y, upper.Y); 

    Gl.glMatrixMode(Gl.GL_MODELVIEW); 

    // rotate the view 
    var shipAngle = 180.0f; // just a test angle for proof of concept 
    Gl.glRotatef(shipAngle, 0.0f, 0.0f, 1.0f); 

И теперь ваши повороты будут применены к модели вид матрицы стеке. (Я считаю, что это тот эффект, который вы хотите). Имейте в виду, что glRotatef() создает матрицу вращения и умножает ее на матрицу в верхней части выбранного стека стека.

Я также настоятельно рекомендую вам, если это возможно, перейти от стационарного конвейера, как это было предложено в @BDL.

Смежные вопросы