DEV Community

Cover image for Updating the UI for orientation changes with C++ android OpenGL | Android game dev
Tristan Elliott
Tristan Elliott

Posted on

Updating the UI for orientation changes with C++ android OpenGL | Android game dev

Table of contents

  1. Should my game allow for orientation changes?
  2. When you don't adjust for orientation changes
  3. What is the UI in a C++ game
  4. Renderer

My app on the Google play store

  • MINI GAME VERSION NOW LIVE!!!!
  • The app

My app's GitHub code

Resources:

Should my game allow for orientation changes?

  • The honest answer is probably not. If we look an any large mobile game(100 million+ downloads), we can notice that most of them are either locked into landscape or portrait mode. But lets be honest here... the games we build probably aren't going to get a 100 million downloads. So our games should adjust for orientation changes. It helps with user experience and its a fun little challenge

When you don't adjust for orientation changes

  • Below is the UI for my little Dino Run clone game
  • Portrait mode:

Portrait UI

  • Landscape mode with only one square adjusted to show the problems:

Landscape UI

  • As you can see if the squares are not adjusted for the orientation change, they will become distorted.

What code to call for orientation changes

What is the UI in a C++ game

  • The UI is represented entirely in a Vector that OpenGL uses to create triangles and will be updated during an orientation change:

class TransformShader {

private:
    std::vector<GLfloat> m_squareVertices = {
            -0.800f, -0.0375f, -0.650f, -0.0375f, -0.650f,  0.0375f,
            -0.800f, -0.0375f, -0.650f,  0.0375f, -0.800f,  0.0375f,
            0.85f, -0.0375f, 1.0f, -0.0375f, 1.0f,  0.0375f,
            0.85f, -0.0375f, 1.0f,  0.0375f, 0.85f,  0.0375f
    };
    GLuint simpleTriangleProgram;
    GLuint vPosition;
    bool showCoin = false;



}

Enter fullscreen mode Exit fullscreen mode
  • The vector should actually be created and updated dynamically. The static definition that I have above will lead to problems(problems I have delt with). The static definition above is a legacy that I inherited from following THIS tutorial. We will talk more about fixing its issues in the next section of this blog post

Renderer

  • My game's own Renderer
  • During an orientation change the Renderer is going to call onSurfacechange(). When that function is called we need to remove any old vectors and create ones adjusted for the screen's aspect ratio

  • So when the orientation changes we need to do two things:

    • 1) Clear existing Vectors : IF YOU DO NOT CLEAR OUT THE EXISTING VECTORS THE VERTICIES WILL STACK ONTOP OF EACHOTHER MAKING THE APSECT RATION APPEAR TO NOT CHANGE AND LEAD TO PERFORMANCE ISSUES(the issue I talked about earlier)
    • 2) Add new ones adjusted for aspect ratio
  • Here is my actual C++ code to deal with the orientation changes:

bool TransformShader::setupGraphics(int w, int h) {
    simpleTriangleProgram = createProgram(m_glVertexShader, m_glFragmentShader);
    if (!simpleTriangleProgram) {
        LOGE("Could not create program");
        return false;
    }
    float aspectRatio = (float)w / (float)h;
    LOGI("setupGraphicsTestingRatio", "aspectRatio--> %f",aspectRatio);

    if(w>h){//determine if portrait or landscape
        float scaleFactor = 0.5f; // reduction
        // width of the first square
        float squareWidth = (-0.650f - (-0.800f)) / aspectRatio * scaleFactor;

        // Shift the first square to the left boundary (-1.0)y
        float leftBoundary = -1.0f;
        float newLeftX = leftBoundary;
        float newRightX = leftBoundary + squareWidth;

        // Move the square 20% to the right
        float shiftAmount = 0.4f;
        newLeftX += shiftAmount;
        newRightX += shiftAmount;

        std::vector<GLfloat> newOneToEdit = {
                // First square shifted 20% to the right
                newLeftX, (-0.0375f), // Bottom-left vertex
                newRightX, (-0.0375f), // Bottom-right vertex
                newRightX, (0.0375f), // Top-right vertex
                newLeftX, (-0.0375f), // Bottom-left vertex (repeated for the second triangle)
                newRightX, (0.0375f), // Top-right vertex
                newLeftX, (0.0375f), // Top-left vertex

                // Second square not shifted
                (0.85f/aspectRatio) * scaleFactor, (-0.0375f), (1.0f/aspectRatio) * scaleFactor, (-0.0375f), (1.0f/aspectRatio) * scaleFactor, ( 0.0375f),
                (0.85f/aspectRatio) * scaleFactor, (-0.0375f), (1.0f/aspectRatio) * scaleFactor,  (0.0375f), ( 0.85f/aspectRatio) * scaleFactor,  (0.0375f)
        };
        m_squareVertices.clear();
        m_squareVertices.insert(m_squareVertices.end(), newOneToEdit.begin(), newOneToEdit.end());

    }else{
        // vertical display
        std::vector<GLfloat> newOneToEdit = {
                -0.800f, (-0.0375f) , -0.650f, (-0.0375f), -0.650f,  (0.0375f) ,
                -0.800f, (-0.0375f) , -0.650f,  (0.0375f) , -0.800f,  (0.0375f) ,
                0.85f, (-0.0375f) , 1.0f, (-0.0375f), 1.0f, ( 0.0375f) ,
                0.85f, (-0.0375f) , 1.0f,  (0.0375f), 0.85f,  (0.0375f)
        };
        m_squareVertices.clear();
        m_squareVertices.insert(m_squareVertices.end(), newOneToEdit.begin(), newOneToEdit.end());
    }


    vPosition = glGetAttribLocation(simpleTriangleProgram, "vPosition");
    glViewport(0, 0, w, h);

    // Set up orthographic projection matrix


    glUseProgram(simpleTriangleProgram);


    LOGI("setupGraphicsTesting", "-----------------------END-----------------------------");
    return true;
}

Enter fullscreen mode Exit fullscreen mode
  • The code its self is really not that important(its yucky but it works). What we should focus on is that to determine if we are in landscape mode. I checked if the w(width) is greater than h(height). If that is true then we have to adjust with the aspect ration (width/height) and apply landscape specific adjustments for the layout

Conclusion

  • Thank you for taking the time out of your day to read this blog post of mine. If you have any questions or concerns please comment below or reach out to me on Twitter.

Top comments (1)

Collapse
 
theplebdev profile image
Tristan Elliott

I have hidden bot comments

Some comments may only be visible to logged-in visitors. Sign in to view all comments. Some comments have been hidden by the post's author - find out more

👋 Kindness is contagious

DEV shines when you're signed in, unlocking a customized experience with features like dark mode!

Okay