2010-09-13 123 views
1

出于某种原因,我的纹理未绘制,即使我的代码看起来与旧项目完全相同。到目前为止,顶点和TexCoords看起来很好,因为我正在绘制白色方块,而应绘制纹理。iOS 4.1 OpenGL ES 1.1未绘制纹理

的进程迄今所说, 我加载了一个位指示和的loadView,我

glEnable(GL_TEXTURE_2D); 
glEnable(GL_BLEND); 
glBlendFunc(GL_ONE, GL_SRC_COLOR); 

然后我的渲染器装起来,这不就没事建设。之后,我将我的纹理加载到gl中。此代码是我旧项目的直接副本,我知道它的工作原理。

- (GLuint)textureFromPath:(NSString *)path 
{ 
    GLuint texture; 
    glGenTextures(1, &texture); 

    UIImage *img = [[UIImage alloc] initWithContentsOfFile:path]; 

    if (!img) { 
     NSLog(@"Image \"%@\" could not be loaded and was not bound", path); 
     return 0; 
    } 

    CGImageRef cgimage = img.CGImage; 

    float width = CGImageGetWidth(cgimage); 
    float height = CGImageGetHeight(cgimage); 
    CGRect bounds = CGRectMake(0, 0, width, height); 
    CGColorSpaceRef colourSpace = CGColorSpaceCreateDeviceRGB(); 

    void *image = malloc(width * height * 4); 
    CGContextRef context = CGBitmapContextCreate(image, width, height, 8, 4 * width, colourSpace, kCGImageAlphaPremultipliedLast); 
    CGColorSpaceRelease(colourSpace); 
    CGContextClearRect(context, bounds); 
    CGContextTranslateCTM (context, 0, height); 
    CGContextScaleCTM (context, 1.0, -1.0); 
    CGContextDrawImage(context, bounds, cgimage); 

    CGContextRelease(context); 

    glBindTexture(GL_TEXTURE_2D, texture); 

    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); 
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); 

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image);  

    [img release]; 
    free(image); 

    return texture; 
} 

我再从GL的生成纹理,并指定它的渲染器然后在0阵列我也这样做在我的老项目,也没关系曾在现在的位置。我感觉到目前为止这么好。

然后,应用程序告诉它startAnimation,然后它调用setFramebuffer,它内部调用createFramebuffer,因为framebuffer是未定义的。然后通知Renderer(btw,Renderer是一个C++类)它已经创建了帧缓冲区。

void bufferHasBeenCreated() const { 
    glMatrixMode(GL_PROJECTION); 
    glLoadIdentity(); 
    glOrthof(-160.0f, 160.0f, -240.0f, 240.0f, -5.0f, 1.0f); 
    glViewport(0, 0, 320, 480); 

    glMatrixMode(GL_MODELVIEW); 
    glLoadIdentity(); 

    glEnable(GL_TEXTURE_2D); 
    glEnable(GL_BLEND); 
    glBlendFunc(GL_ONE, GL_SRC_COLOR); 
} 

然后它在渲染器上调用渲染。

void render() { 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
    glLoadIdentity(); 
    glClearColor(0.325f, 0.0f, 0.325f, 1.0f); 

    glEnableClientState(GL_VERTEX_ARRAY); 
    glEnableClientState(GL_TEXTURE_COORD_ARRAY); 

    static float rot = 0.0f; 

    glRotatef(rot, 0.0f, 0.0f, 1.0f); 

    //glColor4f(0.0f, 0.0f, 1.0f, 1.0f); 
    glBindTexture(GL_TEXTURE_2D, texture_[0]); 

    GLenum err = glGetError(); 
    if (err != GL_NO_ERROR) 
     printf("Error. glError: 0x%04X\n", err); 

    glVertexPointer(2, GL_FLOAT, 0, pos[0]); 
    glTexCoordPointer(2, GL_FLOAT, 0, black); 
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 

    glVertexPointer(2, GL_FLOAT, 0, pos[1]); 
    glTexCoordPointer(2, GL_FLOAT, 0, black); 
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 

    glVertexPointer(2, GL_FLOAT, 0, pos[2]); 
    glTexCoordPointer(2, GL_FLOAT, 0, black); 
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 

    rot += 0.5f; 

    glDisableClientState(GL_VERTEX_ARRAY); 
    glDisableClientState(GL_TEXTURE_COORD_ARRAY); 
} 

然后最后它调用presentFramebuffer,它将renderBuffer和setup上下文绑定起来。

+0

发布您的纹理加载代码。 – 2010-09-13 23:58:26

+0

我已经根据您的要求添加了纹理加载代码。 – NebulaFox 2010-09-14 09:59:15

回答

1

编辑:我已经做了一些更多的工作,事实证明这是与上下文和缓冲区有关。每当我在启用GL_TEXTURE_2D和GL_BLEND的同时只执行上下文,就像你这样做,不加载纹理。然而,当缓冲区加载完毕并且一切正常时,请执行此操作。


