Introduction to the

We learned about texture mapping earlier, we can build a cube with 6 2D textures, and the cube mapping itself is a texture with 6 2D textures, which has the advantage of being indexed/sampled by a direction vector. As long as you are at the center of the cube map, you can sample the cube map using the actual position vector of the cube.

Creating a cube map

Not much different from 2D textures, creating a cube texture is the same as creating a texture, except that our glBindTexture method takes the parameter glES20.gl_TEXTURE_cube_map, and also handles the wrap and filter methods. Unlike 2D textures, it takes six images to set the six sides of the cube, again using glutils.texImage2d, whose target parameters are shown in the following table

Let’s encapsulate the same for creating a cube map as follows:

/** * Cube map * @param Context context * @Param resIds collection, in order: * <ul><li> right {@link GLES20#GL_TEXTURE_CUBE_MAP_POSITIVE_X}</li>* <li> left {@link GLES20#GL_TEXTURE_CUBE_MAP_NEGATIVE_X}</li>* <li> on {@link GLES20#GL_TEXTURE_CUBE_MAP_POSITIVE_Y}</li>* <li> < @link GLES20#GL_TEXTURE_CUBE_MAP_NEGATIVE_Y}</li>* <li> after {@link GLES20#GL_TEXTURE_CUBE_MAP_POSITIVE_Z}</li>* <li> before {@link GLES20#GL_TEXTURE_CUBE_MAP_NEGATIVE_Z}</li></ul>
     * @return int
     */
    public static int createTextureCube(Context context, int[] resIds) {
        if(resIds ! = null && resIds.length >= 6) { int[] texture = new int[1]; Gles20. glGenTextures(1, texture, 0); checkGlError("glGenTexture"); Gles20.glbindtexture (gles20.gl_texture_cube_map, texture[0]); GLES20.glTexParameteri(GLES20.GL_TEXTURE_CUBE_MAP, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR); GLES20.glTexParameteri(GLES20.GL_TEXTURE_CUBE_MAP, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR); GLES20.glTexParameteri(GLES20.GL_TEXTURE_CUBE_MAP, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE); GLES20.glTexParameteri(GLES20.GL_TEXTURE_CUBE_MAP, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);if (OpenGLVersion > 2 && Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
                GLES20.glTexParameteri(GLES20.GL_TEXTURE_CUBE_MAP, GLES30.GL_TEXTURE_WRAP_R, GLES20.GL_CLAMP_TO_EDGE);
            }
 
            Bitmap bitmap;
            final BitmapFactory.Options options = new BitmapFactory.Options();
            options.inScaled = false;
            for (int i = 0; i < resIds.length; i++) {
                bitmap = BitmapFactory.decodeResource(context.getResources(),
                        resIds[i], options);
                if (bitmap == null) {
                    LogUtil.w("Resource ID " + resIds[i] + " could not be decoded.");
                    GLES20.glDeleteTextures(1, texture, 0);
                    return 0;
                }
                GLUtils.texImage2D(GLES20.GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, bitmap, 0);
                bitmap.recycle();
            }
            GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0);
            return texture[0];
        }
        return 0;
    }
Copy the code

The shader code also needs to be modified, we need to use samplerCube to receive our cube map, use textureCube to generate the cube map, and also we need to define the vertex coordinates and texture coordinates of the six sides. The fragment shader code looks like this:

  precision mediump float; varying vec3 TexCoord; Uniform samplerCube Skybox; // Uniform samplerCube Skybox; // The cube texture sampler voidmain() {
      gl_FragColor = textureCube(skybox, TexCoord);
  }

Copy the code

The sky box

Imagine that we create a cube map, and we place the perspective in the middle of the cube map, and we move the perspective as if we were in a cube room looking in all directions. We can in this website (www.custommapmakers.org/skyboxes.ph.) For now, let’s use the following six images to create a cube map:

Then draw a box and place it in our view. The key code is as follows:

    @Override
    public void onDrawFrame(GL10 gl) {
        super.onDrawFrame(gl);
 
        drawTexture();
        GLES20.glDepthFunc(GLES20.GL_LEQUAL);
        drawSkyBox();
        GLES20.glDepthFunc(GLES20.GL_LESS);
    }

Copy the code

The effect is as follows:

We want to move our view, which is a little bit cumbersome with touch events, but here we use the rotation vector function in the sensor that comes with the phone, and we move the phone and we move the view in the sky box. Used in the onSensorChanged getRotationMatrixFromVector converts rotation vector rotation matrix, then calculate can into our Renderer.

Source code address: github.com/jklwan/Open… , you can test the effect. IO /04%20Advanc… learnopengl-cn.github. IO /04%20Advanc… .

If there is insufficient can communicate with each other, read can point a thumbs-up attention.