2015-06-15 2 views
1

Я следовал этот учебник http://www.opengl-tutorial.org/beginners-tutorials/tutorial-3-matrices/, чтобы понять, как просмотр работает, но потом, когда я попытался применить это на мое приложение IOS у меня было так много проблемРисование куба в прошивкой с OpenGL и GLKit

так в основном то, что я понял, это что: (?, что является эквивалентом этого в прошивке)

  1. модель первоначально в нуле и поэтому камера
  2. затем мы используем GLM :: LookAt, чтобы переместить камеру в нужном положении
  3. Нанести преобразование проекции, чтобы перейти от пространства камеры до гомогенного единичного куба пространства

Из основного IOS урока я нашел следующий расчет проекционной матрицы

float aspect = fabs(self.view.bounds.size.width/self.view.bounds.size.height); 
GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f); 
_modelViewProjectionMatrix = projectionMatrix; 

, который я действительно не сделал понимаете ... как они придумали, например, 65?

Другой учебник сделал это:

glViewport(0, 0, self.view.bounds.size.width,self.view.bounds.size.height); 

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

Я следующий набор данных

static const GLfloat cubeVertices[] = { 
    -1.0f,-1.0f,-1.0f, // triangle 1 : begin 
    -1.0f,-1.0f, 1.0f, 
    -1.0f, 1.0f, 1.0f, // triangle 1 : end 
    1.0f, 1.0f,-1.0f, // triangle 2 : begin 
    -1.0f,-1.0f,-1.0f, 
    -1.0f, 1.0f,-1.0f, // triangle 2 : end 
    1.0f,-1.0f, 1.0f, 
    -1.0f,-1.0f,-1.0f, 
    1.0f,-1.0f,-1.0f, 
    1.0f, 1.0f,-1.0f, 
    1.0f,-1.0f,-1.0f, 
    -1.0f,-1.0f,-1.0f, 
    -1.0f,-1.0f,-1.0f, 
    -1.0f, 1.0f, 1.0f, 
    -1.0f, 1.0f,-1.0f, 
    1.0f,-1.0f, 1.0f, 
    -1.0f,-1.0f, 1.0f, 
    -1.0f,-1.0f,-1.0f, 
    -1.0f, 1.0f, 1.0f, 
    -1.0f,-1.0f, 1.0f, 
    1.0f,-1.0f, 1.0f, 
    1.0f, 1.0f, 1.0f, 
    1.0f,-1.0f,-1.0f, 
    1.0f, 1.0f,-1.0f, 
    1.0f,-1.0f,-1.0f, 
    1.0f, 1.0f, 1.0f, 
    1.0f,-1.0f, 1.0f, 
    1.0f, 1.0f, 1.0f, 
    1.0f, 1.0f,-1.0f, 
    -1.0f, 1.0f,-1.0f, 
    1.0f, 1.0f, 1.0f, 
    -1.0f, 1.0f,-1.0f, 
    -1.0f, 1.0f, 1.0f, 
    1.0f, 1.0f, 1.0f, 
    -1.0f, 1.0f, 1.0f, 
    1.0f,-1.0f, 1.0f 
}; 

Это моя установка, очень простое из tutori IOS аль

- (void)setupGL { 
    [EAGLContext setCurrentContext:self.context]; 
    [self loadShaders]; 

    glGenBuffers(1, &_vertexBuffer); 
    glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); 
    glBufferData(GL_ARRAY_BUFFER, sizeof(cubeVertices), cubeVertices, GL_STATIC_DRAW); 

    glVertexAttribPointer (GLKVertexAttribPosition, 
          3, 
          GL_FLOAT, GL_FALSE, 
          0, 
          BUFFER_OFFSET(0)); 
    glEnableVertexAttribArray(GLKVertexAttribPosition); 
    //glBindVertexArrayOES(0); 
} 

и мой drawInRect и обновлять методы

- (void)update { 
    //glViewport(0, 0, self.view.bounds.size.width, self.view.bounds.size.height); 
    float aspect = fabs(self.view.bounds.size.width/self.view.bounds.size.height); 
    GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f); 
    _modelViewProjectionMatrix = projectionMatrix; 

} 

- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect { 
    glClearColor(0.65f, 0.65f, 0.65f, 1.0f); 
    glClear(GL_COLOR_BUFFER_BIT); 
    glUseProgram(_program); 
    glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m); 
    glDrawArrays(GL_TRIANGLES, 0, 12*3); 
} 

и моя вершинный шейдер

attribute vec4 position; 
uniform mat4 modelViewProjectionMatrix; 

void main() { 
    gl_Position = modelViewProjectionMatrix * position; 
} 

и мой пиксельный шейдер

void main() { 
    gl_FragColor = vec4 (0.165, 0.427, 0.620, 1.0); 
} 

ответ

4

