glDrawElements没有显示任何内容

时间:2013-04-10 17:22:34

标签: ios objective-c opengl-es opengl-es-2.0 glkit

我正在尝试在iOS上学习OpenGL。我正在学习本教程。

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的位置?我看不出我们是如何使用它的。

1 个答案:

答案 0 :(得分: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}},
};

即使其他一切都是正确的,你的三角形也会退化为 所有顶点都是重合的。当你修复坐标时,make 确保索引以逆时针方式引用顶点 时尚,或者,对于您的第一次实验更好,请致电

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
};

修改

尝试评论更新的第二部分:

/*
// 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个参数之间的距离才能绘制,实际上第3个参数是所谓的 near 平面的距离,并且必须小于第4个参数 far 平面。这两个参数的安全赌注通常为1和100。

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

修改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