2010-11-25 42 views
1

我與OpenGL ES的播放(2.0)應用程序(IOS)中的XCode的源代碼,並試圖讓在Z多彩格移動的座標,所以我試圖從(iOS)OpenGL ES(2.0)應用程序,如何移動Z中的對象?

gl_Position.y改變shader代碼+ = sin(translate)/ 2.0;

to

gl_Position.z + = sin(translate)/ 2.0; 沒有成功。

廣場根本不動。 它在X和Y中移動得很好...... 初始化OpenGL時是否需要激活一些選項?謝謝!

更新: 我已經上傳了一個例子。這大致是XCode生成的OpenGL ES模板,我只是在Shader.vsh中添加了調用來創建深度緩衝區,並將gl_Position.x添加到gl_Position.z + = sin(translate)/ 2.0f。

我希望在Z座標上看到正方形的正方形移動,但它不會。要麼它保持不變,或者如果我乘以sin(),它會在一個循環中出現和消失。

如果有人能幫助我,我會非常感激,因爲真誠,我不知道自己能做什麼,相信我我試過很多...

來源是一個zip在:http://cl.ly/24240x2D1t2A3I0c1l1P

謝謝!

回答

2

您正在查看的示例沒有深度緩衝區和用於2D GL的透視矩陣。相反,請看aurioTouch示例。在EAGLView類中,您會注意到一個實現深度緩衝區的選項。這兩個組合(自aurioTouch不實現着色器)應該有更好的理解

我認爲您的方法中操作的順序造成的問題。 這是我在我的應用「動態效果凸輪」哪個地方直播相機作爲GL紋理形狀上使用的代碼:

#define DEGREES_TO_RADIANS(__ANGLE__) ((__ANGLE__)/180.0 * M_PI) 



@interface GLView : UIView 
    { 
@private 
    /* The pixel dimensions of the backbuffer */ 
    GLint backingWidth; 
    GLint backingHeight; 

    EAGLContext *context; 

    /* OpenGL names for the renderbuffer and framebuffers used to render to this view */ 
    GLuint viewRenderbuffer; 
    GLuint viewFramebuffer; 
    GLuint depthRenderbuffer; 

    /* OpenGL name for the sprite texture */ 
    GLuint spriteTexture; 
    } 

@property (readonly) GLint backingWidth; 
@property (readonly) GLint backingHeight; 
@property (readonly) EAGLContext *context; 


- (void) drawView; 
- (BOOL) createFramebuffer; 
- (void) destroyFramebuffer; 
+ (UIImage *) snapshot:(GLView *)eaglview; 

@end 




@implementation GLView 


@synthesize backingWidth; 
@synthesize backingHeight; 
@synthesize context; 


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



