2012-06-15 62 views
1

我是OpenGL的完全noob,我一直試圖讓這個簡單的代碼在iphone模擬器上渲染,它啓動正常,飛濺屏幕顯示,然後...什麼都沒有...只是黑暗,我不能告訴我失蹤,可以請一些人幫忙嗎? 我還沒有做任何旋轉,但等待,看看我先渲染了什麼,然後繼續旋轉,然後......似乎無法在模擬器上使用opengl es 1.1渲染

我正在使用Xcode 4.2,如果有問題的話。

這裏是我的代碼:

IRenderEngine.cpp

#ifndef HelloArrow_IRenderingEngine_hpp 
#define HelloArrow_IRenderingEngine_hpp 

#import <OpenGLES/ES1/gl.h> 
#import <OpenGLES/ES1/glext.h> 

//Physical Orientation of a handheld device, equivalent to UIDeviceOrientation 
enum DeviceOrientation{ 
DeviceOrientationUnknown, 
DeviceOrientationPortrait, 
DeviceOrientationPortraitUpsideDown, 
DeviceOrientationLandscapeLeft, 
DeviceOrientationLandscapeRight, 
DeviceOrientationFaceUp, 
DeviceOrientationFaceDown 
}; 

//Creates an instance of a renderer and sets up various openGL state 
struct IRenderingEngine *CreateRenderer1(); 

//Interface to OpenGL ES renderer; consumed by GLView 
struct IRenderingEngine{ 
virtual void Initialize(int width, int height)=0; 
virtual void Render() = 0; 
virtual void UpdateAnimation(float timeStep) = 0; 
virtual void OnRotate(DeviceOrientation newOrientation) = 0; 
virtual ~IRenderingEngine(){}; 
}; 

RenderingEngine.cpp

#include <iostream> 

#include <OpenGLES/ES1/gl.h> 

#include <OpenGLES/ES1/glext.h> 

#include "IRenderingEngine.hpp" 


class RenderingEngine1 : public IRenderingEngine{ 
public: 
RenderingEngine1(); 
void Initialize(int width, int height); 
void Render(); 
void UpdateAnimation(float timeStep){} 
void OnRotate(DeviceOrientation newOrientation){} 
private: 
GLuint m_framebuffer; 
GLuint m_renderbuffer; 
}; 

IRenderingEngine * CreateRenderer1(){ 
return new RenderingEngine1; 
} 

struct Vertex { 
float Position[2]; 
float Color[4]; 
}; 

//Define the position and colors of the 2 triangles 
const struct Vertex Vertices[6] = { 
{{-0.5, -0.866},{1, 1, 0.5f, 1}}, 
{{0.5, -0.866},{1,1,0.5f,1}}, 
{{0,1},{1,1,0.5f,1}}, 
{{-0.5, -0.866},{0.5f,0.5f,0.5f}}, 
{{0.5, -0.866},{0.5f,0.5f,0.5f}}, 
{{0,-0.4f},{0.5f,0.5f,0.5f}} 
}; 
RenderingEngine1::RenderingEngine1(){ 
glGenRenderbuffersOES(1, &m_renderbuffer); 
glBindRenderbufferOES(GL_RENDERBUFFER_OES, m_renderbuffer); 
} 

void RenderingEngine1::Initialize(int width, int height){ 
//Create the framebuffer object and attache the renderbuffer  
glGenFramebuffersOES(1, &m_framebuffer); 
glBindFramebufferOES(GL_FRAMEBUFFER_OES, m_framebuffer); 

glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES,  GL_RENDERBUFFER_OES, m_renderbuffer); 

glViewport(0, 0, width, height); 

glMatrixMode(GL_PROJECTION); 

glLoadIdentity(); 

const float maxX = 2; 
const float maxY = 3; 

glOrthof(-maxX,+maxX,-maxY,+maxY,-1,1); 


glMatrixMode(GL_MODELVIEW); 

glLoadIdentity(); 

} 

