android - 纹理翻转并上下颠倒

标签 android opengl-es opengl-es-2.0

我正在尝试在简单的正方形上绘制一个简单的纹理。

但是,纹理图像看起来是翻转且颠倒的。我认为我的所有纹理定义都是正确的,所以我不知道问题是什么。

这是我的纹理加载代码:

final int[] textureObjectIds = new int[1];
        GLES20.glGenTextures(1 , textureObjectIds , 0);
        if (textureObjectIds[0] == 0){
            Logger.Log( TAG , "Unable to generate new texture object");
        }

        //define options for decoding
        final BitmapFactory.Options options = new BitmapFactory.Options();

        options.inScaled = true ;



        final Bitmap bitmap = BitmapFactory.decodeResource(context.getResources() , resourceId , options); //decode texture resource to bitmap
        if (bitmap == null){
            Logger.Log(TAG, "Resource ID " + resourceId + " Could not be decoded");
            GLES20.glDeleteTextures(1 , textureObjectIds , 0);
            return 0;
        }

        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureObjectIds[0]); //bind texture to our texture object

        // define magnify and minimize filters
        GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D , GLES20.GL_TEXTURE_MIN_FILTER , GLES20.GL_LINEAR_MIPMAP_LINEAR);
        GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D , GLES20.GL_TEXTURE_MAG_FILTER , GLES20.GL_LINEAR);

        //GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D , GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
        //GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D , GLES20.GL_TEXTURE_WRAP_T , GLES20.GL_CLAMP_TO_EDGE);

        GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0); // load bitmap data to texture

        bitmap.recycle(); // release recycle

        GLES20.glGenerateMipmap(GLES20.GL_TEXTURE_2D);

        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D , 0); //unbind from the texture

        return textureObjectIds[0];

我的正方形和纹理的坐标:

private static final float TEXTURE_FLOOR  = 0.0f;
private static final float TEXTURE_CEIL= 2.0f;

private static final float[] VERTEX_DATA  = {
                                                                        //Coordinates : X , Y , Z , S , T
                                                                        //Triangle1
                                                                        -0.5f , -0.5f   , 0.0f , TEXTURE_FLOOR , TEXTURE_CEIL  ,
                                                                         0.5f , -0.5f   , 0.0f , TEXTURE_CEIL  , TEXTURE_CEIL ,
                                                                        -0.5f ,  0.5f   , 0.0f , TEXTURE_FLOOR , TEXTURE_FLOOR ,

                                                                        //Triangle2
                                                                         0.5f  , -0.5f  , 0.0f , TEXTURE_CEIL , TEXTURE_CEIL ,
                                                                         0.5f  ,  0.5f  , 0.0f , TEXTURE_CEIL  , TEXTURE_FLOOR ,
                                                                        -0.5f  ,  0.5f  , 0.0f , TEXTURE_FLOOR  , TEXTURE_FLOOR
                                                                      };

代码中的更多信息:

private static final int     POSITION_COMPONENT_COUNT               = 3 ;
private static final int     TEXTURE_COORDINATES_COMPONENT_COUNT    = 2 ;
private static final int     STRIDE                                 =  (POSITION_COMPONENT_COUNT + TEXTURE_COORDINATES_COMPONENT_COUNT)
                                                                        * BYTES_PER_FLOAT ;

vertexArray.setVertexAttribPointer(0 , textureShaderProgram.getPositionAttributeLocation() , POSITION_COMPONENT_COUNT , STRIDE);
vertexArray.setVertexAttribPointer(POSITION_COMPONENT_COUNT, textureShaderProgram.getTextureCoordinatesAttributeLocation(), TEXTURE_COORDINATES_COMPONENT_COUNT, STRIDE);

哪里:

public void setVertexAttribPointer(int dataOffset , int attributeLocation , int componentCount , int stride){
    floatBuffer.position(0);
    GLES20.glVertexAttribPointer(attributeLocation, componentCount, GLES20.GL_FLOAT, false, stride, floatBuffer);
    GLES20.glEnableVertexAttribArray(attributeLocation);
    floatBuffer.position(0);

我的位智图标问题的示例图像: waze

最佳答案

您的纹理坐标已关闭。请引用How do opengl texture coordinates work?了解纹理坐标如何工作,并正确设置它们。

除此之外,您还忘记在 setVertexAttribPointer 函数中使用 dataOffset 参数。

public void setVertexAttribPointer(int dataOffset , int attributeLocation , int componentCount , int stride) {
  floatBuffer.position(0);
  GLES20.glVertexAttribPointer(attributeLocation, componentCount, GLES20.GL_FLOAT, false, stride, floatBuffer);
  GLES20.glEnableVertexAttribArray(attributeLocation);
  floatBuffer.position(0);
}

使您的顶点位置值用于纹理坐标。您应该将 floatBuffer 设置为从第一个纹理坐标开始,即 dataOffset

public void setVertexAttribPointer(int dataOffset , int attributeLocation , int componentCount , int stride) {
    floatBuffer.position(dataOffset);
    GLES20.glVertexAttribPointer(attributeLocation, componentCount, GLES20.GL_FLOAT, false, stride, floatBuffer);
    GLES20.glEnableVertexAttribArray(attributeLocation);
    floatBuffer.position(0);
}

关于android - 纹理翻转并上下颠倒,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34575127/

相关文章:

android - LibGDX - 着色器在桌面上工作但不在 Android 上

ios - 是否可以在 OpenGL ES 2.0/iOS 上渲染到 8 位纹理帧缓冲区?

java - Android:三星 S2 上的 GLES 2.0 损坏?

ios - openGL ES 2.0 着色器内置/支持哪些属性?

android - RelativeLayout 高度填充剩余空间

android - 如何在自定义 tablayout 中更改 tablayout 选定的文本颜色

java - 如何使用 openGL 和贝塞尔曲线创建拼图 block ?

android - 64 位 android,32 位应用程序与 32 位 native 库

java - Android slider 布局和 NullPointerException

ios - 是否可以将 float 组传递给 iOS SceneKit 顶点着色器修改器?