2013-04-10 4 views
2

Я пытаюсь изучить OpenGL на iOS. Я следую этому руководству.glDrawElements ничего не показывает

http://www.raywenderlich.com/5235/beginning-opengl-es-2-0-with-glkit-part-2

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

https://gist.github.com/seanhess/5356598

я вижу цвет фона меняется, так что OpenGL работает вообще. Просто вызов glDrawElements, похоже, ничего не делает.

glDrawElements(GL_TRIANGLES, sizeof(Indices)/sizeof(Indices[0]), GL_UNSIGNED_BYTE, 0); 

У него есть демо-код, но это не то же самое, как код он должен писать в учебнике, и я хочу, чтобы понять, почему это не работает, прежде чем вставить его в.

Где должен ли использоваться GLKBaseEffect? Я не понимаю, как мы его использовали.

+0

Вот демонстрационный код для справки - https://github.com/jrwren/HelloGLKit/blob/master/HelloGLKit/HelloGLKitViewController.m –

ответ

5

Следующая, кажется, не так, как все вершины одинаковы:

// these are not TRIANGLES, they are vertices 
const Vertex Vertices[] = { 
    {{1, -1, 0}, {1, 0, 0, 1}}, 
    {{1, -1, 0}, {1, 0, 0, 1}}, 
    {{1, -1, 0}, {1, 0, 0, 1}}, 
    {{1, -1, 0}, {1, 0, 0, 1}}, 
}; 

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

glDisable(GL_CULL_FACE); 

перед нанесением. Вы могли бы попытаться забрать свои вершины, как это:

// these are not TRIANGLES, they are vertices 
const Vertex Vertices[] = { 
    {{-.9, -.9, 0}, {1, 0, 0, 1}}, 
    {{.9, -.9, 0}, {1, 0, 0, 1}}, 
    {{-.9, .9, 0}, {1, 0, 0, 1}}, 
    {{.9, .9, 0}, {1, 0, 0, 1}}, 
}; 

// These are the trianges. Just reference the vertices 
const GLubyte Indices[] = { 
    0, 1, 2, 
    2, 1, 3 
}; 

Редактировать

Try комментировать прочь вторую часть обновления:

/* 
// Set the projection matrix of the effect. It defines the field of view 
float aspect = fabsf(self.view.bounds.size.width/self.view.bounds.size.height); 
GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 40., 10.0); 
self.effect.transform.projectionMatrix = projectionMatrix; 

// Rotate about z axis 
// the model view matrix is the transform applied to any geometry that the effect renders 
GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0, 0, -6); 
_rotation += 90 * self.timeSinceLastUpdate; 
modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, GLKMathDegreesToRadians(_rotation), 0, 0, 1); 
self.effect.transform.modelviewMatrix = modelViewMatrix; 
*/ 

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

GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 40., 10.0); 

Переведенные и повернутый объект должен быть расположен на расстоянии между 3-й и 4-й параметр этого вызова для того, чтобы быть нарисованы, а на самом деле третий параметр расстояние до так называемого около плоскости и должно быть меньше 4-го параметра, далеко самолет. Для этих двух параметров безопасная ставка обычно составляет 1 и 100.

GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 1.0, 100.0); 

Edit 2

Ниже приводится рабочая версия.

// 
// HelloGLKitViewController.m 
// OpenGL2Tutorial 
// 
// Created by Sean Hess on 4/10/13. 
// Copyright (c) 2013 Sean Hess. All rights reserved. 
// 

#import "HelloGLKitViewController.h" 

typedef struct { 
    float Position[3]; 
    float Color[4]; 
} Vertex; 

// these are not TRIANGLES, they are vertices 
const Vertex Vertices[] = { 
    {{-.9, -.9, 0}, {1, 0, 0, 1}}, 
    {{.9, -.9, 0}, {1, 0, 0, 1}}, 
    {{-.9, .9, 0}, {1, 0, 0, 1}}, 
    {{.9, .9, 0}, {1, 0, 0, 1}}, 
}; 

// These are the trianges. Just reference the vertices 
const GLubyte Indices[] = { 
    0, 1, 2, 
    2, 1, 3 
}; 


@interface HelloGLKitViewController() { 
    GLuint _vertexBuffer; 
    GLuint _indexBuffer; 
    float _rotation; 
    float _currentRed; 
    BOOL _increasing; 
} 

@property (nonatomic, strong) EAGLContext * context; 
@property (nonatomic, strong) GLKBaseEffect * effect; 
@end 

@implementation HelloGLKitViewController 

