在opengl中以正确的比例渲染纹理

时间:2012-09-06 05:25:33

标签: opengl-es opengl-es-2.0

我试图渲染一个纹理,保持其在openGL es 2.0中的比例。

我想我需要计算比率并改变平截头体尺寸,这是正确的方法吗? 现在我使用视锥体-1,1渲染宽度和高度,以便在没有屏幕尺寸时纹理被拉伸。

如何渲染纹理让我们说这个比例宽度= 400高度= 800?

这是我的代码:

@Override
    public void onDrawFrame(GL10 glUnused) {

    GLES20.glClearColor(0.9f, 0.9f, 0.9f, .5f);
    GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);
    GLES20.glEnable( GLES20.GL_BLEND );
    GLES20.glBlendFunc( GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA );


    Matrix.setIdentityM(mMMatrix, 0);
    Matrix.rotateM(mMMatrix, 0, 270.0f, 0, 0, 1);
    Matrix.multiplyMM(mMVPMatrix, 0, mVMatrix, 0, mMMatrix, 0);
    Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mMVPMatrix, 0);

    GLES20.glUseProgram(programTextured);

    GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureID);


    sqTex.getVertexBuffer().position(sqTex.VERT_OFFSET);
    GLES20.glVertexAttribPointer(
            GLES20.glGetAttribLocation(programTextured, "aPosition"), 3,
            GLES20.GL_FLOAT, false, 5 * 4, sqTex.getVertexBuffer());
    GLES20.glEnableVertexAttribArray(GLES20.glGetAttribLocation(programTextured, "aPosition"));

    sqTex.getVertexBuffer().position(sqTex.TEXT_OFFSET);
    GLES20.glVertexAttribPointer(
            GLES20.glGetAttribLocation(programTextured, "aTextureCoord"), 2,
            GLES20.GL_FLOAT, false, 5 * 4, sqTex.getVertexBuffer());
    GLES20.glEnableVertexAttribArray(GLES20.glGetAttribLocation(programTextured, "aTextureCoord"));


    GLES20.glUniformMatrix4fv(
            GLES20.glGetUniformLocation(programTextured, "uMVPMatrix"), 1, false,
            mMVPMatrix, 0);
    GLES20.glVertexAttrib4f(
            GLES20.glGetAttribLocation(programTextured, "acolor"), 
            .6f,0.3f,0.9f,.5f);
    GLES20.glDrawElements(GLES20.GL_TRIANGLES, 6, GLES20.GL_UNSIGNED_SHORT, sqTex.getIndexBuffer());

    GLES20.glDisableVertexAttribArray(GLES20.glGetAttribLocation(programTextured, "aTextureCoord"));
}

@Override
public void onSurfaceChanged(GL10 glUnused, int width, int height) {
    GLES20.glViewport(0, 0, width, height);
    float ratio = (float) width / height;
    //flaot ratio2 = (float)height / 
    //Matrix.frustumM(mProjMatrix, 0, -ratio, ratio, -1, 1, 3f, 17);



Matrix.frustumM(mProjMatrix, 0, -1, 1, -1, 1, 3, 17);

}

int mTextureID;
@Override
public void onSurfaceCreated(GL10 glUnused, EGLConfig config) {

    program = createProgram(mVertexShader, mFragmentShader);
    programTextured = createProgram(mVertexShaderTextured, mFragmentShaderTextured);

    Matrix.setLookAtM(mVMatrix, 0, 0, 0, -5, 0f, 0f, 0f, 0f, 1.0f, 0.0f);

    int[] textures = new int[1];
    GLES20.glGenTextures(1, textures, 0);

    mTextureID = textures[0];
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureID);

    GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER,
            GLES20.GL_NEAREST);
    GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D,
            GLES20.GL_TEXTURE_MAG_FILTER,
            GLES20.GL_LINEAR);

    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S,
            GLES20.GL_REPEAT);
    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T,
            GLES20.GL_REPEAT);

    InputStream is = mContext.getResources()
        .openRawResource(R.drawable.image0003);
    Bitmap bitmap;
    try {
        bitmap = BitmapFactory.decodeStream(is);
    } finally {
        try {
            is.close();
        } catch(IOException e) {
            // Ignore.
        }
    }

    GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);
    bitmap.recycle();
}

1 个答案:

答案 0 :(得分:0)

我会离开平截头体,而是使用比例:

您需要2个因素,首先是screenRatio = screenWidth/screenHeight,然后是imageRatio = imageWidth/imageHeight

现在如果imageRatio < screenRatio你需要在宽度上缩小它:

if (imageWidth>imageHeight) scaleM(mMMatrix, 1/(imageWidth/imageHeight), 1, 1)
else scaleM(mMMatrix, 1/(imageHeight/imageWidth), 1, 1)

或者如果imageRatio > screenRatio您需要将其缩小到高度:

if (imageHeight>imageWidth) scaleM(mMMatrix, 1, 1/(imageHeight/imageWidth), 1)
else scaleM(mMMatrix, 1, 1/(imageWidth/imageHeight), 1)