Draw your graphics

Now that you have initialized the app, it's time to start coding the main functionality. We'll walk through how the app handles screen events and how to start drawing graphics using OpenGL ES.

In main(), we call the following two functions:

  • The handleScreenEvent() function determines the type of screen event that has occurred and responds accordingly.
  • The render() function draws the square on the screen.

As long as the NAVIGATOR_EXIT event has not occurred, this frame loop continues to execute. The loop calls handleScreenEvent() to handle new events and render() to update the display.

while (!exit_application) {
     //Request and process all available BPS events
     bps_event_t *event = NULL;

    for(;;) {
        if (BPS_SUCCESS != bps_get_event(&event, 0)) {
            fprintf(stderr, "bps_get_event failed\n");
            break;
        }
 
        if (event) {
            int domain = bps_event_get_domain(event);

            if (domain == screen_get_domain()) {
                handleScreenEvent(event);
            } else if ((domain == navigator_get_domain())
                    && (NAVIGATOR_EXIT == bps_event_get_code(event))) {
                exit_application = 1;
            }
        } else {
            break;
        }
    }
    render();
 }

Handle screen events

For all screen events, we extract the screen event from the generic BlackBerry Platform Services event that we received by calling screen_event_get_event().

screen_event_t screen_event = screen_event_get_event(event);

Then we determine the type of screen event that occurred and the position of the event on the screen. Every screen event is associated with a set of properties. You can query these properties by using the screen_get_event_property_iv() function, which is part of screen.h. For more information on event structure and other properties that can be queried in this context, refer to the Event types in the screen.h library. Here, we determine the type of screen event and store it in screen_val.

int screen_val;
screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_TYPE, &screen_val);

If the event is a touch screen event, determine the type of touch screen event that occurred. Touch screen events have codes associated with them, which are listed in the screen.h library.

switch (screen_val) {

    case SCREEN_EVENT_MTOUCH_TOUCH:
    case SCREEN_EVENT_MTOUCH_MOVE:
    case SCREEN_EVENT_MTOUCH_RELEASE:

break;
}

Although this project template does not perform any actions for the different types of events, you can add code here that is appropriate for your app. Now that the framework is in place, you can try experimenting with it on your device or simulator before moving on.

Render the square

It's useful to organize your per-frame OpenGL ES code into a single function. We've called ours render() and we do the following:

Invoke glClear(). This function simply clears the color and depth buffers.
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

Enable GL_VERTEX_ARRAY state and provide an array of vertices that describes our simple square.

glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(2, GL_FLOAT, 0, vertices);

Similarly, enable GL_COLOR ARRAY state and provide an array that defines a color of each of our vertices.

glEnableClientState(GL_COLOR_ARRAY);
glColorPointer(4, GL_FLOAT, 0, colors);

Add a small rotation with respect to the vertical axis and then render the square. Our square rotates gradually on every frame.

glRotatef(0.5f, 0.0f, 1.0f, 0.0f);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

Although it's not necessary to disable these client states in our specific sample, it's a good practice to disable all client states that are used by the current rendering logic. This simple step can save you a lot of time in front of the debugger because EGL code is typically difficult to debug.

glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);

After the frame is complete, it must be displayed on the screen. We invoke bbutil_swap() because all our EGL interactions are handled by bbutil.h (which simply calls eglSwapBuffers with an error check).

bbutil_swap();

Clean up your app

After the user triggers the app to close (using the navigator), the NAVIGATOR_EXIT event is generated. A short time is given for your app to exit cleanly, but if it does not, the OS terminates the app's process.

To perform a clean exit, we add termination code to the end of main.c. This code stops screen events, shuts down the BlackBerry Platform Services library, cleans up EGL artifacts, and destroys the screen context.

screen_stop_events(screen_cxt);
bps_shutdown();
bbutil_terminate();
screen_destroy_context(screen_cxt);
return 0;

We're finished! Build and run the app to see the result.

You can now extend this app to change the graphics, change the screen, and handle touch events to add different features to your app.

Last modified: 2015-03-31



Got questions about leaving a comment? Get answers from our Disqus FAQ.

comments powered by Disqus