Opengl GLES20。GL_CLAMP_TO_EDGE android

时间:2022-06-11 12:52:23

Rendering a texture into a rectangle(2 tri) with :

将纹理渲染成矩形(2 tri):

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);

and no problem. But I dont want the texture to be stretched so Im trying to change to:

和没有问题。但是我不想让纹理被拉伸,所以我尝试着去改变:

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);

but everything I got is a black screen.

但我得到的都是黑色的屏幕。

Is there any simple way to avoid a texture to fit the screen keeping the ratio?

有没有一种简单的方法来避免纹理与屏幕保持比例?

This is where I load the texture

这是我加载纹理的地方。

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];
}

This is the some of renderer code:

这是一些渲染代码:

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 );
}

and the quad vertices with the texture coordinates

以及带有纹理坐标的四边形顶点。

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 
};

All I want is to see the texture scaled to the screen size but keeping the aspect ratio so it doesn't get stretched.

我想要的是看到纹理缩放到屏幕尺寸,但保持纵横比,这样它就不会被拉伸。

Thanks

谢谢

1 个解决方案

#1


5  

In order to avoid this black screen issue, you needed to combine the four lines as opposed to replacing the former two with the latter two. In your code, you were replacing

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

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);

with

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);

Originally, I did the same thing; however, the correction should have been to add the clamping lines as opposed to replacing the filtering lines. The working code is a combination:

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

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);

#1


5  

In order to avoid this black screen issue, you needed to combine the four lines as opposed to replacing the former two with the latter two. In your code, you were replacing

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

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);

with

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);

Originally, I did the same thing; however, the correction should have been to add the clamping lines as opposed to replacing the filtering lines. The working code is a combination:

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

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);