Dick bowler
Dick bowler

Reputation: 11

iOS - zoom only part of display using openGL ES

I'm working on a level builder app to build content for a game. Part of the iPad screen is a dedicated control panel, while the rest is a graphical representation of the level being built. I need to zoom the level area in and out without affecting the control panel. I'm using openGL ES for rendering. Can anyone give me some pointers here? Can I split the screen with different viewports and so just scale one?

Upvotes: 1

Views: 881

Answers (2)

datenwolf
datenwolf

Reputation: 162327

The trick is to understand that OpenGL is a state machine and there is no such thing like "global initialization". As long as you follow the badly written tutorials and have your projection matrix setup in the window resize handler you'll be stuck. What you actually do is something like this:

void render_perspective_scene(void);

void render_ortho_scene(void);

void render_HUD();

void display()
{
    float const aspect = (float)win_width/(float)win_height;

    glViewport(0,0,win_width,win_height);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glFrustum(-aspect*near/lens, aspect*near/lens, -near/lens, near/lens, near, far);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    render_perspective_scene();

    glEnable(GL_SCISSOR_TEST);
    // just clear the depth buffer, so that everything that's
    // drawn next will overlay the previously rendered scene.
    glClear(GL_DEPTH_BUFFER_BIT);
    glViewport(ortho_x, ortho_y, ortho_width, ortho_height);
    glScissor(ortho_x, ortho_y, ortho_width, ortho_height);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(-aspect*scale, aspect*scale, -scale, scale, 0, 1);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    render_ortho_scene();

    // Same for the HUD, only that we render
    // that one in pixel coordinates.
    glViewport(hud_x, hud_y, hud_width, hud_height);
    glScissor(hud_x, hud_y, hud_width, hud_height);
    glClear(GL_DEPTH_BUFFER_BIT);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(0, win_width, 0, win_height, 0, 1);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    render_HUD();
}

The important part is, that you set the viewport/scissor and the projection within the drawing handler prior to rendering that sub-part.

Upvotes: 2

Nicol Bolas
Nicol Bolas

Reputation: 474336

If you're rendering with OpenGL ES (presumably 2.0), then you have full control over the scaling of what you render. You decide where the scale gets applied, and you decide how things are rendered.

I'd guess your code currently looks a bit like this.

Get view scale
Apply view scale to view matrix
Render level
Render control panel

When it should look like this.

Render control panel
Get view scale
Apply view scale to view matrix
Render level

The matrices (or whatever transformation stuff you have) you use for transforming the level should not be used for transforming the control panel.

Upvotes: 1

Related Questions