void RenderingEngine1::Render(){ 

glClearColor(0.5f, 0.5f, 0.5f, 1); 


glClear(GL_COLOR_BUFFER_BIT); 


glEnableClientState(GL_VERTEX_ARRAY); 


glEnableClientState(GL_COLOR_ARRAY); 
glVertexPointer(2,GL_FLOAT,4,&Vertices[0].Position); 


glColorPointer(4,GL_FLOAT,2,&Vertices[0].Color); 

GLsizei vertexcount = sizeof(Vertices)/sizeof(Vertex); 
glDrawArrays(GL_TRIANGLES, 0, vertexcount); 
glFlush(); 
glDisableClientState(GL_VERTEX_ARRAY); 
glDisableClientState(GL_COLOR_ARRAY); 
} 

GLView.h

#import "IRenderingEngine.hpp" 
#import <UIKit/UIKit.h> 
#import <OpenGLES/EAGL.h> 
#import <QuartzCore/QuartzCore.h> 


@interface GLView : UIView 
{ 
EAGLContext *m_context; 
struct IRenderingEngine *m_renderingEngine; 
float m_timestamp; 
} 

-(void) drawView:(CADisplayLink*) displayLink; 
-(void) didRotate: (NSNotification*) notification; 

@end 

GLView.mm

#import <OpenGLES/EAGLDrawable.h> 
#import <OpenGLES/ES1/gl.h> //<- for GL_RENDERBUFFER only 
#import "GLView.h" 
#import "mach/mach_time.h" 
#import "IRenderingEngine.hpp" 

@implementation GLView 

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

- (id)initWithFrame:(CGRect)frame 
{ 
self = [super initWithFrame:frame]; 
if (self) { 
    // Initialization code 
    CAEAGLLayer *eaglLayer = (CAEAGLLayer*) super.layer; 
    eaglLayer.opaque = YES; 
    m_context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1]; 

    if(!m_context || ![EAGLContext setCurrentContext:m_context]){ 
     return nil; 
    } 

    m_renderingEngine = CreateRenderer1();  

    [m_context renderbufferStorage:GL_RENDERBUFFER fromDrawable:eaglLayer]; 

    m_renderingEngine->Initialize(CGRectGetWidth(frame), CGRectGetHeight(frame)); 
    [self drawView:nil]; 
    m_timestamp = CACurrentMediaTime(); 
    CADisplayLink *displayLink; 
    displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(drawView:)]; 
    [displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; 
    [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications]; 
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didRotate:) name:UIDeviceOrientationDidChangeNotification object:nil]; 

} 
return self; 
} 

/* 
// Only override drawRect: if you perform custom drawing. 
// An empty implementation adversely affects performance during animation. 
- (void)drawRect:(CGRect)rect 
{ 
// Drawing code 
} 
*/ 

-(void) drawView: (CADisplayLink *) displayLink{ 

if(displayLink != nil){ 
    float elapsedseconds = [displayLink timestamp] - m_timestamp; 
    m_timestamp = [displayLink timestamp]; 
    m_renderingEngine->UpdateAnimation(elapsedseconds); 
} 
m_renderingEngine->Render(); 

[m_context presentRenderbuffer:GL_RENDERBUFFER_OES]; 

} 

-(void) dealloc{ 
if([EAGLContext currentContext] == m_context) 
    [EAGLContext setCurrentContext:nil]; 
m_renderingEngine = nil; 
m_timestamp = nil; 
} 

-(void) didRotate:(NSNotification *)notification{ 
UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation]; 
m_renderingEngine->OnRotate((DeviceOrientation) orientation); 
[self drawView:nil]; 
} 

@end 

AppDelegate.h

#import <UIKit/UIKit.h> 
#import "GLView.h" 

@class ViewController; 

@interface AppDelegate : UIResponder <UIApplicationDelegate>{ 
UIWindow *m_window; 
GLView *m_view; 
} 

@property (strong, nonatomic) IBOutlet UIWindow *m_window; 

@end 

,最後,AppDelegate.mm

#import "AppDelegate.h" 
#import "OpenGLVC.h" 
#import <UIKit/UIKit.h> 

