简体   繁体   English

OpenGL ES显示白色或黑色屏幕

[英]OpenGL ES shows white or black screen

I'm trying to port my desktop OpenGL program to OpenGL ES 1.1 on iOS but I'm having no luck. 我试图将我的桌面OpenGL程序移植到iOS上的OpenGL ES 1.1,但我没有运气。 All the code is the same eg drawArrays and glOrthof, except the framebuffer logic on the iOS side obviously is different, as it takes the place of GLUT which does not exist on iOS. 所有代码都是相同的,例如drawArrays和glOrthof,只是iOS端的帧缓冲逻辑明显不同,因为它代替了iOS上不存在的GLUT。 Can someone tell me what is wrong with this code? 有人可以告诉我这段代码有什么问题吗? It tends to show either a white or black screen. 它倾向于显示白色或黑色屏幕。

gllayer = (CAEAGLLayer *)self.layer;
gllayer.opaque = TRUE;
gllayer.drawableProperties = @{
    kEAGLDrawablePropertyRetainedBacking: @YES,
    kEAGLDrawablePropertyColorFormat: kEAGLColorFormatRGBA8
};
context = [[EAGLContext alloc] initWithAPI: kEAGLRenderingAPIOpenGLES1];
if (!context || ![EAGLContext setCurrentContext:context]) {
    [self release];
    return nil;
}
glGenFramebuffersOES (1, &framebuffer);
glGenRenderbuffersOES (1, &renderbuffer);
glBindFramebufferOES (GL_FRAMEBUFFER_OES, framebuffer);
glBindRenderbufferOES (GL_RENDERBUFFER_OES, renderbuffer);
[context renderbufferStorage: GL_RENDERBUFFER_OES fromDrawable: gllayer];
glFramebufferRenderbufferOES (GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, renderbuffer);
glGetRenderbufferParameterivOES (GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth);
glGetRenderbufferParameterivOES (GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight);
glGenRenderbuffersOES (1, &depthbuffer);
glBindRenderbufferOES (GL_RENDERBUFFER_OES, depthbuffer);
glRenderbufferStorageOES (GL_RENDERBUFFER_OES, GL_DEPTH_COMPONENT16_OES, backingWidth, backingHeight);
glFramebufferRenderbufferOES (GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, depthbuffer);
if (glCheckFramebufferStatusOES (GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES)
    return nil;

It looks to me like basically on iOS we're drawing into a buffer. 在我看来,基本上就像在iOS上,我们正在吸收缓冲区。 If it were possible to draw directly onto the screen I'd just do that instead. 如果可以直接在屏幕上绘制,我会这样做。

- (void) startAnimation
{
     displayLink = [NSClassFromString(@"CADisplayLink") displayLinkWithTarget:self
                                                                selector:@selector(drawGLContent)
               ];
     [displayLink setFrameInterval: animationFrameInterval];
     [displayLink addToRunLoop: [NSRunLoop currentRunLoop]
                  forMode:NSDefaultRunLoopMode];

    animating = TRUE;
}

@Frank, I can see that you are having troubles with the OpenGL initialization. @Frank,我可以看到您在OpenGL初始化方面遇到了麻烦。 Here I've created a MyGLView view that is a UIView that contains all the OpenGL setup code. 在这里,我创建了一个MyGLView视图,它是一个包含所有OpenGL设置代码的UIView。 The EAGLContext, the renderbuffer and the framebuffer are correctly created and destroyed. 正确创建并销毁了EAGLContext,渲染缓冲区和帧缓冲区。 I have added some comments so you can see what is going on. 我添加了一些评论,以便您了解发生了什么。

Also The method drawGLContent is where you need to place your draw calls specifically under the "TODO" comment. 同样,方法drawGLContent是您需要将绘制调用专门放在“ TODO”注释下的位置。

#import <GLKit/GLKit.h>
#import <Foundation/Foundation.h>

@interface MyGLView : UIView{

    EAGLContext *context;

    GLuint viewRenderbuffer, viewFramebuffer;
}

- (void)drawGLContent;

@end

@implementation MyGLView

// Implement this to override the default layer class (which is [CALayer class]).
// We do this so that our view will be backed by a layer that is capable of OpenGL ES rendering.
+ (Class)layerClass
{
    return [CAEAGLLayer class];
}

- (id)init{
    if ((self = [super init])) {
        [self initView];
    }

    return self;
}

- (id)initWithFrame:(CGRect)frame{
    if ((self = [super initWithFrame:frame])) {
        [self initView];
    }

    return self;
}

- (id)initWithCoder:(NSCoder*)coder {

    if ((self = [super initWithCoder:coder])) {
        [self initView];
    }

    return self;
}

- (void)initView{
    CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer;

    eaglLayer.opaque = YES;
    // In this application, we want to retain the EAGLDrawable contents after a call to presentRenderbuffer.
    eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:
                                    [NSNumber numberWithBool:YES], kEAGLDrawablePropertyRetainedBacking, kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat, nil];

    context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1];

    if (!context || ![EAGLContext setCurrentContext:context]) {
        NSLog(@"failed to init HeatmapView");
    }

    // Set the view's scale factor as you wish
    self.contentScaleFactor = [[UIScreen mainScreen] scale];

    [EAGLContext setCurrentContext:context];

    [self createBuffers];
}

