0

我创建了 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
4

2 回答 2

2

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

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

于 2013-01-30T20:54:05.243 回答
1

当你设法让 openGL ES 2.0 运行时——这在启动时可能很困难——但你没有得到你想要的图纸,我绝对推荐在设备上运行,这使得 XCode 的额外功能能够调试 openGL

在此处输入图像描述

那么你也能 :

  • 逐步完成您的循环和绘图调用,并查看刷新的颜色/深度缓冲区图像
  • 查看所有有界 gl 对象
  • 查看 VAOs 内容(您可以看到它指向的实际数据,对查找丢失的数据/指针很有用)
  • 程序:您可以在 GPU 上实时编辑着色器(gl 绑定对象 -> 程序:双击!)对润色着色器很有用

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

您忘记的属性是 GLKBaseEffectcolorMaterialEnabled

于 2013-02-01T03:34:22.583 回答