我已经得到了我的纹理绘制。我把所有的代码都拿出来放到自己的文件中。然后,我将再次开始将它拉上一部分,并希望能够让我已经拥有的结构中的所有东西都能够工作。

(目标C)ES1Renderer.h

#import <QuartzCore/QuartzCore.h> 
#import "OpenGLES.h" 

@interface ES1Renderer : UIView { 
@private 
    GLint backingWidth; 
    GLint backingHeight; 
    EAGLContext *context; 

    GLuint viewFramebuffer, viewRenderbuffer; 

    GLuint texture[1]; 

    BOOL animating; 
    BOOL displayLinkSupported; 
    NSInteger animationFrameInterval; 
    // Use of the CADisplayLink class is the preferred method for controlling your animation timing. 
    // CADisplayLink will link to the main display and fire every vsync when added to a given run-loop. 
    // The NSTimer class is used only as fallback when running on a pre 3.1 device where CADisplayLink 
    // isn't available. 
    id displayLink; 
    NSTimer *animationTimer; 
} 

@property (readonly, nonatomic, getter=isAnimating) BOOL animating; 
@property (nonatomic) NSInteger animationFrameInterval; 

- (void) startAnimation; 
- (void) stopAnimation; 

- (void)render; 

@end 

接着ES1Renderer.m

#import "ES1Renderer.h" 


@implementation ES1Renderer 

@synthesize animating; 
@dynamic animationFrameInterval; 

+ (Class)layerClass 
{ 
    return [CAEAGLLayer class]; 
} 

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

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

     if (!context || ![EAGLContext setCurrentContext:context]) 
     { 
      [self release]; 
      return nil; 
     } 

     // Generate buffers 
     glGenFramebuffersOES(1, &viewFramebuffer); 
     glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer); 

     glGenRenderbuffersOES(1, &viewRenderbuffer); 
     glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer); 
     glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, viewRenderbuffer); 


     glMatrixMode(GL_MODELVIEW); 
     glLoadIdentity(); 

     // Disable Depth 
     glDisable(GL_DEPTH_TEST); 

     // Load textures 
     glEnable(GL_TEXTURE_2D); 
     glEnable(GL_BLEND); 
     glBlendFunc(GL_ONE, GL_SRC_COLOR); 

     glGenTextures(1, texture); 

     UIImage *img = [[UIImage alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"colour" ofType:@"png"]]; 

     if (!img) { 
      NSLog(@"Image \"colour.png\" could not be loaded and was not bound"); 
      [self release]; 
      return nil; 
     } 

     CGImageRef cgimage = img.CGImage; 

     float width = CGImageGetWidth(cgimage); 
     float height = CGImageGetHeight(cgimage); 
     CGRect bounds = CGRectMake(0, 0, width, height); 
     CGColorSpaceRef colourSpace = CGColorSpaceCreateDeviceRGB(); 

     void *image = malloc(width * height * 4); 
     CGContextRef imgContext = CGBitmapContextCreate(image, 
                           width, height, 
                           8, 4 * width, colourSpace, 
                           kCGImageAlphaPremultipliedLast); 

     CGColorSpaceRelease(colourSpace); 
     CGContextClearRect(imgContext, bounds); 
     CGContextTranslateCTM (imgContext, 0, height); 
     CGContextScaleCTM (imgContext, 1.0, -1.0); 
     CGContextDrawImage(imgContext, bounds, cgimage); 

     CGContextRelease(imgContext); 

     glBindTexture(GL_TEXTURE_2D, texture[0]); 

     glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); 
     glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); 

     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image); 

     GLenum err = glGetError(); 
     if (err != GL_NO_ERROR) 
      NSLog(@"Error. glError: 0x%04X\n", err); 

     free(image); 
     [img release]; 

     animating = FALSE; 
     displayLinkSupported = FALSE; 
     animationFrameInterval = 1; 
     displayLink = nil; 
     animationTimer = nil; 

     // A system version of 3.1 or greater is required to use CADisplayLink. The NSTimer 
     // class is used as fallback when it isn't available. 
     NSString *reqSysVer = @"3.1"; 
     NSString *currSysVer = [[UIDevice currentDevice] systemVersion]; 
     if ([currSysVer compare:reqSysVer options:NSNumericSearch] != NSOrderedAscending) 
      displayLinkSupported = TRUE; 
    } 

    return self; 
} 

- (void)drawView:(id)sender 
{ 
    [self render]; 

    GLenum err = glGetError(); 
    if (err != GL_NO_ERROR) 
     NSLog(@"Error. glError: 0x%04X\n", err); 
} 

