2012-02-26 2 views
0

Я полный идиот в OpenGL, и я не могу понять, почему мой код не работает, отображается только четкий цвет. Я пытаюсь настроить простой рендеринг на iOS. Пожалуйста, кто-нибудь может мне помочь?Нужна помощь с простым кодом OpenGL ES 2.0

Мой основной код сцена:

// 
// Scene.m 

#import "Scene.h" 

GLfloat vertices[] = { 
    0.0, 0.0, 
    1.0, 0.0, 
    0.0, 1.0, 
    1.0, 1.0 
}; 

@implementation Scene 
+(Class)layerClass { 
    return [CAEAGLLayer class]; 
} 
- (id)initWithFrame:(CGRect)frame 
{ 
    self = [super initWithFrame:frame]; 
    if (self) { 
     CAEAGLLayer *glLayer = (CAEAGLLayer *)self.layer; 
     glLayer.opaque = YES; 
     glLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:FALSE], kEAGLDrawablePropertyRetainedBacking, kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat, nil]; 

     context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; 
     if (!context) { 
      NSLog(@"Failed to create 2.0 context"); 
      exit(1); 
     } 

     [EAGLContext setCurrentContext:context]; 


     GLuint framebuffer, colorRenderbuffer; 
     glGenFramebuffers(1, &framebuffer); 
     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer); 
     glGenRenderbuffers(1, &colorRenderbuffer); 
     glBindRenderbuffer(GL_RENDERBUFFER, colorRenderbuffer); 
     [context renderbufferStorage:GL_RENDERBUFFER fromDrawable:glLayer]; 
     glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRenderbuffer); 

     GLuint vbo; 
     glGenBuffers(1, &vbo); 
     glBindBuffer(GL_ARRAY_BUFFER, vbo); 
     glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); 

     GLuint program = [self loadShaders:@"Test.vp" frag:@"Test.fp"]; 
     positionIndex = glGetAttribLocation(program, "position"); 
     mvpIndex = glGetUniformLocation(program, "mvp"); 
     glLinkProgram(program); //added this 
     GLint param; 
     glGetProgramiv(program, GL_LINK_STATUS, &param); 
     if (param == GL_FALSE) { 
      NSLog(@"Failed to link the program"); 
      exit(1); 
     } 
     glUseProgram(program); 

     CADisplayLink *displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(render:)]; 
     [displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode]; 
    } 
    return self; 
} 
-(void)render:(CADisplayLink *)_displayLink { 
    glClearColor(1.0f, 0.0f, 0.0f, 1.0f); 
    glClear(GL_COLOR_BUFFER_BIT); 

    glEnableVertexAttribArray(positionIndex); 
    glVertexAttribPointer(positionIndex, 2, GL_FLOAT, GL_FALSE, 0, (GLvoid *)0); 
    GLfloat mvp[] = { 
     1, 0, 0, 0, 
     0, 1, 0, 0, 
     0, 0, 1, 0, 
     0, 0, 0, 1 
    }; 
    glUniformMatrix4fv(mvpIndex, 1, GL_FALSE, mvp); 
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 

    [context presentRenderbuffer:GL_RENDERBUFFER]; 

    glDisableVertexAttribArray(positionIndex); 
} 
-(GLuint)loadShaders:(NSString *)vertShader frag:(NSString *)fragShader { 
    NSString *vertPath = [[NSBundle mainBundle] pathForResource:[vertShader stringByDeletingPathExtension] ofType:@"vp"]; 
    NSString *fragPath = [[NSBundle mainBundle] pathForResource:[fragShader stringByDeletingPathExtension] ofType:@"fp"]; 

    if (!vertPath || !fragPath) { 
     NSLog(@"Failed to find paths of shaders"); 
     exit(1); 
    } 

    NSError *error; 
    const GLchar* vertSource = [[NSString stringWithContentsOfFile:vertPath encoding:NSUTF8StringEncoding error:&error] UTF8String]; 
    const GLchar* fragSource = [[NSString stringWithContentsOfFile:fragPath encoding:NSUTF8StringEncoding error:&error] UTF8String]; 

    if (!vertSource || !fragSource) { 
     NSLog(@"Faild to load shader sources\n%@", [error localizedDescription]); 
     exit(1); 
    } 

    GLuint vert, frag; 
    vert = glCreateShader(GL_VERTEX_SHADER); 
    frag = glCreateShader(GL_FRAGMENT_SHADER); 

    GLint length = strlen(vertSource); 
    glShaderSource(vert, 1, &vertSource, &length); 
    length = strlen(fragSource); 
    glShaderSource(frag, 1, &fragSource, &length); 

    glCompileShader(vert); 
    glCompileShader(frag); 

    GLint success; 
    glGetShaderiv(vert, GL_COMPILE_STATUS, &success); 
    if (success == GL_FALSE) { 
     GLchar messages[256]; 
     glGetShaderInfoLog(vert, sizeof(messages), 0, &messages[0]); 
     NSLog(@"Failed to compile vertex shader\n%@", [NSString stringWithUTF8String:messages]); 
     exit(1); 
    } 

    glGetShaderiv(frag, GL_COMPILE_STATUS, &success); 
    if (success == GL_FALSE) { 
     GLchar messages[256]; 
     glGetShaderInfoLog(frag, sizeof(messages), 0, &messages[0]); 
     NSLog(@"Failed to compile fragment shader\n%@", [NSString stringWithUTF8String:messages]); 
     exit(1); 
    } 

    GLuint prog = glCreateProgram(); 
    glAttachShader(prog, vert); 
    glAttachShader(prog, frag); 

    //Removed glLinkProgram() 

    return prog; 
} 
@end 

