Ios OpenGL循环不工作

Ios OpenGL循环不工作,ios,opengl-es,Ios,Opengl Es,我试着画一个圆圈,但不知怎么搞得一团糟 typedef struct { float Position[3]; float Color[4]; } Vertex; Vertex* Vertices; //vertices store information for each "point" used to draw a triangle GLubyte* Indices; //Used to reuse vertices //const GLushort Indices

我试着画一个圆圈,但不知怎么搞得一团糟

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

Vertex* Vertices; //vertices store information for each "point" used to draw a triangle
GLubyte* Indices; //Used to reuse vertices
//const GLushort Indices[] = {
//    0, 1, 2,
//    2, 3,
//    3, 4
//};
int points = 181;

@interface CometGLViewController (){
    float _curRed;
    BOOL _increasing;
    GLuint _vertexBuffer;
    GLuint _indexBuffer;
    GLuint _vertexArray;
    float _rotation;
}

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

@end

@implementation CometGLViewController

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

# pragma mark - View lifecycle

- (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;
    [self setupVertices];
    [self setupGL];
}

- (void)viewDidUnload
{
    [super viewDidUnload];

    [self tearDownGL];

    if ([EAGLContext currentContext] == self.context) {
        [EAGLContext setCurrentContext:nil];
    }
    self.context = nil;
}

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

#pragma mark - GLKViewDelegate

- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect
{
    glClearColor(0, 0, 0, 1.0);
    glClear(GL_COLOR_BUFFER_BIT);

    [self.effect prepareToDraw];

    glBindVertexArrayOES(_vertexArray);
    glDrawElements(GL_TRIANGLES, points * 2 + 1, GL_UNSIGNED_BYTE, 0);
}

#pragma mark - GLKViewControllerDelegate

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

    //Rotate
    float aspect = fabsf(self.view.bounds.size.width / self.view.bounds.size.height);
    GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 4.0f, 15.0f);
    self.effect.transform.projectionMatrix = projectionMatrix;

    GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -6.0f);
    //_rotation += 90 * self.timeSinceLastUpdate;
    //modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, GLKMathDegreesToRadians(_rotation), 0, 0, 1);
    self.effect.transform.modelviewMatrix = modelViewMatrix;
}

#pragma mark - OpenGL stuff
- (void)setupGL {

    [EAGLContext setCurrentContext:self.context];
    glEnable(GL_CULL_FACE);
    self.effect = [[GLKBaseEffect alloc] init];

// ----- Setup textures
//    NSDictionary * options = [NSDictionary dictionaryWithObjectsAndKeys:
//                              [NSNumber numberWithBool:YES],
//                              GLKTextureLoaderOriginBottomLeft,
//                              nil];
//    
//    NSError * error;
//    NSString *path = [[NSBundle mainBundle] pathForResource:@"tile_floor" ofType:@"png"];
//    GLKTextureInfo * info = [GLKTextureLoader textureWithContentsOfFile:path options:options error:&error];
//    if (info == nil) {
//        NSLog(@"Error loading file: %@", [error localizedDescription]);
//    }
//    
//    self.effect.texture2d0.name = info.name;
//    self.effect.texture2d0.enabled = true;

    glGenVertexArraysOES(1, &_vertexArray);
    glBindVertexArrayOES(_vertexArray);
// ----- create new buffer,  work with "vertexBuffer", glBufferData sends data for opengl usage
    glGenBuffers(1, &_vertexBuffer);
    glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(Vertex) * points, Vertices, GL_STATIC_DRAW);

    glGenBuffers(1, &_indexBuffer);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBuffer);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLubyte) * (points * 2 + 1), Indices, GL_STATIC_DRAW);

// ----- Setup vertices attributes
    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));
}

- (void)tearDownGL {

    [EAGLContext setCurrentContext:self.context];

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

    self.effect = nil;

}

- (void)setupVertices
{
    Vertices = malloc(sizeof(Vertex) * points);
    Vertex v = {{0, 0, 0}, {0, 0, 1, 1}};
    Vertices[0] = v;
    GLubyte ind[points *2 +1];
    ind[0] = 0;
    int indPos = 1;

    for(int i = 1; i < points; ++i){
        float theta = 2.0 * 3.1415926 * ( ((float)i-1)*2 / (float)points );
        Vertex v = {{cosf(theta), sinf(theta), 0}, {1, 1, 0, 1}};
        Vertices[i] = v;

        ind[indPos] = i;
        if(i != points-1)
            ind[indPos + 1] = i+1;
        else
            ind[indPos +1] = 1;
        indPos = indPos +2;

        NSLog(@"%f und %f", cosf(theta), sinf(theta));
        NSLog(@"%i und %i", i, i+1);
    }
    Indices = ind;
}

#pragma mark - Touch control

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

