Почему моя программа OpenGL ES 2.0 только рисует линию вместо набора линий? (GLKit или OpenGL) - PullRequest
3 голосов
/ 09 декабря 2011

Хорошо, я проверял снова и снова, и до сих пор я «думаю», что я понимаю, как рисует opengl и как указать, что я хочу рисовать, однако я просто не могу заставить его рисовать больше 1 линии.

Используя шаблон из Xcode 4.2, я могу получить следующий код. Он рисует мой квадратный скелет с помощью GLKIT, потому что я просто игнорирую метод opengl es 2.0, чтобы не использовать шейдеры atm, но когда я касаюсь экрана, он должен нарисовать мой собственный массив, которого нет ....

Итак, сначала квадратный формат (просто чтобы показать тип переменной, которую они используют в шаблоне)

GLfloat gCubeVertexData[216] = 
{
    // Data layout for each line below is:
    // positionX, positionY, positionZ,     normalX, normalY, normalZ,
    0.5f, -0.5f, -0.5f,        1.0f, 0.0f, 0.0f,
    0.5f, 0.5f, -0.5f,         1.0f, 0.0f, 0.0f,
    0.5f, -0.5f, 0.5f,         1.0f, 0.0f, 0.0f,
    0.5f, -0.5f, 0.5f,         1.0f, 0.0f, 0.0f,
    0.5f, 0.5f, 0.5f,          1.0f, 0.0f, 0.0f,
    0.5f, 0.5f, -0.5f,         1.0f, 0.0f, 0.0f,

    0.5f, 0.5f, -0.5f,         0.0f, 1.0f, 0.0f,
    -0.5f, 0.5f, -0.5f,        0.0f, 1.0f, 0.0f,
    0.5f, 0.5f, 0.5f,          0.0f, 1.0f, 0.0f,
    0.5f, 0.5f, 0.5f,          0.0f, 1.0f, 0.0f,
    -0.5f, 0.5f, -0.5f,        0.0f, 1.0f, 0.0f,
    -0.5f, 0.5f, 0.5f,         0.0f, 1.0f, 0.0f,

    -0.5f, 0.5f, -0.5f,        -1.0f, 0.0f, 0.0f,
    -0.5f, -0.5f, -0.5f,       -1.0f, 0.0f, 0.0f,
    -0.5f, 0.5f, 0.5f,         -1.0f, 0.0f, 0.0f,
    -0.5f, 0.5f, 0.5f,         -1.0f, 0.0f, 0.0f,
    -0.5f, -0.5f, -0.5f,       -1.0f, 0.0f, 0.0f,
    -0.5f, -0.5f, 0.5f,        -1.0f, 0.0f, 0.0f,

    -0.5f, -0.5f, -0.5f,       0.0f, -1.0f, 0.0f,
    0.5f, -0.5f, -0.5f,        0.0f, -1.0f, 0.0f,
    -0.5f, -0.5f, 0.5f,        0.0f, -1.0f, 0.0f,
    -0.5f, -0.5f, 0.5f,        0.0f, -1.0f, 0.0f,
    0.5f, -0.5f, -0.5f,        0.0f, -1.0f, 0.0f,
    0.5f, -0.5f, 0.5f,         0.0f, -1.0f, 0.0f,

    0.5f, 0.5f, 0.5f,          0.0f, 0.0f, 1.0f,
    -0.5f, 0.5f, 0.5f,         0.0f, 0.0f, 1.0f,
    0.5f, -0.5f, 0.5f,         0.0f, 0.0f, 1.0f,
    0.5f, -0.5f, 0.5f,         0.0f, 0.0f, 1.0f,
    -0.5f, 0.5f, 0.5f,         0.0f, 0.0f, 1.0f,
    -0.5f, -0.5f, 0.5f,        0.0f, 0.0f, 1.0f,

    0.5f, -0.5f, -0.5f,        0.0f, 0.0f, -1.0f,
    -0.5f, -0.5f, -0.5f,       0.0f, 0.0f, -.0f,
    0.5f, 0.5f, -0.5f,         0.0f, 0.0f, -1.0f,
    0.5f, 0.5f, -0.5f,         0.0f, 0.0f, -1.0f,
    -0.5f, -0.5f, -0.5f,       0.0f, 0.0f, -1.0f,
    -0.5f, 0.5f, -0.5f,        0.0f, 0.0f, -1.0f
};

Вот мой SetupGL, который я вызываю один раз в функции «Просмотр загрузки».

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

    [self loadShaders];

    self.effect = [[GLKBaseEffect alloc] init];
    self.effect.light0.enabled = GL_TRUE; //No Idea why it wont work without this


    glGenVertexArraysOES(1, &_vertexArray);
    glBindVertexArrayOES(_vertexArray);

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

    glEnableVertexAttribArray(GLKVertexAttribPosition);
    glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0));

    glBindVertexArrayOES(0);
}

Это метод обновления (который просто вращает вещи)

- (void)update
{
    float aspect = fabsf(self.view.bounds.size.width / self.view.bounds.size.height);
    GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 10000.0f);

    self.effect.transform.projectionMatrix = projectionMatrix;

    GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -10.0f);
    baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f);

    // Compute the model view matrix for the object rendered with GLKit
    GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -1.5f);
    modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f);
    modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix);

    self.effect.transform.modelviewMatrix = modelViewMatrix;

    _rotation += self.timeSinceLastUpdate * 0.5f;
}

Метод Draw In Rect (Я думаю, что Render)

- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
{
    glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glBindVertexArrayOES(_vertexArray);

    // Render the object with GLKit
    [self.effect prepareToDraw];

    glDrawArrays(GL_LINE_STRIP, 0, 36); //Probably have to change the 36

}

