2012-12-16 199 views
0

我開始從谷歌的Android教程打開gl,然後使用此tutorial: 添加紋理。由於類結構有點不同,我不得不做一些代碼移動重命名。我結束了是:紋理被拉伸在android opengl es 2.0

enter image description here

Here是紋理文件我用。 正如人們可以看到的那樣,儘管底層對象是正方形,但紋理沿着(1,1)伸展。 這是我的四代碼,任何幫助表示讚賞。

public class GLSquare implements IGLObject { 

private final String vertexShaderCode = 
// This matrix member variable provides a hook to manipulate 
// the coordinates of the objects that use this vertex shader 
"uniform mat4 uMVPMatrix;" + "attribute vec2 a_TexCoordinate;" 
     + "varying vec2 v_TexCoordinate;" + "attribute vec4 vPosition;" 
     + "void main() {" 
     + 
     // the matrix must be included as a modifier of gl_Position 
     " gl_Position = uMVPMatrix * vPosition;" 
     + "v_TexCoordinate = a_TexCoordinate;" + "}"; 

private final String fragmentShaderCode = "precision mediump float;" 
     + "uniform sampler2D u_Texture;" + "varying vec2 v_TexCoordinate;" 
     + "void main() {" 
     + " gl_FragColor = texture2D(u_Texture, v_TexCoordinate);" + "}"; 

private final FloatBuffer vertexBuffer; 
private final ShortBuffer drawListBuffer; 
private final int mProgramHandle; 
private int mPositionHandle; 
private int mMVPMatrixHandle; 
private int mTextureDataHandle; 
/** The texture pointer */ 

// number of coordinates per vertex in this array 
static final int COORDS_PER_VERTEX = 3; 
static float squareCoords[] = { -10f, 10f, 0.0f, // top left 
     -10f, -10f, 0.0f, // bottom left 
     10f, -10f, 0.0f, // bottom right 
     10f, 10f, 0.0f }; // top right 

private FloatBuffer textureBuffer; // buffer holding the texture coordinates 
private float texture[] = { 
     // Mapping coordinates for the vertices 
     0.0f, 1.0f, // top left (V2) 
     0.0f, 0.0f, // bottom left (V1) 
     1.0f, 1.0f, // top right (V4) 
     1.0f, 0.0f // bottom right (V3) 
}; 

static float[] mTranslate = new float[16]; 
static float[] translatedMVP = new float[16]; 

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

public GLSquare(float x, float y, float z, Context context) { 
    // initialize vertex byte buffer for shape coordinates 
    ByteBuffer bb = ByteBuffer.allocateDirect(squareCoords.length * 4); 
    bb.order(ByteOrder.nativeOrder()); 
    vertexBuffer = bb.asFloatBuffer(); 
    vertexBuffer.put(squareCoords); 
    vertexBuffer.position(0); 

    bb = ByteBuffer.allocateDirect(texture.length * 4); 
    bb.order(ByteOrder.nativeOrder()); 
    textureBuffer = bb.asFloatBuffer(); 
    textureBuffer.put(texture); 
    textureBuffer.position(0); 

    // initialize byte buffer for the draw list 
    ByteBuffer dlb = ByteBuffer.allocateDirect(
    // (# of coordinate values * 2 bytes per short) 
      drawOrder.length * 2); 
    dlb.order(ByteOrder.nativeOrder()); 
    drawListBuffer = dlb.asShortBuffer(); 
    drawListBuffer.put(drawOrder); 
    drawListBuffer.position(0); 

    Matrix.setIdentityM(mTranslate, 0); 
    Matrix.translateM(mTranslate, 0, x, y, z); 
    // prepare shaders and OpenGL program 
    final int vertexShaderHandle = GLTools.compileShader(
      GLES20.GL_VERTEX_SHADER, vertexShaderCode); 
    final int fragmentShaderHandle = GLTools.compileShader(
      GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode); 

    mProgramHandle = GLTools.createAndLinkProgram(vertexShaderHandle, 
      fragmentShaderHandle, new String[] { "a_Position", "a_Color", 
        "a_TexCoordinate" }); 
    // Load the texture 
    mTextureDataHandle = GLTools.loadGLTexture(context, R.raw.stars1024); 
} 

public void draw(float[] vpMatrix) { 
    // Add program to OpenGL environment 
    GLES20.glUseProgram(mProgramHandle); 

    // Pass in the position information 
    vertexBuffer.position(0); 
    GLES20.glVertexAttribPointer(mPositionHandle, 3, GLES20.GL_FLOAT, 
      false, 0, vertexBuffer); 
    GLES20.glEnableVertexAttribArray(mPositionHandle); 

    int mTextureCoordinateHandle = GLES20.glGetAttribLocation(
      mProgramHandle, "a_TexCoordinate"); 
    // Pass in the texture coordinate information 
    textureBuffer.position(0); 
    GLES20.glVertexAttribPointer(mTextureCoordinateHandle, 2, 
      GLES20.GL_FLOAT, false, 0, textureBuffer); 
    GLES20.glEnableVertexAttribArray(mTextureCoordinateHandle); 

    mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgramHandle, 
      "uMVPMatrix"); 
    WideOpenRenderer.checkGlError("glGetUniformLocation"); 

    // Apply the projection and view transformation 
    Matrix.multiplyMM(translatedMVP, 0, vpMatrix, 0, mTranslate, 0); 
    GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, translatedMVP, 0); 

    // Draw the cube. 
    GLES20.glDrawElements(GLES20.GL_TRIANGLES, drawOrder.length, 
      GLES20.GL_UNSIGNED_SHORT, drawListBuffer); 

} 

} 

這裏是梅索德裝載質地:

public static int loadGLTexture(Context context, final int resourceId) { 
    Log.d("GLTools", "Loading texture..."); 
     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]); 
      Log.d("GLTools", "Binding texture, setting parameter" + resourceId); 
      // 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]; 
} 

回答

0

好了,我現在能回答我的問題。 紋理相對於它的原點=左底點(u,v)=(0,0)剛剛縮放,這激怒了我,因爲我是opengl的新手,我期待它會相對於至少縮放世界的起源,或物體的質心。