- (id)init 
    { 
    self = [[super init] initWithFrame:CGRectMake(0.0, 0.0, 480.0, 640.0)];  // size of the camera image being captures 

    if (self==nil) 
     return self; 


    // Set Content Scaling 
    // 
    if (HIRESDEVICE) 
     { 
     self.contentScaleFactor = (CGFloat)2.0; 
     } 

    // Get our backing layer 
    // 
    CAEAGLLayer *eaglLayer = (CAEAGLLayer*) self.layer; 

    // Configure it so that it is opaque, does not retain the contents of the backbuffer when displayed, and uses RGBA8888 color. 
    // 
    eaglLayer.opaque = YES; 

    eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys: 
             [NSNumber numberWithBool:FALSE], kEAGLDrawablePropertyRetainedBacking, 
             kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat, 
             nil]; 

    // Create our EAGLContext, and if successful make it current and create our framebuffer. 
    // 
    context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1]; 

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

    // Final View Settings 
    // 
    [self setOpaque:YES]; 
    self.multipleTouchEnabled = YES; 
    self.backgroundColor = [UIColor clearColor]; 

    [EAGLContext setCurrentContext:context]; 

    glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer); 
    glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer); 

    glMatrixMode(GL_PROJECTION); 
    glLoadIdentity(); 

    GLfloat zNear = 1.0; 
    GLfloat zFar = 1000.0; 
    GLfloat fieldOfView = 90;  // Lens Angle of View 
    GLfloat size = zNear * tanf(DEGREES_TO_RADIANS(fieldOfView)/2.0); 
    CGRect rect = CGRectMake((CGFloat)0.0, (CGFloat)0.0, backingWidth, backingHeight); 

    glFrustumf(-size, size, -size/(rect.size.width/rect.size.height), size/(rect.size.width/rect.size.height), zNear, zFar); 

    glViewport(0, 0, backingWidth, backingHeight); 

    glClearColor(0.0f, 0.0f, 0.0f, 0.0f); 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

    glEnable(GL_DEPTH_TEST); 
    glDepthFunc(GL_LESS); 
    glEnable(GL_MULTISAMPLE); 
    glEnable(GL_LINE_SMOOTH); 
    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); 
    glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); 
    glHint(GL_POINT_SMOOTH_HINT, GL_NICEST); 
    glDisable(GL_ALPHA_TEST); 

    // Turn Translucent Textures: OFF 
    // 
    glDisable(GL_BLEND); 

// // Turn Translucent Textures: ON 
// // 
// glEnable(GL_BLEND); 
// glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); 

    return self; 
    } 



- (void) drawView 
    { 
    [context presentRenderbuffer:GL_RENDERBUFFER_OES]; 
    } 




- (BOOL)createFramebuffer 
    { 
    // Generate IDs for a framebuffer object and a color renderbuffer 
    // 
    glGenFramebuffersOES(1, &viewFramebuffer); 
    glGenRenderbuffersOES(1, &viewRenderbuffer); 

    glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer); 
    glBindRenderbufferOES(GL_RENDERBUFFER_OES, 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 whereever the layer is (which corresponds with our view). 
    // 
    [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); 

    // If this app uses a depth buffer, we'll create and attach one via another renderbuffer. 
    // 
    if (YES) 
     { 
     glGenRenderbuffersOES(1, &depthRenderbuffer); 
     glBindRenderbufferOES(GL_RENDERBUFFER_OES, depthRenderbuffer); 
     glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_DEPTH_COMPONENT16_OES, backingWidth, backingHeight); 
     glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, depthRenderbuffer); 
     } 

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

    return YES; 
    } 


