为什么顶点显示为白色而不是顶点缓冲区中的颜色?

时间:2013-01-30 18:40:23

标签: opengl-es opengl-es-2.0 glkit

我创建了3个缓冲区来分隔顶点位置,颜色和索引数据。

顶点正确呈现为正方形,但它是白色而不是数组dynamicVertexData中定义的颜色。

我正在使用OpenGL ES 2.0,但我认为我正在犯一般的OpenGL错误。

有人能发现它吗?

typedef struct _vertexStatic
{
    GLfloat position[2];
} vertexStatic;

typedef struct _vertexDynamic
{
    GLubyte color[4];
} vertexDynamic;

enum {
    ATTRIB_POSITION,
    ATTRIB_COLOR,
    NUM_ATTRIBUTES
};

// Separate buffers for static and dynamic data.
GLuint    staticBuffer;
GLuint    dynamicBuffer;
GLuint    indexBuffer;

const vertexStatic staticVertexData[] = {

    {0, 0},
    {50, 0},
    {50, 50},
    {0, 50},
};

vertexDynamic dynamicVertexData[] = {

    {0, 0, 255, 255},
    {0, 0, 255, 255},
    {0, 0, 255, 255},
    {0, 0, 255, 255},
};

const GLubyte indices[] = {

    0, 1, 2,
    2, 3, 0,
};


- (void)setupGL {

    CGSize screenSize = [UIApplication currentSize];
    CGSize screenSizeHalved = CGSizeMake(screenSize.width/2, screenSize.height/2);

    numIndices = sizeof(indices)/sizeof(indices[0]);

    [EAGLContext setCurrentContext:self.context];

    glEnable(GL_CULL_FACE); // Improves perfromance

    self.effect = [[GLKBaseEffect alloc] init];


    // The near and far plane are measured in units from the eye
    self.effect.transform.projectionMatrix = GLKMatrix4MakeOrtho(-screenSizeHalved.width,
                                                                     screenSizeHalved.width,
                                                                     -screenSizeHalved.height,
                                                                     screenSizeHalved.height,
                                                                     0.0f, 1.0f);

    self.preferredFramesPerSecond = 30;

    CreateBuffers();
}

void CreateBuffers()
{
    // Static position data
    glGenBuffers(1, &staticBuffer);
    glBindBuffer(GL_ARRAY_BUFFER, staticBuffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(staticVertexData), staticVertexData, GL_STATIC_DRAW);

    // Dynamic color data
    // While not shown here, the expectation is that the data in this buffer changes between frames.
    glGenBuffers(1, &dynamicBuffer);
    glBindBuffer(GL_ARRAY_BUFFER, dynamicBuffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(dynamicVertexData), dynamicVertexData, GL_DYNAMIC_DRAW);

    // Static index data
    glGenBuffers(1, &indexBuffer);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
}

void DrawModelUsingMultipleVertexBuffers()
{
    glBindBuffer(GL_ARRAY_BUFFER, staticBuffer);
    glVertexAttribPointer(ATTRIB_POSITION, 2, GL_FLOAT, GL_FALSE, sizeof(vertexStatic), 0);
    glEnableVertexAttribArray(ATTRIB_POSITION);

    glBindBuffer(GL_ARRAY_BUFFER, dynamicBuffer);
    glVertexAttribPointer(ATTRIB_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(vertexDynamic), 0);
    glEnableVertexAttribArray(ATTRIB_COLOR);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
    glDrawElements(GL_TRIANGLES, sizeof(indices)/sizeof(GLubyte), GL_UNSIGNED_BYTE, (void*)0);
    }

- (void)tearDownGL {

    [EAGLContext setCurrentContext:self.context];

    glDeleteBuffers(1, &_vertexBuffer);
    glDeleteBuffers(1, &_indexBuffer);
    //glDeleteVertexArraysOES(1, &_vertexArray);

    self.effect = nil;    

}

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];

    if (!self.context) {
        NSLog(@"Failed to create ES context");
    }

    GLKView *view = (GLKView *)self.view;
    view.context = self.context;
//    view.drawableMultisample = GLKViewDrawableMultisample4X; // Smoothes jagged lines. More processing/memory
    view.drawableColorFormat = GLKViewDrawableColorFormatRGB565; // Lower colour range. Less processing/memory
    [self setupGL];
}


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

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

    [self.effect prepareToDraw];

    DrawModelUsingMultipleVertexBuffers();
}

@end

2 个答案:

答案 0 :(得分:2)

您已使用ATTRIB_COLORglVertexAttribPointer入口点启用并将顶点缓冲区绑定到glEnableVertexAttribArray绑定点,但未指定如何处理它们。

OpenGLES 2.0删除了大部分固定功能渲染管道,因此您需要编写顶点着色器以使用顶点缓冲区。在1.X中,您可以使用glColorPointer入口点为固定功能管道指定顶点颜色。

答案 1 :(得分:1)

当你设法运行openGL ES 2.0时 - 启动时可能很难 - 但是你没有得到你想要的图纸,我明确地建议在设备上运行,这使得XCode的额外功能可以调试openGL

enter image description here

然后你可以:

  • 逐步完成循环并绘制调用,并查看颜色/ 深度缓冲图像刷新
  • 查看所有有界的gl对象
  • 查看VAO内容(您可以看到它指向的实际数据,对查找缺失的数据/指针很有用)
  • 程序:您可以在GPU上编辑着色器LIVE(gl bound objects - > program:双击!),可用于修饰着色器

如果你很好奇,这也非常有用,可以深入了解GLKit的GLKBaseEffect内部工作 - 实际上只是生成一个openGL程序,其特定的顶点和片段着色器代码取决于你设置的属性。 ..

您忘记的属性是GLKBaseEffect colorMaterialEnabled