// I think this method just fills the objective-c stuff with the information from my c structs 
- (void)setupGL { 
    [EAGLContext setCurrentContext:self.context]; 
    self.effect = [GLKBaseEffect new]; 

    glGenBuffers(1, &_vertexBuffer); // supposed to be an array of buffers, doing that trick again 
    glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); // when I say "GL_ARRAY_BUFFER" I mean _vertexBuffer 
    glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW); 

    glGenBuffers(1, &_indexBuffer); 
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBuffer); 
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(Indices), Indices, GL_STATIC_DRAW); 
} 

- (void)tearDownGL { 
    [EAGLContext setCurrentContext:self.context]; 
    glDeleteBuffers(1, &_vertexBuffer); 
    glDeleteBuffers(1, &_indexBuffer); 
    self.effect = nil; 
} 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    // Do any additional setup after loading the view. 

    self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; 
    if (!self.context) NSLog(@"FAiled to create ES Context"); 
    GLKView * view = (GLKView *)self.view; 
    view.context = self.context; 

    // will automatically pause when interrupted 
    self.pauseOnWillResignActive = YES; 

    [self setupGL]; 
} 

- (void)didReceiveMemoryWarning 
{ 
    [super didReceiveMemoryWarning]; 
    // Dispose of any resources that can be recreated. 
    [self tearDownGL]; 
} 

#pragma mark - GLKViewDelegate 

- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect { 

    glClearColor(_currentRed, 0.0, 0.0, 1.0); 
    glClear(GL_COLOR_BUFFER_BIT); 

    // have to call after you change any properties in the effect, before drrawing 
    [self.effect prepareToDraw]; 

    // We don't have to do this again, since we did it above in setupGL 
    // They're already bound to GL_ARRAY_BUFFER and GL_ELEMENT_ARRAYBUFFER 
    glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer); 
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBuffer); 

    // remember my vertex array contains Vertex(s) 
    // so we're telling it how to read it 
    // position is 3 floats, the offset is based on that offsetof function 
    glEnableVertexAttribArray(GLKVertexAttribPosition); 
    glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid*) offsetof(Vertex, Position)); 

    glEnableVertexAttribArray(GLKVertexAttribColor); 
    glVertexAttribPointer(GLKVertexAttribColor, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid*) offsetof(Vertex, Color)); 

    // 1. pretty much always use triangles 
    // 2. the number of vertices to render. tricky way to do .length on array 
    // 3. the data type 
    // 4. seems like should be pointer to indices. We're using VBOs, so it's already set to the GL_ELEMENT_ARRAY_BUFFER. So give it 0. 
    glDrawElements(GL_TRIANGLES, sizeof(Indices)/sizeof(Indices[0]), GL_UNSIGNED_BYTE, 0); 

} 

- (void)update { 
    if (_increasing) { 
     _currentRed += 1.0 * self.timeSinceLastUpdate; 
    } else { 
     _currentRed -= 1.0 * self.timeSinceLastUpdate; 
    } 
    if (_currentRed >= 1.0) { 
     _currentRed = 1.0; 
     _increasing = NO; 
    } 
    if (_currentRed <= 0.0) { 
     _currentRed = 0.0; 
     _increasing = YES; 
    } 


    // Set the projection matrix of the effect. It defines the field of view 
    float aspect = fabsf(self.view.bounds.size.width/self.view.bounds.size.height); 
    GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 1.0, 100.0); 
    self.effect.transform.projectionMatrix = projectionMatrix; 


    // Rotate about z axis 
    // the model view matrix is the transform applied to any geometry that the effect renders 
    GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0, 0, -6); 
    _rotation += 90 * self.timeSinceLastUpdate; 
    modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, GLKMathDegreesToRadians(_rotation), 0, 0, 1); 
    self.effect.transform.modelviewMatrix = modelViewMatrix; 

} 

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { 
    self.paused = !self.paused; 

    NSLog(@"timeSinceLastUpdate: %f", self.timeSinceLastUpdate); 
    NSLog(@"timeSinceLastDraw: %f", self.timeSinceLastDraw); 
    NSLog(@"timeSinceFirstResume: %f", self.timeSinceFirstResume); 
    NSLog(@"timeSinceLastResume: %f", self.timeSinceLastResume); 
} 


@end 
+0

Duh, спасибо.Он все еще не работает, вы можете проверить суть снова? –

+2

Я предлагаю взять это как опыт обучения; пересмотреть все свои входы и проверить наличие ошибок. – dans3itz

+0

Большое спасибо! Проблема была действительно перспективой. Я ошибочно поставил 40 - 10 вместо 4-10. Ваше объяснение действительно помогает мне понять, что происходит. –

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