- (void) destroyFramebuffer 
    { 
    glDeleteFramebuffersOES(1, &viewFramebuffer); 
    viewFramebuffer = 0; 

    glDeleteRenderbuffersOES(1, &viewRenderbuffer); 
    viewRenderbuffer = 0; 

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




+ (UIImage *) snapshot:(GLView *)eaglview 
    { 
    NSInteger x = 0; 
    NSInteger y = 0; 
    NSInteger width = [eaglview backingWidth]; 
    NSInteger height = [eaglview backingHeight]; 
    NSInteger dataLength = width * height * 4; 

// Need to do this to get it to flush before taking the snapshit 
// 
    NSUInteger i; 
    for (i=0; i<100; i++) 
     { 
     glFlush(); 
     CFRunLoopRunInMode(kCFRunLoopDefaultMode, (float)1.0/(float)60.0, FALSE); 
     } 

    GLubyte *data = (GLubyte*)malloc(dataLength * sizeof(GLubyte)); 

    // Read pixel data from the framebuffer 
    // 
    glPixelStorei(GL_PACK_ALIGNMENT, 4); 
    glReadPixels(x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, data); 

    // Create a CGImage with the pixel data 
    // If your OpenGL ES content is opaque, use kCGImageAlphaNoneSkipLast to ignore the alpha channel 
    // otherwise, use kCGImageAlphaPremultipliedLast 
    // 
    CGDataProviderRef ref = CGDataProviderCreateWithData(NULL, data, dataLength, NULL); 
    CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB(); 
    CGImageRef iref = CGImageCreate(width, height, 8, 32, width * 4, colorspace, kCGBitmapByteOrder32Big | kCGImageAlphaPremultipliedLast, ref, NULL, true, kCGRenderingIntentDefault); 

    // OpenGL ES measures data in PIXELS 
    // Create a graphics context with the target size measured in POINTS 
    // 
    NSInteger widthInPoints; 
    NSInteger heightInPoints; 

    if (NULL != UIGraphicsBeginImageContextWithOptions) 
     { 
     // On iOS 4 and later, use UIGraphicsBeginImageContextWithOptions to take the scale into consideration 
     // Set the scale parameter to your OpenGL ES view's contentScaleFactor 
     // so that you get a high-resolution snapshot when its value is greater than 1.0 
     // 
     CGFloat scale = eaglview.contentScaleFactor; 
     widthInPoints = width/scale; 
     heightInPoints = height/scale; 
     UIGraphicsBeginImageContextWithOptions(CGSizeMake(widthInPoints, heightInPoints), NO, scale); 
     } 
    else 
     { 
     // On iOS prior to 4, fall back to use UIGraphicsBeginImageContext 
     // 
     widthInPoints = width; 
     heightInPoints = height; 
     UIGraphicsBeginImageContext(CGSizeMake(widthInPoints, heightInPoints)); 
     } 

    CGContextRef cgcontext = UIGraphicsGetCurrentContext(); 

    // UIKit coordinate system is upside down to GL/Quartz coordinate system 
    // Flip the CGImage by rendering it to the flipped bitmap context 
    // The size of the destination area is measured in POINTS 
    // 
    CGContextSetBlendMode(cgcontext, kCGBlendModeCopy); 
    CGContextDrawImage(cgcontext, CGRectMake(0.0, 0.0, widthInPoints, heightInPoints), iref); 

    // Retrieve the UIImage from the current context 
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); // autoreleased image 

    UIGraphicsEndImageContext(); 

    // Clean up 
    free(data); 
    CFRelease(ref); 
    CFRelease(colorspace); 
    CGImageRelease(iref); 

    return image; 
    } 


@end 
+0

作爲對此的擴展:您現在幾乎肯定想要堅持ES 1.x。這保留了經典的OpenGL矩陣堆棧,使您可以輕鬆執行這類操作。對於ES 2.x,因爲現在每個階段都是非常開放的,所以你必須在很大程度上爲自己處理3d數學。 – Tommy 2010-11-25 20:40:01

+2

@up - 那有什麼問題?更多的代碼,是的,但更多的控制。在像OpenGL這樣的低級API中編程3D圖形應該意味着可編程管線時代的「大量3D數學」......我強烈建議不要在學習現代技術時學習舊技術。 – Kos 2010-11-25 22:22:23

0
// Create default framebuffer object. 
    glGenFramebuffers(1, &defaultFramebuffer); 
    glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebuffer); 

    // Create color render buffer and allocate backing store. 
    glGenRenderbuffers(1, &depthRenderbuffer); <---- 
    glGenRenderbuffers(1, &colorRenderbuffer); 

    glBindRenderbuffer(GL_RENDERBUFFER, depthRenderbuffer); <---- 
    glBindRenderbuffer(GL_RENDERBUFFER, colorRenderbuffer); 

    [context renderbufferStorage:GL_RENDERBUFFER fromDrawable:(CAEAGLLayer *)self.layer]; 

    glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &framebufferWidth); 
    glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &framebufferHeight); 

    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, framebufferWidth, framebufferHeight); <---- 

    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRenderbuffer); 
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthRenderbuffer); <---- 

我添加了我的代碼(... < ----),現在我得到一個粉紅色的屏幕(哈哈)。有任何想法嗎?這真令人沮喪。我不應該在setFrame .. presentFrame中做些什麼..?