- (void) render 
{ 
    //glDisable(GL_TEXTURE_2D); 

    [EAGLContext setCurrentContext:context]; 
    glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer); 

    static const float textureVertices[] = { 
     -0.5f, -0.33f, 
     0.5f, -0.33f, 
     -0.5f, 0.33f, 
     0.5f, 0.33f, 
    }; 

    static const float textureCoords[] = { 
     0.0f, 0.0f, 
     0.0f, 0.515625f, 
     0.12890625f, 0.0f, 
     0.12890625f, 0.515625f, 
    }; 

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
    glLoadIdentity(); 
    glClearColor(0.5f, 0.5f, 0.5f, 1.0f); 

    glEnableClientState(GL_VERTEX_ARRAY); 
    glEnableClientState(GL_TEXTURE_COORD_ARRAY); 

    glBindTexture(GL_TEXTURE_2D, texture[0]); 

    //glColor4f(0.0f, 0.0f, 0.0f, 1.0f); 

    glVertexPointer(2, GL_FLOAT, 0, textureVertices); 
    glTexCoordPointer(2, GL_FLOAT, 0, textureCoords); 
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 

    glDisableClientState(GL_VERTEX_ARRAY); 
    glDisableClientState(GL_TEXTURE_COORD_ARRAY); 

    glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer); 
    [context presentRenderbuffer:GL_RENDERBUFFER_OES]; 
} 

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

    glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer); 
    [context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:(CAEAGLLayer *)self.layer]; 
    glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, viewRenderbuffer); 

    glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth); 
    glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight); 

    glMatrixMode(GL_PROJECTION); 
    glLoadIdentity(); 
    glViewport(0, 0, backingWidth, backingHeight); 

    glMatrixMode(GL_MODELVIEW); 
    glLoadIdentity(); 

    if(glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES) 
     NSLog(@"failed to make complete framebuffer object %x", glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES)); 
} 

- (void) dealloc 
{ 
    // Tear down GL 
    if (viewFramebuffer) 
    { 
     glDeleteFramebuffersOES(1, &viewFramebuffer); 
     viewFramebuffer = 0; 
    } 

    if (viewRenderbuffer) 
    { 
     glDeleteRenderbuffersOES(1, &viewRenderbuffer); 
     viewRenderbuffer = 0; 
    } 

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

    [context release]; 
    context = nil; 

    displayLink = nil; 
    animationTimer = nil; 

    [super dealloc]; 
} 

- (NSInteger) animationFrameInterval 
{ 
    return animationFrameInterval; 
} 

- (void) setAnimationFrameInterval:(NSInteger)frameInterval 
{ 
    // Frame interval defines how many display frames must pass between each time the 
    // display link fires. The display link will only fire 30 times a second when the 
    // frame internal is two on a display that refreshes 60 times a second. The default 
    // frame interval setting of one will fire 60 times a second when the display refreshes 
    // at 60 times a second. A frame interval setting of less than one results in undefined 
    // behavior. 
    if (frameInterval >= 1) 
    { 
     animationFrameInterval = frameInterval; 

     if (animating) 
     { 
      [self stopAnimation]; 
      [self startAnimation]; 
     } 
    } 
} 

- (void) startAnimation 
{ 
    if (!animating) 
    { 
     if (displayLinkSupported) 
     { 
      // CADisplayLink is API new to iPhone SDK 3.1. Compiling against earlier versions will result in a warning, but can be dismissed 
      // if the system version runtime check for CADisplayLink exists in -initWithCoder:. The runtime check ensures this code will 
      // not be called in system versions earlier than 3.1. 

      displayLink = [NSClassFromString(@"CADisplayLink") displayLinkWithTarget:self selector:@selector(drawView:)]; 
      [displayLink setFrameInterval:animationFrameInterval]; 
      [displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; 
     } 
     else 
      animationTimer = [NSTimer scheduledTimerWithTimeInterval:(NSTimeInterval)((1.0/60.0) * animationFrameInterval) target:self selector:@selector(drawView:) userInfo:nil repeats:TRUE]; 

     animating = TRUE; 
    } 
} 

- (void)stopAnimation 
{ 
    if (animating) 
    { 
     if (displayLinkSupported) 
     { 
      [displayLink invalidate]; 
      displayLink = nil; 
     } 
     else 
     { 
      [animationTimer invalidate]; 
      animationTimer = nil; 
     } 

     animating = FALSE; 
    } 
} 


@end 

只有一个与此代码的问题。它已过时。苹果公司发布了一种新的做事方式,但地狱。有用。

更新: 事实证明,我已经在加载纹理之前设置了上下文。

+1

也许你的意思是你没有在加载纹理之前设置上下文?在我的情况下,我已经在加载我的纹理之前在EAGLView中将setFrameBuffer注释掉了,这会导致纹理呈现白色(可能会被更多的API返回检查!))。 – 2011-06-07 15:44:41