背景图片移动OpenGL ES2

时间:2013-03-17 11:57:57

标签: android opengl-es-2.0

我正试图让我的2D背景图像移动。在fututre它将实现为自动运动(看起来像相机跟随一些对象)。一个典型的例子 - 愤怒的小鸟游戏。在攻击期间,摄像机跟随鸟。

目前,我只是更改setLookAtM()中的值。这是代码:

public void onSurfaceCreated(GL10 unused, EGLConfig config) {
    GLES20.glClearColor(0.5f, 0.5f, 0.5f, 1.0f);

    GLES20.glDisable(GLES20.GL_DEPTH_TEST); 
    GLES20.glEnable(GLES20.GL_BLEND);
    GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA,GLES20.GL_ONE_MINUS_SRC_ALPHA);

    // background
   bg = new BackGround(mActivityContext);

}

public void onDrawFrame(GL10 unused) {
    // Redraw background color
    GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);

    Matrix.setLookAtM(mVMatrix, 0, -1f, 0f, -3, 0f, 0f, 0f, 0f, 1.0f, 0.0f);
    Matrix.setIdentityM(mTrMatrix, 0);

    bg.draw(mMVPMatrix);
}

public void onSurfaceChanged(GL10 unused, int width, int height) {
    GLES20.glViewport(0, 0, width , height );

    float ratio = (float) width / height;
    Matrix.orthoM(mProjMatrix, 0, -ratio, ratio, -1, 1, 3, 7);
}


class BackGround {

    private FloatBuffer vertexBuffer;
    private ShortBuffer drawListBuffer;

    static final int COORDS_PER_VERTEX = 3;
    static float squareCoords[] = { -15.5f,  15.5f, 0.0f,   // top left
    -15.5f, -15.5f, 0.0f,   // bottom left
    15.5f, -15.5f, 0.0f,   // bottom right
    15.5f,  15.5f, 0.0f }; // top right

    int mProgram;
    int mPositionHandle;

    private short drawOrder[] = { 0, 1, 2, 0, 2, 3 }; // order to draw vertices
    private final String vertexShaderCode = "attribute vec2 a_TexCoordinate;" +
    "varying vec2 v_TexCoordinate;" +
    "uniform mat4 uMVPMatrix;" +
    "attribute vec4 vPosition;" +
    "void main() {" +
    "  gl_Position = uMVPMatrix * vPosition;" +
    "v_TexCoordinate = a_TexCoordinate;" +
    "}";

    private final String fragmentShaderCode =
    "precision mediump float;" +
    "uniform vec4 vColor;" +
    "uniform sampler2D u_Texture;" +
    "varying vec2 v_TexCoordinate;" +
    "void main() {" +
    "gl_FragColor = ( texture2D(u_Texture, v_TexCoordinate));" +
    "}";

    public BackGround(final Context context) {
        // initialize vertex byte buffer for shape coordinates
        ByteBuffer bb = ByteBuffer.allocateDirect(squareCoords.length * 4);
        bb.order(ByteOrder.nativeOrder());
        vertexBuffer = bb.asFloatBuffer();
        vertexBuffer.put(squareCoords);
        vertexBuffer.position(0);

        mActivityContext = context;

        // initialize byte buffer for the draw list
        ByteBuffer dlb = ByteBuffer.allocateDirect(drawOrder.length * 2);
        dlb.order(ByteOrder.nativeOrder());
        drawListBuffer = dlb.asShortBuffer();
        drawListBuffer.put(drawOrder);
        drawListBuffer.position(0);

        int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode);
        int fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode);

        final float[] cubeTextureCoordinateData = {
            -15.5f,  15.5f,
            -15.5f, -15.5f,
            15.5f, -15.5f,
            15.5f,  15.5f
        };

        mCubeTextureCoordinates =   
        ByteBuffer.allocateDirect(cubeTextureCoordinateData.length *  
        4).order(ByteOrder.nativeOrder()).asFloatBuffer();
        mCubeTextureCoordinates.put(cubeTextureCoordinateData).position(0);

        mProgram = GLES20.glCreateProgram();             
        GLES20.glAttachShader(mProgram, vertexShader);   
        GLES20.glAttachShader(mProgram, fragmentShader); 
        GLES20.glBindAttribLocation(mProgram, 0, "a_TexCoordinate");
        GLES20.glLinkProgram(mProgram);   

        // load background bitmap 256x256px              
        mTextureDataHandle = loadTexture(mActivityContext, R.drawable.mud);
    }

    public void draw(float[] mvpMatrix) {

        GLES20.glUseProgram(mProgram);
        mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");

        GLES20.glEnableVertexAttribArray(mPositionHandle);
        GLES20.glVertexAttribPointer(mPositionHandle, COORDS_PER_VERTEX,
        GLES20.GL_FLOAT, false, vertexStride, vertexBuffer);

        mColorHandle = GLES20.glGetUniformLocation(mProgram, "vColor");
        GLES20.glUniform4fv(mColorHandle, 1, color, 0);

        mTextureUniformHandle = GLES20.glGetAttribLocation(mProgram, "u_Texture");
        mTextureCoordinateHandle = GLES20.glGetAttribLocation(mProgram, "a_TexCoordinate");

        GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureDataHandle);
        GLES20.glUniform1i(mTextureUniformHandle, 0);

        mCubeTextureCoordinates.position(0);
        GLES20.glVertexAttribPointer(mTextureCoordinateHandle, mTextureCoordinateDataSize,
        GLES20.GL_FLOAT, false, 0, mCubeTextureCoordinates);
        GLES20.glEnableVertexAttribArray(mTextureCoordinateHandle);

        mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
        GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mvpMatrix, 0);
        GLES20.glDrawElements(GLES20.GL_TRIANGLES, drawOrder.length,
        GLES20.GL_UNSIGNED_SHORT, drawListBuffer);
        GLES20.glDisableVertexAttribArray(mPositionHandle);
    }
}

问题是我不知道如何在大区域(不受屏幕尺寸限制)上传播我的背景(256x256)。 currenty,纹理仅在屏幕边缘重复。当我试图移动它(使用SetLookAtm())它移动正常,但留下空条纹:

初始背景图片(bmp-reversed):

ab
cd

屏幕上的背景图片:

--------
|ababab|
|cdcdcd|
|ababab|
|cdcdcd|
|ababab|
|cdcdcd|
--------

移动后的背景图像(右 - >)

--------
|  abab|
|  cdcd|
|  abab|
|  cdcd| 
|  abab|
|  cdcd|
--------

方向(左,右,上,下)无关紧要。它只对哪个边条纹出现有影响

1 个答案:

答案 0 :(得分:0)

或者:

A)定义背景矩形,使其超出屏幕的两端(并通过设置其位置来“滚动”背景)

--------
|ababab|ababab
|cdcdcd|cdcdcd
|ababab|ababab
|cdcdcd|cdcdcd
|ababab|ababab
|cdcdcd|cdcdcd
--------

或:

B)如前所述定义填充屏幕的bg矩形,但为纹理坐标设置动画以使其滚动。例如:如果您的texcoords形成一个矩形(0.00,0.00)->(1.00,1.00),则通过将texcoords更改为(0.05,0.00)->(1.05,1.00)来滚动左边的bg。确保按如下方式设置glTexParameteri:

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
相关问题