@implementation AppDelegate 

@synthesize m_window = _window; 

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 
{ 
CGRect screenBounds = [[UIScreen mainScreen] bounds]; 
self.m_window = [[UIWindow alloc] initWithFrame:screenBounds]; 
m_view = [[GLView alloc] initWithFrame:screenBounds]; 
[m_window addSubview:m_view]; 
[application setStatusBarHidden:YES withAnimation:UIStatusBarAnimationNone]; 
OpenGLVC *oglvc = [[OpenGLVC alloc] init]; 
self.m_window.rootViewController = oglvc; 
// Override point for customization after application launch. 
[self.m_window makeKeyAndVisible]; 
return YES; 
} 

- (void)applicationWillResignActive:(UIApplication *)application 
{ 
/* 
Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 
Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 
*/ 
} 

- (void)applicationDidEnterBackground:(UIApplication *)application 
{ 
/* 
Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 
If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 
*/ 
} 

- (void)applicationWillEnterForeground:(UIApplication *)application 
{ 
/* 
Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 
*/ 
} 

- (void)applicationDidBecomeActive:(UIApplication *)application 
{ 
/* 
Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 
*/ 
} 

- (void)applicationWillTerminate:(UIApplication *)application 
{ 
/* 
Called when the application is about to terminate. 
Save data if appropriate. 
See also applicationDidEnterBackground:. 
*/ 
} 

@end 
+0

應該不是你的'm_view'是'OpenGLVC'控制器的主要觀點,而不是添加到應用程序的窗口?查看http://developer.apple.com/library/ios/DOCUMENTATION/UIKit/Reference/UIWindow_Class/UIWindowClassReference/UIWindowClassReference.html#//apple_ref/occ/instp/UIWindow/rootViewController。目前,您正在將'm_view'添加到應用程序主窗口,然後將'OpenGLVC'指定爲窗口的根視圖控制器,該視圖控制器使用該視圖控制器的視圖作爲主窗口視圖。 – Rog

+0

@Rog謝謝,一旦我將GLView分配給OpenGLVC,它(視圖)應該作爲窗口的子視圖隱式添加,它使它運行良好並顯示我想要的所有內容。我認爲,在這種情況下,VC可以用於任何目的,所以我創建了它,所以我沒有看到任何問題,因爲UIView對象也不是UiResponder(就像VC一樣)。那麼,我想說的是謝謝,看起來像View/View Controller問題比OpenGL更多。再次感謝。 – RNS

回答

0

嘗試改變

glVertexPointer(2,GL_FLOAT,4,&Vertices[0].Position); 
glColorPointer(4,GL_FLOAT,2,&Vertices[0].Color); 

glVertexPointer(2,GL_FLOAT,sizeof(Vertex),&Vertices[0].Position); 
glColorPointer(4,GL_FLOAT,sizeof(Vertex),&Vertices[0].Color); 

這兩個函數中的第三個參數應該是跨度,即Vertices [0] .Position和Vertices [1] .Position之間的字節偏移量的差異。

換句話說,如果你站在Vertices [i] .Position並花了一個長的步幅,然後站在Vertices [i + 1] .Position,你的步幅必須以字節爲單位要多長時間(不漂浮)。它是而不是你必須跳過從Vertices [i] .Position結束到Vertices [i + 1] .Position開始的間隙。

此外,步幅總是以字節表示,而不是浮點數或整數。

參見:

http://www.opengl.org/sdk/docs/man/xhtml/glVertexPointer.xml

http://www.opengl.org/sdk/docs/man/xhtml/glColorPointer.xml

+0

謝謝,我已經設置了這種方式(與sizeof)之前...我只是擺弄代碼,看看有什麼作品(是的,我完全腦子裏),但是,是的,它不會工作如果我沒有把它改回sizeof(頂點),我輸入的數字是完全錯誤的!感謝您的關注。如果沒有gl [Vertex && Color]指針()參數的改變,我對View Controller所做的工作就沒有幫助。非常感謝。 – RNS