iPhone and C++ OpenGL programming

27 08 2009

I am currently working in my last big game for the iPhone with so much to do and so few time :P

And during this last months I received many comments about writing a detailed post about C++ programming with OpenGL and the iPhone SDK.

Well… here it is!

I created a new OpenGL ES Application Project within Xcode.

I then added a test C++ class to the project. The trick here is to change the extension of the implementation file from “.cpp” to “.mm”, this way we can freely mix C++ code with ObjectiveC code.

I also renamed the “EAGLView.m” file to “EAGLView.mm” for the same reason. Well, in my project every implementation file ends with “.mm” to avoid headaches!

This is how the test class looks like:

class TestClass : public Singleton<TestClass>
{

    friend class Singleton<TestClass>;

private:

    EAGLContext* m_pContext;
    GLuint m_uiViewRenderbuffer;
    GLuint m_uiViewFramebuffer;
    GLuint m_uiDepthRenderbuffer;

public:

    TestClass(void);

    void Init(EAGLContext* pContext, GLuint renderBuffer, GLuint frameBuffer, GLuint depthBuffer);
    void Cleanup(void);

    void Update(void);

private:

    void BeginRender(void);
    void EndRender(void);

    void DrawSomething(void);

};

As you can see, the class is a singleton for simplicity and convenience.

Then I changed the “createFramebuffer”, “destroyFramebuffer” and “drawView” methods of “EAGLView.mm” in order to call the wrapper methods of our test class.

- (BOOL)createFramebuffer {

    glGenFramebuffersOES(1, &viewFramebuffer);
    glGenRenderbuffersOES(1, &viewRenderbuffer);

    glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
    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);

    if (USE_DEPTH_BUFFER) {
        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;
    }

    TestClass::Instance().Init(context, viewRenderbuffer, viewFramebuffer, depthRenderbuffer);

    return YES;
}
- (void)destroyFramebuffer {

    TestClass::Instance().Cleanup();

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

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

    TestClass::Instance().Update();
}

You can wrap the input methods of “EAGLView.mm” in the same simple way.

And I’m afraid that’s all folks :mrgreen:

You can grab the full source code from here.

Hope this helps!




Ozone Teaser Trailer (iPhone and iPod Touch)

9 07 2009

This fall your iPhone will never be the same…

Get ready for Ozone




iPhone C++ programming

3 12 2008

I am a hardcore C++ fan and I really dislike Objective C.

I decided to take a look to the iPhone SDK and see if I can make some OpenGL programming using pure C++.

I found that it’s really easy to mix both languages in the same project. You can even mix Objective C and C++ code in the same file just by adding the “.mm” extension to your files, instead of “.cpp”.

Using the OpenGL ES example bundled in the SDK I made a wrapper in C++ that receives the iPhone events I need, like input and drawing.

I modified the example so it calls to my wrapper in every drawing and input event and then, the wrapper calls to my pure C++ objects.

I can now concentrate my efforts in writing the logic and drawing methods in pure C++ and see the changes in my iPhone :mrgreen: