Привет, добавь в следующем коде в шейдер квадрат, который будет под отрисовывающейся фигурой и текстура ему будет задана u_texture1:
internal class MyRenderer(var c: Context) : GLSurfaceView.Renderer {
    private val texture = IntArray(2)
    private val x_camera: Float
    private val y_camera: Float
    private val z_camera: Float
    private val x_light_position = 5f
    private val y_light_position = 30f
    private val z_light_position = 5f
    private val model_matrix: FloatArray
    private val view_matrix: FloatArray
    private val model_view_matrix: FloatArray
    private val projection_matrix: FloatArray
    private val model_view_projection_matrix: FloatArray
    private val max_size_x = 70
    private val max_size_z = 60
    private val size_index: Int
    private val x0 = -1.3f
    private val z0 = -1.5f
    private val dx = 0.05f
    private val dz = 0.05f
    private val x: FloatArray
    private val y: Array<FloatArray>
    private val z: FloatArray
    private val vertexes: FloatArray
    private val normales_x: Array<FloatArray>
    private val normales_y: Array<FloatArray>
    private val normales_z: Array<FloatArray>
    private val normales: FloatArray
    private val vertexes_buffer: FloatBuffer
    private val normales_buffer: FloatBuffer
    private val index_buffer: ShortBuffer
    private var m_shader: Shader? = null

    init {
        model_matrix = FloatArray(16)
        view_matrix = FloatArray(16)
        model_view_matrix = FloatArray(16)
        projection_matrix = FloatArray(16)
        model_view_projection_matrix = FloatArray(16)
        Matrix.setIdentityM(model_matrix, 0)
        x_camera = -1.0f
        y_camera = 6.0f
        z_camera = 0.0f
        Matrix.setLookAtM(view_matrix, 0, x_camera, y_camera, z_camera, 0f, 0.0f, 0f, 0f, 1f, 0f)
        Matrix.multiplyMM(model_view_matrix, 0, view_matrix, 0, model_matrix, 0)
        x = FloatArray(max_size_x + 1)
        z = FloatArray(max_size_z + 1)
        y = Array(max_size_z + 1) { FloatArray(max_size_x + 1) }
        vertexes = FloatArray((max_size_z + 1) * (max_size_x + 1) * 3)
        normales_x = Array(max_size_z + 1) { FloatArray(max_size_x + 1) }
        normales_y = Array(max_size_z + 1) { FloatArray(max_size_x + 1) }
        normales_z = Array(max_size_z + 1) { FloatArray(max_size_x + 1) }
        normales = FloatArray((max_size_z + 1) * (max_size_x + 1) * 3)
        for (i in 0..max_size_x) {
            x[i] = x0 + i * dx
        }
        for (j in 0..max_size_z) {
            z[j] = z0 + j * dz
        }
        val vb = ByteBuffer.allocateDirect((max_size_z + 1) * (max_size_x + 1) * 3 * 4)
        vb.order(ByteOrder.nativeOrder())
        vertexes_buffer = vb.asFloatBuffer()
        vertexes_buffer.position(0)
        val nb = ByteBuffer.allocateDirect((max_size_z + 1) * (max_size_x + 1) * 3 * 4)
        nb.order(ByteOrder.nativeOrder())
        normales_buffer = nb.asFloatBuffer()
        normales_buffer.position(0)
        val index: ShortArray
        size_index = 2 * (max_size_x + 1) * max_size_z + (max_size_z - 1)
        index = ShortArray(size_index)
        var k = 0
        var j = 0
        while (j < max_size_z) {
            for (i in 0..max_size_x) {
                index[k] = chain(j, i)
                k++
                index[k] = chain(j + 1, i)
                k++
            }
            if (j < max_size_z - 1) {
                index[k] = chain(j + 1, max_size_x)
                k++
            }
            j++
            if (j < max_size_z) {
                for (i in max_size_x downTo 0) {
                    index[k] = chain(j, i)
                    k++
                    index[k] = chain(j + 1, i)
                    k++
                }
                if (j < max_size_z - 1) {
                    index[k] = chain(j + 1, 0)
                    k++
                }
                j++
            }
        }
        val bi = ByteBuffer.allocateDirect(size_index * 2)
        bi.order(ByteOrder.nativeOrder())
        index_buffer = bi.asShortBuffer()
        index_buffer.put(index)
        index_buffer.position(0)
        get_vertexes()
        get_normales()
    }

