2011-12-31 38 views
7

Tôi đang cố gắng vẽ họa tiết lên hình tứ giác trong OpenGL2.0. Cho đến nay tôi đã nhận được các quads để hiển thị và tất cả mọi thứ, nhưng các kết cấu không có ở đó - quads là tất cả các màu đen.Android OpenGL2.0 hiển thị họa tiết màu đen

nghi ngờ chính của tôi là tôi không lập bản đồ kết cấu một cách chính xác - textures của tôi là không quyền hạn của 2, cũng không phải là họ vuông - chiều rộng của họ là trong lĩnh vực mWidth và chiều cao của họ trong mRowHeight.

Quad được vẽ trong danh sách theo chiều dọc, được thực hiện bằng ma trận dịch.

Tôi sẽ rất biết ơn nếu có ai có thể vượt qua được nguyên nhân này tôi đang tuyệt vọng!

Đây là mã có liên quan:

Khởi tạo bộ đệm:

void initBuffers() { 
     float r = (float) mRowHeight/(mHeight/2f); 
     ByteBuffer bb; 

     float[] bounds = { // X Y Z 
     /* 0 - TL */-1f, 1f, 0f, 
     /* 1 - BL */-1f, 1 - r, 0f, 
     /* 2 - BR */ 1f, 1 - r, 0f, 
     /* 3 - TR */ 1f, 1f, 0f }; 
     bb = ByteBuffer.allocateDirect(bounds.length * 4); 
     bb.order(ByteOrder.nativeOrder()); 
     mVertBuffer = bb.asFloatBuffer(); 
     mVertBuffer.put(bounds).position(0); 

     short[] indices = { 0, 1, 2, 0, 2, 3 }; 
     bb = ByteBuffer.allocateDirect(indices.length * 2); 
     bb.order(ByteOrder.nativeOrder()); 
     mIndBuffer = bb.asShortBuffer(); 
     mIndBuffer.put(indices).position(0); 

     float[] texture = { 
       /* 0 - BL */-1f, 1f, 
       /* 1 - TL */-1f, 1 - r, 
       /* 2 - BR */1f, 1 - r, 
       /* 3 - TR */1f, 1f }; 
     bb = ByteBuffer.allocateDirect(texture.length * 4); 
     bb.order(ByteOrder.nativeOrder()); 
     mTexBuffer = bb.asFloatBuffer(); 
     mTexBuffer.put(texture).position(0); 

    } 

Vẽ khung:

@Override 
    public void drawFrame() { 
     long startTime = System.currentTimeMillis(); 
     if (!mLayoutComplete) { 
      return; 
     } 
     final float halfw = mHeight/2f; 
     final int rowHeight = mRowHeight; 
     final float r = (float) rowHeight/halfw; 

     int i = mFirstRow; 

     final float initial = (float) ((i * rowHeight) - mScroll)/halfw; 

     Matrix.setIdentityM(mTMatrix, 0); 
     Matrix.translateM(mTMatrix, 0, 0, -initial, 0); 

     GLES20.glVertexAttribPointer(maPositionHandle, 3, GLES20.GL_FLOAT, 
       false, 0, mVertBuffer); 
     GLES20.glEnableVertexAttribArray(maPositionHandle); 

     final int l = mLastRow; 
     for (; i <= l; i++) { 

      ThumbRow thr = mCache.get(i); 
      if (thr != null) { 
       GLES20.glActiveTexture(GLES20.GL_TEXTURE0); 
       if (thr.mDirty) { 
        thr.loadTexture(null, null); 
        thr.mDirty = false; 
       } else { 
        GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, thr.mRow + 1); 
       } 
       GLES20.glUniform1i(msTextureHandle, 0); 

       GLES20.glVertexAttribPointer(maTextureHandle, 2, 
         GLES20.GL_FLOAT, false, 0, mTexBuffer); 
       GLES20.glEnableVertexAttribArray(maTextureHandle); 

       GLES20.glUniformMatrix4fv(muTMatrixHandle, 1, false, 
         mTMatrix, 0); 
       GLES20.glDrawElements(GLES20.GL_TRIANGLES, 6, 
         GLES20.GL_UNSIGNED_SHORT, mIndBuffer); 
       Log.i(TAG, GLES20.glGetProgramInfoLog(mProgram)); 
      } 

      Matrix.translateM(mTMatrix, 0, 0, -r, 0); // Shift drawing 
                 // window to next 
                 // row. 
     } 

     GLES20.glDisableVertexAttribArray(maPositionHandle); 
     GLES20.glDisableVertexAttribArray(maTextureHandle); 

     Log.d(TAG, "onDrawFrame(): " 
       + (System.currentTimeMillis() - startTime)); 
    } 

Đang tải các kết cấu:

 public void loadTexture(GL10 gl, Context c) { 
      GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mRow + 1); 

      // Create Nearest Filtered Texture 
      GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, 
        GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST); 
      GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, 
        GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR); 

      // Different possible texture parameters, e.g. 
      // GLES20.GL_CLAMP_TO_EDGE 
      GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, 
        GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_REPEAT); 
      GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, 
        GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_REPEAT); 

      Bitmap bitmap = mBitmap; 
      if (bitmap == null) { 
       bitmap = mEmptyBitmap; 
      } 
      GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0); 
     } 

Vertex Shader:

uniform mat4 uTMatrix; 
uniform mat4 uMVPMatrix; 
attribute vec4 aPosition; 
attribute vec2 aTextureCoord; 
varying vec2 vTextureCoord; 

void main() { 
    gl_Position = uMVPMatrix * uTMatrix * aPosition; 
    vTextureCoord = aTextureCoord; 
} 

Fragment Shader:

precision mediump float; 
varying vec2 vTextureCoord; 
uniform sampler2D sTexture; 
void main() { 
    gl_FragColor = texture2D(sTexture, vTextureCoord); 
} 

Bất kỳ trợ giúp sẽ được nhiều đánh giá cao.

+0

Sau khi gọi '' glBindTexture (..) '' '' mRow + 1'' chẳng hạn? Nếu đó là một số biến nội bộ, bạn nên thay đổi nó thành tên kết cấu mà bạn nhận được từ '' glGenTextures (..) ''. Và về cơ bản, nếu bạn chỉ sử dụng một texture (và chỉ cập nhật nội dung của nó), hãy sử dụng tên texture đó mọi lúc. – harism

+0

mRow là chỉ số của quad hiện tại được vẽ - kết cấu của quad được xác định bởi mRow của nó. EDIT: Từ những gì tôi hiểu nó là okay để sử dụng tên kết cấu của riêng tôi miễn là chúng là duy nhất và tôi nhớ chúng – saarraz1

+0

Không. Bạn phải phân bổ các tên kết cấu bằng cách sử dụng glGenTextures (..), bạn không thể tự tìm ra các tên kết cấu. Trong trường hợp của bạn, bạn nên phân bổ ROW_COUNT tên kết cấu và sử dụng glBindTexture (.., TEXTURE_NAMES [mRowIdx]).Nhưng nếu ROW_COUNT rất cao, tốt nhất là nên tải lại bitmap vào một kết cấu chỉ cho mỗi hàng để tránh việc sử dụng bộ nhớ không cần thiết. – harism

Trả lời

20

Đây là vấn đề khá phổ biến về kết cấu trên OpenGL ES 2.0 gây ra rất nhiều đau đầu cho tôi trong quá khứ.

Trong OpenGL ES 2.0, trong không có sức mạnh của 2 hoạ tiết, chế độ bọc chỉ có thể là GL_CLAMP_TO_EDGE.

Có những hạn chế cũng như trên bộ lọc mà bạn có thể sử dụng mà có thể được chỉ GL_NEAREST hoặc GL_LINEAR (nói cách khác không mipmapping)

Nói cách đơn giản, kiểm tra bạn loadtexture chức năng, thay đổi các 2 dòng mã từ:

GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, 
        GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_REPEAT); 
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, 
        GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_REPEAT); 

để

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

tôi hy vọng này có khắc phục được vấn đề, cho tôi biết :)

Maurizio Benedetti

+0

OMG IT WORKS !! Tôi không thể cảm ơn đủ! Tôi gần như đã từ bỏ việc sử dụng OGL sau đó bạn đã xuất hiện. Cảm ơn rất nhiều lần nữa. – saarraz1

+0

wow, vui khi đọc điều đó. Chúc một ngày tốt lành và chúc may mắn cho các dự án của bạn. –

+0

Tx. Giúp tôi. Đoán đọc các chi tiết kỹ thuật là phải :) –

Các vấn đề liên quan