Чтобы начать с ответом, что лет u ищут и не хватаетGLKMatrix4MakeLookAt. Остальное - только если вы заинтересованы в более глубоком понимании.

Ваше предположение кажется правильным, но я думаю, что вы не понимали, как работает матричная система и openGL. Кажется, вы понимаете, как использовать его. Поэтому, чтобы начать с того, что мы обычно рассматриваем, это 3 матричных компонента, которые затем могут быть вставлены в шейдер в качестве продукта или переданы как каждый компонент в шейдер и умножены на них.

Первый компонент - матрица проекции. Этот компонент отражает экранную проекцию и обычно устанавливается как «орто» или «усеченный». «Орто» - это орфографическая проекция, которая означает, что объект будет иметь тот же размер независимо от расстояния. «Усечка» создаст эффект, который заставит объекты появляться больше или меньше в зависимости от расстояния. В вашем случае вы используете «frustum» с функцией удобства GLKMatrix4MakePerspective.Первый параметр описывает поле обзора и ваш образец, который будет иметь угол 65 градусов, второй - это соотношение сторон, которое должно отражать соотношение экран/вид, а последние два являются плоскостями отсечения. Используя эквивалент с «усеченным» была бы:

GLfloat fieldOfView = M_PI_2; 
    GLfloat near = .1f; 
    GLfloat far = 1000.0f; 
    GLfloat screenRatio = 1.0f/2.0f; 

    GLfloat right = tanf(fieldOfView)*.5f * near; // half of the tagens of field of view 
    GLfloat left = -right; // symetry 
    GLfloat top = right*screenRatio; // scale by screen ratio 
    GLfloat bottom = -top; // symetry 

    GLKMatrix4MakeFrustum(left, right, bottom, top, near, far); 

Второй матрица вида, который, как правило, используется в качестве «камеры». Чтобы использовать это, проще всего вызвать какую-то форму «lookAt», которая в вашем случае равна GLKMatrix4MakeLookAt. Это должно ответить на вопрос «что эквивалентно этому в iOS?».

И 3-я модельная матрица, которая описывает положение объекта в вашей системе координат. Обычно это используется, поэтому вы можете поместить свою модель в нужную позицию, установить определенное вращение и, если необходимо, масштабировать ее.

Итак, как все это происходит, вы в какой-то момент размножаете все матрицы и называете это чем-то вроде матрицы проекции-проекции. Затем эта матрица используется для умножения каждой позиции вершин, чтобы описать ее экранную проекцию.

glViewport не имеет никакого отношения к этому. Эта функция определит, какую часть буфера вы рисуете, и ничего больше. Попытайтесь разделить все значения на половину и посмотреть, что происходит (лучше, чем любое другое объяснение).

Чтобы немного объяснить, что происходит с точки зрения математики, и реализация openGL выглядит следующим образом: OpenGL будет рисовать только фрагменты (пиксели), которые находятся внутри поля [-1, 1] во всех осях. Это означает, что из прогнозов нет магии, чтобы переопределить это, но позиции вершин преобразуются, поэтому правильные значения соответствуют этому.

Для frustum Например, он будет принимать 4 пограничные значения (left, right, top, bottom), near и далеко clipping самолетов. Этот метод определяется так, что любая позиция вершины с Z значением, равным near, будет преобразована в -1, и каждая позиция с Z значением, равным far, будет преобразована в 1. Все промежуточные будут проходить линейную интерполяцию. Что касается X и Y, они будут масштабироваться в зависимости от преобразованного значения Z, так что для Z при 0 будет масштабироваться на 0, Z на near на 1,0, а остальные затем экстраполируются линейно.

lookAt на самом деле очень похож на матрицу модели, но наоборот. Если вы переместите камеру назад, это будет то же самое, что перемещение объекта вперед, если вы повернете влево, объект окажется перемещенным и повернутым вправо и так далее ...

Матрица модели просто преобразует все позиции вершин используя базовые векторы и перевод. Соответствующими частями этой матрицы являются верхняя часть 3x3, которые являются базовыми векторами и нижней (или правой частью некоторой реализации) вектором 3x1 (1x3), который является переводом. Самый простой способ представить, что это система координат, определенная внутри системы координат: нулевое значение (начало координат) находится в части перевода матрицы, ось X - это первая строка (столбец) матрицы 3x3, Y вторая и Z - третий. Длина этих 3 векторов представляет собой шкалу уважаемых координат ... Все это сочетается.

+0

Очень полезное объяснение, чем вы так много! он соединял точки для меня, поскольку я читал фрагменты отсюда и там, не имея возможности подключить их. – nevermind

+0

Да, эти системы могут быть очень неприятными, поскольку некоторые из них очень трудно понять. Вы можете найти сотни примеров, а не 2 из них, которые кажутся одинаковыми. Я рад, что мое объяснение помогло вам, но это довольно много, чтобы принять участие в не-эксперте в этой области.Я рад, что это помогло вам. –

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