    private fun chain(j: Int, i: Int): Short {
        return (i + j * (max_size_x + 1)).toShort()
    }

    private fun get_vertexes() {
        val time = System.currentTimeMillis().toDouble()
        for (j in 0..max_size_z) {
            for (i in 0..max_size_x) {
                y[j][i] = 0.02f * Math.cos(0.005 * time + 5 * (z[j] + x[i])).toFloat()
            }
        }
        var k = 0
        for (j in 0..max_size_z) {
            for (i in 0..max_size_x) {
                vertexes[k] = x[i]
                k++
                vertexes[k] = y[j][i]
                k++
                vertexes[k] = z[j]
                k++
            }
        }
        vertexes_buffer.put(vertexes)
        vertexes_buffer.position(0)
    }

    private fun get_normales() {
        for (j in 0 until max_size_z) {
            for (i in 0 until max_size_x) {
                normales_x[j][i] = -(y[j][i + 1] - y[j][i]) * dz
                normales_y[j][i] = dx * dz
                normales_z[j][i] = -dx * (y[j + 1][i] - y[j][i])
            }
        }
        for (j in 0 until max_size_z) {
            normales_x[j][max_size_x] = (y[j][max_size_x - 1] - y[j][max_size_x]) * dz
            normales_y[j][max_size_x] = dx * dz
            normales_z[j][max_size_x] = -dx * (y[j + 1][max_size_x] - y[j][max_size_x])
        }
        for (i in 0 until max_size_x) {
            normales_x[max_size_z][i] = -(y[max_size_z][i + 1] - y[max_size_z][i]) * dz
            normales_y[max_size_z][i] = dx * dz
            normales_z[max_size_z][i] = dx * (y[max_size_z - 1][i] - y[max_size_z][i])
        }
        normales_x[max_size_z][max_size_x] =
            (y[max_size_z][max_size_x - 1] - y[max_size_z][max_size_x]) * dz
        normales_y[max_size_z][max_size_x] = dx * dz
        normales_z[max_size_z][max_size_x] =
            dx * (y[max_size_z - 1][max_size_x] - y[max_size_z][max_size_x])
        var k = 0
        for (j in 0..max_size_z) {
            for (i in 0..max_size_x) {
                normales[k] = normales_x[j][i]
                k++
                normales[k] = normales_y[j][i]
                k++
                normales[k] = normales_z[j][i]
                k++
            }
        }
        normales_buffer.put(normales)
        normales_buffer.position(0)
    }

    @SuppressLint("ResourceType")
    override fun onSurfaceCreated(gl: GL10?, config: javax.microedition.khronos.egl.EGLConfig?) {
        gl?.glGenTextures(2, texture, 0)
        val stream: InputStream
        val bitmap: Bitmap
        stream = c.resources.openRawResource(R.drawable.water1)
        bitmap = BitmapFactory.decodeStream(stream)
        gl?.glBindTexture(GL10.GL_TEXTURE_2D, texture[0])
        gl?.glTexParameterf(
            GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER,
            GL10.GL_LINEAR.toFloat()
        )
        GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0)





        GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR)
        GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR)
        GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0)
        bitmap.recycle()
        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0)



        GLES20.glEnable(GLES20.GL_DEPTH_TEST)
        GLES20.glEnable(GLES20.GL_BLEND)
        GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA)
        val vertex_shader = "uniform mat4 u_modelViewProjectionMatrix;" +
                "attribute vec3 a_vertex;" +
                "attribute vec3 a_normal;" +
                "varying vec3 v_vertex;" +
                "varying vec3 v_normal;" +
                "void main() {" +
                "v_vertex = a_vertex;" +
                "vec3 n_normal = normalize(a_normal);" +
                "v_normal = n_normal;" +
                "gl_Position = u_modelViewProjectionMatrix * vec4(a_vertex, 1.0);" +
                "}"
        val fragment_shader = "precision mediump float;" +
                "uniform vec3 u_camera;" +
                "uniform vec3 u_lightPosition;" +
                "uniform sampler2D u_texture0;" +
                "uniform sampler2D u_texture1;" +
                "varying vec3 v_vertex;" +
                "varying vec3 v_normal;" +

                "vec3 myrefract(vec3 IN, vec3 NORMAL, float k) {" +
                " float nv = dot(NORMAL,IN);" +
                " float v2 = dot(IN,IN);" +
                " float knormal = (sqrt(((k * k - 1.0) * v2) / (nv * nv) + 1.0) - 1.0) * nv;" +
                " vec3 OUT = IN + (knormal * NORMAL);" +
                " return OUT;" +
                "}" +
                "void main() {" +
                " vec3 n_normal = normalize(v_normal);" +
                " vec3 lightvector = normalize(u_lightPosition - v_vertex);" +
                " vec3 lookvector = normalize(u_camera - v_vertex);" +
                " float ambient = 0.1;" +
                " float k_diffuse = 0.7;" +
                " float k_specular = 0.3;" +
                " float diffuse = k_diffuse * max(dot(n_normal, lightvector), 0.0);" +
                " vec3 reflectvector = reflect(-lightvector, n_normal);" +
                " float specular = k_specular * pow( max(dot(lookvector,reflectvector),0.0), 40.0);" +
                " vec4 one = vec4(1.0,1.0,1.0,1.0);" +
                " vec4 lightColor = (ambient + diffuse + specular) * one;" +
                " vec3 OUT = myrefract(-lookvector, n_normal, 1.2);" +
                " float ybottom = -1.0;" +
                " float xbottom = v_vertex.x + OUT.x * (ybottom - v_vertex.y) / OUT.y;" +
                " float zbottom = v_vertex.z + OUT.z * (ybottom - v_vertex.y) / OUT.y;" +
                " vec2 texCoord = vec2(xbottom, zbottom);" +
                " vec4 textureColor = texture2D(u_texture0, texCoord);" +
                " textureColor.a *= 0.5;" +
                " gl_FragColor = lightColor * textureColor;" +
                "vec4 textureColor1 = texture2D(u_texture1, gl_FragCoord.xy);" +
                //"gl_FragColor = mix(textureColor0, textureColor1, textureColor1.a) * lightColor;" +
                "}"

        val textureId = texture[1]
        val options = BitmapFactory.Options()
        options.inScaled = false
        val bitmap1 = BitmapFactory.decodeResource(Resources.getSystem(), R.drawable.water, options)
        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureId)

        m_shader = Shader(vertex_shader, fragment_shader)
        m_shader!!.link_vertex_buffer(vertexes_buffer)
        m_shader!!.link_normal_buffer(normales_buffer)
        m_shader!!.link_texture(texture)




    }

    override fun onSurfaceChanged(gl: GL10, width: Int, height: Int) {
        gl.glViewport(0, 0, width, height)
        val ratio = width.toFloat() / height
        val k = 0.0555f
        val left = -k * ratio
        val right = k * ratio
        val bottom = -k
        val near = 0.1f
        val far = 10.0f
        Matrix.frustumM(projection_matrix, 0, left, right, bottom, k, near, far)
        Matrix.multiplyMM(
            model_view_projection_matrix,
            0,
            projection_matrix,
            0,
            model_view_matrix,
            0
        )
    }

    override fun onDrawFrame(gl: GL10) {
        m_shader!!.link_model_view_projection_matrix(model_view_projection_matrix)
        m_shader!!.link_camera(x_camera, y_camera, z_camera)
        m_shader!!.link_light_source(x_light_position, y_light_position, z_light_position)
        get_vertexes()
        get_normales()
        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT or GLES20.GL_DEPTH_BUFFER_BIT)
        GLES20.glDrawElements(
            GLES20.GL_TRIANGLE_STRIP, size_index, GLES20.GL_UNSIGNED_SHORT,
            index_buffer
        )
    }
}