纹理被翻转并颠倒
texture is flipped and upside down
我想在简单的正方形上绘制一个简单的纹理。
但是,纹理图像被翻转和上下颠倒。我想我所有的纹理定义都是正确的,所以我不知道问题出在哪里。
这是我的纹理加载代码:
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);
我的位智图标问题示例图片:
您的纹理坐标已关闭。纹理坐标的工作原理请参考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);
}
我想在简单的正方形上绘制一个简单的纹理。
但是,纹理图像被翻转和上下颠倒。我想我所有的纹理定义都是正确的,所以我不知道问题出在哪里。
这是我的纹理加载代码:
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);
我的位智图标问题示例图片:
您的纹理坐标已关闭。纹理坐标的工作原理请参考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);
}