在Android中的Opengl GLES20.GL_CLAMP_TO_EDGE

时间:2012-08-01 11:30:16

标签: opengl-es

使用:

将纹理渲染为矩形(2个三角形)
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER,
                       GLES20.GL_NEAREST);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER,
                       GLES20.GL_NEAREST);

没问题。但我不希望纹理被拉伸,所以我试图改为:

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

但我得到的一切都是黑屏。

有没有简单的方法可以避免纹理与屏幕保持比例?

这是我加载纹理的地方

public static int loadTexture(final Context context, Bitmap bitmap)
{
    final int[] textureHandle = new int[1];

    GLES20.glGenTextures(1, textureHandle, 0);

    if (textureHandle[0] != 0)
    {
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inScaled = false;   // No pre-scaling

        // Read in the resource
        //final Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), resourceId, options);

        // Bind to the texture in OpenGL
        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureHandle[0]);

        // Set filtering
        GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);
        GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST);

        // Load the bitmap into the bound texture.
        GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);

        // Recycle the bitmap, since its data has been loaded into OpenGL.
        bitmap.recycle();                       
    }

    if (textureHandle[0] == 0)
    {
        throw new RuntimeException("Error loading texture.");
    }

    return textureHandle[0];
}

这是一些渲染器代码:

public void onSurfaceCreated(GL10 glUnused, EGLConfig config)
{

    String vShaderStr = RawResourceReader.readTextFileFromRawResource(this.context, R.raw.bulge_vertex_shader);

    String fShaderStr = RawResourceReader.readTextFileFromRawResource(this.context, R.raw.bulge_fragment_shader);



    // Load the shaders and get a linked program object
    mProgramObject = ESShader.loadProgram(vShaderStr, fShaderStr);

    // Get the attribute locations
    mPositionLoc = GLES20.glGetAttribLocation(mProgramObject, "a_position");
    mTexCoordLoc = GLES20.glGetAttribLocation(mProgramObject, "a_texCoord" );

    centerUniformLoc = GLES20.glGetUniformLocation(mProgramObject, "center");

    radiusUniformLoc = GLES20.glGetUniformLocation(mProgramObject, "radius");

    scaleUniformLoc = GLES20.glGetUniformLocation(mProgramObject, "scale");


    Bitmap b  = ((theApplication)context.getApplicationContext()).getBitmap();

    mTextureId = TextureHelper.loadTexture(this.context, b);

    GLES20.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);

}

// /
// Draw a triangle using the shader pair created in onSurfaceCreated()
//
public void onDrawFrame(GL10 glUnused)
{
    //distance += 0.01;


    // Set the viewport
    GLES20.glViewport(0, 0, mWidth, mHeight);

    // Clear the color buffer
    GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);

    // Use the program object
    GLES20.glUseProgram(mProgramObject);

    // Load the vertex position
    mVertices.position(0);
    GLES20.glVertexAttribPointer ( mPositionLoc, 3, GLES20.GL_FLOAT, 
                                   false, 
                                   5 * 4, mVertices );

    // Load the texture coordinate
    mVertices.position(3);
    GLES20.glVertexAttribPointer ( mTexCoordLoc, 2, GLES20.GL_FLOAT,
                                   false, 
                                   5 * 4, 
                                   mVertices );

    GLES20.glEnableVertexAttribArray ( mPositionLoc );
    GLES20.glEnableVertexAttribArray ( mTexCoordLoc );

    // Bind the texture
    GLES20.glActiveTexture ( GLES20.GL_TEXTURE0 );
    GLES20.glBindTexture ( GLES20.GL_TEXTURE_2D, mTextureId );


    GLES20.glUniform2f(centerUniformLoc, mCenterData[0], mCenterData[1]);


    GLES20.glUniform1f(radiusUniformLoc, radius);

    GLES20.glUniform1f(scaleUniformLoc, scale);

    // Set the color matrix uniform unit to 1


    GLES20.glDrawElements ( GLES20.GL_TRIANGLES, 6, GLES20.GL_UNSIGNED_SHORT, mIndices );
}

和纹理坐标为

的四边形顶点
private final float[] mVerticesData =
{ 
        -1f, 1f, 0.0f, // Position 0
        0.0f, 0.0f, // TexCoord 0
        -1f, -1f, 0.0f, // Position 1
        0.0f, 1.0f, // TexCoord 1
        1f, -1f, 0.0f, // Position 2
        1.0f, 1.0f, // TexCoord 2
        1f, 1f, 0.0f, // Position 3
        1.0f, 0.0f // TexCoord 3
};


private final short[] mIndicesData =
{ 
        0, 1, 2, 0, 2, 3 
};

我想要的只是看到纹理缩放到屏幕尺寸,但保持纵横比,使其不会拉伸。

由于

1 个答案:

答案 0 :(得分:5)

为了避免出现黑屏问题,您需要组合这四行,而不是将前两行替换为后两行。在您的代码中,您正在替换

GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER,
                   GLES20.GL_NEAREST);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER,
                   GLES20.GL_NEAREST);

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

最初,我做了同样的事情;然而,校正应该是添加夹紧线而不是更换过滤线。工作代码是一个组合:

GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER,
                   GLES20.GL_NEAREST);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER,
                   GLES20.GL_NEAREST);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, 
                   GLES20.GL_CLAMP_TO_EDGE);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, 
                   GLES20.GL_CLAMP_TO_EDGE);