@end
typedef结构{
浮动位置[3];
浮色[4];
}顶点;
顶点*顶点//顶点存储用于绘制三角形的每个“点”的信息
GLubyte*索引//用于重用顶点
//常量短索引[]={
//    0, 1, 2,
//    2, 3,
//    3, 4
//};
积分=181;
@接口:GLViewController(){
浮动汇率;
布尔值增加;
GLuint_顶点缓冲区;
胶合指数缓冲;
胶合垂直排列;
浮动旋转;
}
@属性(强,非原子)EAGLContext*上下文;
@性质(强、非原子)GLKBaseEffect*效应;
@结束
@视图控制器的实现
-(id)initWithNibName:(NSString*)nibNameOrNil bundle:(NSBundle*)nibBundleOrNil
{
self=[super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
如果(自我){
//自定义初始化
}
回归自我;
}
#pragma标记-视图生命周期
-(无效)viewDidLoad
{
[超级视图下载];
self.context=[[EAGLContext alloc]initWithAPI:keagrenderingapiopengles2];
if(!self.context){
NSLog(@“未能创建ES上下文”);
}
GLKView*视图=(GLKView*)self.view;
view.context=self.context;
view.drawableMultisample=GLKViewDrawableMultisample4X;
[自我设置];
[自设置GL];
}
-(无效)视图卸载
{
[超级视频下载];
[自毁];
if([EAGLContext currentContext]==self.context){
[EAGLContext setCurrentContext:nil];
}
self.context=nil;
}
-(无效)未收到记忆警告
{
[超级记忆警告];
//处置所有可以重新创建的资源。
}
#pragma标记-GLKViewDelegate
-(void)glkView:(glkView*)视图drawInRect:(CGRect)rect
{
glClearColor(0,0,0,1.0);
glClear(GLU颜色缓冲位);
[自生效准备提款];
GLBindVertexarray(_vertexArray);
GLD元素(GLU三角形,点*2+1,GLU无符号字节,0);
}
#pragma标记-GLKViewControllerDelegate
-(作废)更新
{
如果(_增加){
_curRed+=1.0*self.timesInclastUpdate;
}否则{
_curRed-=1.0*self.timesInclastUpdate;
}
如果(\u curRed>=1.0){
_curRed=1.0;
_增加=否;
}
如果(_curRed您正在使用

GLubyte ind[points*3];
但是你有

int points = 360;
由于ubyte只有8位,您最多可以处理256个不同的顶点,这说明您没有得到一个完整的圆,只有256度。然而,我认为可能还有其他问题,因为我不明白这个错误如何解释您使用的屏幕截图中的所有问题…

GLubyte ind[points*3];
但是你有

int points = 360;
由于ubyte只有8位,您最多可以处理256个不同的顶点,这说明您没有得到一个完整的圆,只有256度。然而,我认为可能还有其他问题,因为我不明白这个错误如何解释您屏幕截图中的所有问题…

对于您使用的基本模式,您的索引是错误的。 它们是按扇形顺序排列的,但随后您将
GL\u TRIANGLE\u fan
作为基本类型传递给
glpaurements(…)
。这不是冗余问题,这完全是错误的。您有3N个索引,这意味着与这些索引一起使用的唯一逻辑基本模式是
GL\u TRIANGLES

目前,在调用
glpaurements(…)
时,只需将
GL_三角形
替换为
GL_三角形
,即可解决此问题,但这不会获得针对三角形邻接进行优化的基本模式的好处。
我将在下面解释一个更好的解决方案,它将减少索引数组的必要大小,并正确使用
GL\u TRIANGLE\u FAN

根据以下代码判断: 我可以得出结论,你的思路是正确的,只是你忘了扇形不是由每个三角形的3个索引定义的;扇形中的每个附加三角形共享一个公共中心顶点,并重复使用最后一个顶点。因此,索引的数量是N+2,其中N是三角形的数量

你要做的是用你的索引沿着圆的周长走,你将生成一个V-2三角形,其中V是圆周长上的顶点数。如果你纠正了你的索引,那么你应该得到一个很好的三角化圆(或者近似于一个的圆)


从视觉上看,三角形风扇就是这样工作的:

每个三角形共享中心顶点
A
,并重新使用最后一个寻址的顶点。因此,定义
ABC
后,每个后续三角形只需要1个点(例如
D
e
F

另一种思考方式是,每个三角形与前面的三角形共享一条从中心顶点辐射的边;就像纸扇一样


更新: 我相信这会解决您的问题,索引的数量实际上会匹配一个适当扇形圆中的顶点数量。我对与上面顶点相关的三角形数量的讨论可能会产生一些混乱,三角形的数量实际上在代码中的任何地方都没有定义

- (void)setupVertices
{
    Vertices = malloc(sizeof(Vertex) * points);
    Vertex v = {{0, 0, 0}, {0, 0, 1, 1}};
    Vertices[0] = v;
    GLubyte ind[points];
    ind[0] = 0;
    int indPos = 1;

    for(int i = 1; i < points; ++i){
        float theta = 2.0 * 3.1415926 * ( ((float)i-1)*2 / (float)points );
        Vertex v = {{cosf(theta), sinf(theta), 0}, {1, 1, 0, 1}};
        Vertices[i] = v;

        ind[indPos] = i;

        NSLog(@"%f und %f", cosf(theta), sinf(theta));
        NSLog(@"%i und %i", i, i+1);
    }
    Indices = ind;
}
-(无效)设置顶点
{
顶点=malloc(sizeof(顶点)*点);
顶点v={0,0,0},{0,0,1,1};
顶点[0]=v;
GLubyte ind[点];
ind[0]=0;
int indPos=1;
对于(int i=1;i
现在,当需要绘制扇形时,您将使用许多索引点。顺便说一句,您甚至不需要索引顶点渲染来高效地绘制扇形;索引都是连续的。
gldrawArray(GL_Triange