Код шейдера:

attribute vec2 position; 
uniform mat4 mvp; 

void main(void) { 
    gl_Position = mvp * vec4(position.xy, -1.0, 1.0); 
} 

и

void main() { 
    gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0); 
} 

Спасибо заранее

+0

Попробуйте использовать 'glGetError' после вызова функций gl. Сначала вы должны попробовать попробовать 'glUseProgram' и' glDrawArrays'. Ожидание результатов. – kibab

ответ

3
glEnableVertexAttribArray(positionIndex); 
glVertexAttribPointer(positionIndex, 2, GL_FLOAT, GL_FALSE, 0, vertices); 

Эта строка неверна:

glDisableVertexAttribArray(positionIndex); 

Не отключить его, прежде чем использовать его, или вы потеряете его

Кроме того, поскольку вы используете VBO для Verts, вы не нужно сделать это:

glVertexAttribPointer(positionIndex, 2, GL_FLOAT, GL_FALSE, 0, vertices); 

Просто включите его в этом:

glVertexAttribPointer(positionIndex, 2, GL_FLOAT, GL_FALSE, 0, (void*)0); 

Вы ВГА e vbo, связанный с графическим процессором, он будет использовать этот буфер для рисования. Используйте glVertexAttribPointer для определения смещения в vbo, он найдет первый элемент для данного атрибута.

@kibab Предложение, которое я сделал для vbo, является правильным.

Принимает EXC_BAD_ACCESS из-за его атрибута, не имеющей привязки к его шейдеру. См. Комментарии ниже. Что касается mvp, вы неверны, снова. Mvp предназначен для преобразования точек в систему координат -1.0, -1.0, до 1.0, 1.0. Это означает, что его вершины должны отображаться с учетом их значений.

См. http://flylib.com/books/2/789/1/html/2/images/03fig02.jpg.

Также изменение координаты z ничего не сделает для вас. Измените свою вершину, чтобы начать с -1.0, -1.0 и перейдите к 1.0.1.0 в полноэкранный режим, чтобы мы могли что-то получить на экране.

Предполагая, что вы не используете какие-либо классы apple, предоставленные gl, ваш glViewPort не будет установлен.

Попробуйте использовать связанный Таблица размеров вашего вида по

glViewport(0, 0, bouds.width, bounds.height); 

Также пожалуйста, поместите ваши Verts на 0,0 г вместо -1.0

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

GLfloat  vertices[] = { 
      -1.0f, -1.0f, 0.0f, 
      1.0f, -1.0f , 0.0f, 
      -1.0f, 1.0f , 0.0f, 
      1.0f, 1.0f , 0.0f,}; 

     glVertexAttribPointer(positionIndex,3,GL_FLOAT,0,0,vertices); 
     glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 
+0

Спасибо, но у меня все еще возникают проблемы. Если я изменил glVertexAttribPointer, как вы предложили, я все равно получаю красный экран, но если я только изменю glDisableVertexAttribArray, glDrawArrays вернет EXC_BAD_ACCESS. – user1128661

+0

Внезапно он решил, что больше не будет разбиваться на glDrawArrays, но я все равно получаю красный экран. – user1128661

+0

Хорошо, последний фрагмент, который является неправильным, заключается в том, как вы получаете атрибуты. Вы должны получить атрибуты перед связыванием. Итак, перед glLinkProgram (prog); сопоставьте свой атрибут – Nico