Это сенсорная часть:

При касаниях я просто создаю NSMutableData

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 
{
    UITouch *touch = [touches anyObject];
    startPoint = [touch locationInView:self.view];

    vertexData3 = [NSMutableData dataWithLength: sizeof(GLKVector2)]; //HERE

    if (!referenceAttitude)
        referenceAttitude = motionManager.deviceMotion.attitude;

    writtingON = YES;   

}

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

ОДНАКО для проверки чертежа я просто создаю временную переменную NSMUtableData с некоторыми значениями, которые я добавил вручную (добавление ужасно). Я использую NSMutableData, потому что это то, что они предложили в другом учебнике. Я на 90% уверен, что данные сохраняются правильно, потому что когда я их получаю, они там. (http://games.ianterrell.com/how-to-draw-2d-shapes-with-glkit/)

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event 
{


    ////////Test array


    tempVert = GLKVector2Make(10, -8);
    NSRange r = {0*sizeof(GLKVector2), sizeof(GLKVector2)};
    [vertexData3 replaceBytesInRange: r withBytes:&tempVert];
    [vertexData3 increaseLengthBy:sizeof(GLKVector2)];

    tempVert = GLKVector2Make(2, -8);
    NSRange q = {1*sizeof(GLKVector2), sizeof(GLKVector2)};
    [vertexData3 replaceBytesInRange: q withBytes:&tempVert];
    [vertexData3 increaseLengthBy:sizeof(GLKVector2)];

    tempVert = GLKVector2Make(4, 9);
    NSRange w = {2*sizeof(GLKVector2), sizeof(GLKVector2)};
    [vertexData3 replaceBytesInRange: w withBytes:&tempVert];
    [vertexData3 increaseLengthBy:sizeof(GLKVector2)];

    tempVert = GLKVector2Make(1, -9);
    NSRange e = {3*sizeof(GLKVector2), sizeof(GLKVector2)};
    [vertexData3 replaceBytesInRange: e withBytes:&tempVert];
    [vertexData3 increaseLengthBy:sizeof(GLKVector2)];

    tempVert = GLKVector2Make(2, -2);
    NSRange t = {4*sizeof(GLKVector2), sizeof(GLKVector2)};
    [vertexData3 replaceBytesInRange: t withBytes:&tempVert];
    [vertexData3 increaseLengthBy:sizeof(GLKVector2)];


    //////////////////////

    glGenVertexArraysOES(1, &_vertexArray);
    glBindVertexArrayOES(_vertexArray);

    glGenBuffers(1, &_vertexBuffer);
    glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);

    glBufferData(GL_ARRAY_BUFFER, sizeof(vertexData3), [vertexData3 mutableBytes], GL_DYNAMIC_DRAW);

    glEnableVertexAttribArray(GLKVertexAttribPosition);
    glVertexAttribPointer(GLKVertexAttribPosition, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));

    glBindVertexArrayOES(0);

}

Эта последняя часть сводит меня с ума !!! Я думаю, что это должно сделать, изменить буфер с моим собственным массивом так, чтобы автообновление отображало его.

Любые предложения будут по достоинству оценены.

Спасибо

Да, и если кто-нибудь знает, как настроить ортогональную матрицу, потому что я действительно заинтересован только в 2d atm компонентов, так что я не могу заменить его для этой матрицы перспективы.

EDIT:

Хорошо, я только что попытался отправить случайный массив GLfloats, и он действительно меняет форму, но почему бы не с моим массивом NSMutableData? я думал, что делаю ту же процедуру, что и в учебнике ....

1 Ответ

0 голосов
/ 20 января 2012

последняя часть должна быть только:

glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertexData3), [vertexData3 mutableBytes], GL_DYNAMIC_DRAW);
// bind buffer and specify it's new data (no need to glGenBuffers(), that was done in setupGL())
// also, it would be handy to save number of vertices so it could be used later for drawing (nVertices = sizeof(vertexData3) / sizeof(GLKVector2))

glBindVertexArrayOES(_vertexArray);
glEnableVertexAttribArray(GLKVertexAttribPosition);
glVertexAttribPointer(GLKVertexAttribPosition, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
glBindVertexArrayOES(0);
// bind vertex array and setup the vertex attribute (although this could be done only once, in setupGL())

Таким образом, вы не генерируете так много объектов OpenGL, и рендеринг должен быть более быстрым (также не будет исчерпан объем памяти).

В противном случае рендеринг выглядит нормально. Но вы действительно должны использовать реальное количество вершин для рисования:

glDrawArrays(GL_LINE_STRIP, 0, nVertices);

Почти наверняка есть проблемы с масштабом (не должно быть различий между GLfloats и GLKVector2). Вы генерируете некоторые точки с помощью вашего метода, но затем рисуете только первые 36. Возможно, что существует кривая, сгенерированная корреляцией, но вы видите только короткий фрагмент ее начала, который, естественно, кажется плоским. Кроме того, вы, кажется, не уверены, что ваши расчеты положения генерируют координаты внутри окна, возможно, было бы неплохо а) опубликовать здесь свой источник б) умножить свои координаты на несколько небольших (но выше нуля) значений для чтобы они помещались на экране.

Что касается орто, вы можете использовать:

GLKMatrix4MakeOrtho(-1, 1, -1, 1, .1, 1000); // this sets normalized coordinates
GLKMatrix4MakeOrtho(0, widthPx, 0, heightPx, .1, 1000); // this sets pixel coordinates

Параметрами GLKMatrix4MakeOrtho являются только желаемые координаты по углам экрана (слева, справа, снизу, сверху) и диапазон глубины, на котором рисуется (близко, далеко).

Надеюсь, это даст вам хоть какое-то понимание ...

...