- (void)createBuffers{

    // The pixel dimensions
    GLint backingWidth;
    GLint backingHeight;

    // Generate IDs for a framebuffer object and a color renderbuffer
    glGenFramebuffers(1, &viewFramebuffer);
    glGenRenderbuffers(1, &viewRenderbuffer);

    glBindFramebuffer(GL_FRAMEBUFFER, viewFramebuffer);
    glBindRenderbuffer(GL_RENDERBUFFER, viewRenderbuffer);
    // This call associates the storage for the current render buffer with the EAGLDrawable (our CAEAGLLayer)
    // allowing us to draw into a buffer that will later be rendered to screen wherever the layer is (which corresponds with our view).
    [context renderbufferStorage:GL_RENDERBUFFER fromDrawable:(id<EAGLDrawable>)self.layer];
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, viewRenderbuffer);

    glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &backingWidth);
    glGetRenderbufferParameteriv(GL_RENDERBUFFER,   GL_RENDERBUFFER_HEIGHT, &backingHeight);

    if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
    {
        NSLog(@"failed to make complete framebuffer object %x", glCheckFramebufferStatus(GL_FRAMEBUFFER));
    }

    // Setup the view port in Pixels
    glViewport(0, 0, backingWidth ,backingHeight);
}

- (void)destroyBuffers{

    // Destroy framebuffers and renderbuffers
    if (viewFramebuffer) {
        glDeleteFramebuffers(1, &viewFramebuffer);
        viewFramebuffer = 0;
    }
    if (viewRenderbuffer) {
        glDeleteRenderbuffers(1, &viewRenderbuffer);
        viewRenderbuffer = 0;
    }
}

#pragma mark - Public methods

- (void)drawGLContent{

    [EAGLContext setCurrentContext:context];

    if(viewRenderbuffer == 0 || viewFramebuffer == 0){
        [self createBuffers];
    }

    //Clear the framebuffer
    glClearColor(0.0, 0.0, 0.0, 0.0);
    glClear(GL_COLOR_BUFFER_BIT);

    ///////////////////////////////////////////
    //TODO:MAKE Draw Calls!!
    ///////////////////////////////////////////

    // Display the buffer
    [context presentRenderbuffer:GL_RENDERBUFFER];
}

#pragma mark -

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {
    return NO;
}

-(void)layoutSubviews
{
    [EAGLContext setCurrentContext:context];

    [self destroyBuffers];
    [self createBuffers];

    //Clear the framebuffer
    glClearColor(0.0, 0.0, 0.0, 0.0);
    glClear(GL_COLOR_BUFFER_BIT);
    [context presentRenderbuffer:GL_RENDERBUFFER];
}

- (void)dealloc
{
    [self destroyBuffers];

    // tear down context
    if ([EAGLContext currentContext] == context)
        [EAGLContext setCurrentContext:nil];
}

@end

This class is based in Ray Wenderlich OpenGL ES 2.0 tutorials but slightly adapted to OpenGL ES 1.0. 此类基于Ray Wenderlich OpenGL ES 2.0教程,但略微适用于OpenGL ES 1.0。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM