2011-08-17 20 views
8

Tôi chỉ đang học cách làm việc với OpenGL ES 2.0 dành cho Android. Tôi đã cố gắng chỉ đơn giản là hiển thị một kết cấu ở giữa màn hình, đủ dễ dàng, nhưng tôi dường như không thể có được Alpha alpha hoạt động đúng cách. Hình ảnh sẽ hiển thị với nền đen hoặc toàn bộ hình ảnh sẽ được pha trộn thành màu nền một chút, tùy thuộc vào cài đặt tôi sử dụng.Kênh alpha alpha OpenGL ES 2.0

Các hướng dẫn thực tế mà tôi đã theo dõi để không bao giờ làm việc với tính minh bạch, vì vậy tôi đã cố gắng làm việc trong mã tôi đã tìm thấy bằng cách tìm kiếm xung quanh, và có khả năng vừa bỏ lỡ một bước quan trọng. Tôi đã tìm kiếm khá nhiều để tìm ra vấn đề này mặc dù, và tôi đã không nhìn thấy bất kỳ câu trả lời đã có một cái gì đó thiết lập của tôi không. Tôi đã thử mọi sự kết hợp của glBlendFunc và những gì không có may mắn.

Tôi đoán nếu tôi cố gắng dán tất cả mã có thể liên quan đến điều này, câu hỏi có vẻ rất cồng kềnh, vì vậy tôi sẽ sẵn lòng đăng bất kỳ mã nào bạn yêu cầu. Tôi rất cảm kích mọi ý tưởng cho những gì tôi nên thử tiếp theo.

EDIT :: Đây là trình đổ bóng phân đoạn của tôi, đó là điều tôi cho là nguyên nhân. Đây là phần duy nhất mà tôi chưa bao giờ thực sự tìm thấy một ví dụ phù hợp để làm việc với tính minh bạch, và mọi thứ khác phù hợp với những gì tôi đã thấy ở nơi khác.

 final String fragmentShader =   
     "precision mediump float;  \n" 
     + "varying vec2 v_Color;   \n"  
     + "uniform sampler2D s_baseMap; \n" 
     + "void main()     \n"  
     + "{        \n" 
     + " vec4 baseColor;    \n" 
     + " baseColor = texture2D(s_baseMap, v_Color); \n" 
     + " gl_FragColor = baseColor;  \n"  
     + "}        \n"; 

Nó không bao giờ làm bất cứ điều gì với alpha rõ ràng, nó là từ một ví dụ mà không sử dụng nó sau khi tất cả, nhưng tôi vẫn không biết nhiều về bóng đổ mảnh và bởi vì nó dường như "loại" làm việc khi nó pha trộn hình ảnh vào nền, tôi figured nó đã được làm việc với alpha trong một số hình thức và tôi chỉ có một cái gì đó đặt sai.

EDIT :: Đây là phương thức "loadTexture". Nó gần như giống như ví dụ từ cuốn sách OpenGL ES 2.0 mà tôi đang cố gắng học hỏi, với một vài thay đổi dường như làm cho hình ảnh gần hơn để hoạt động đúng cách.

private int loadTexture (InputStream is) 
{ 
    int[] textureId = new int[1]; 
    Bitmap bitmap; 
    bitmap = BitmapFactory.decodeStream(is); 
    byte[] buffer = new byte[bitmap.getWidth() * bitmap.getHeight() * 4]; 

    for (int y = 0; y < bitmap.getHeight(); y++) 
     for (int x = 0; x < bitmap.getWidth(); x++) 
     { 
      int pixel = bitmap.getPixel(x, y); 
      buffer[(y * bitmap.getWidth() + x) * 4 + 0] = (byte)((pixel >> 16) & 0xFF); 
      buffer[(y * bitmap.getWidth() + x) * 4 + 1] = (byte)((pixel >> 8) & 0xFF); 
      buffer[(y * bitmap.getWidth() + x) * 4 + 2] = (byte)((pixel >> 0) & 0xFF); 
     } 

    ByteBuffer byteBuffer = ByteBuffer.allocateDirect(bitmap.getWidth() * bitmap.getHeight() * 4); 
    byteBuffer.put(buffer).position(0); 

    GLES20.glGenTextures (1, textureId, 0); 
    GLES20.glBindTexture (GLES20.GL_TEXTURE_2D, textureId[0]); 

    GLES20.glTexImage2D (GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, bitmap.getWidth(), bitmap.getHeight(), 0, 
          GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, byteBuffer); 

    GLES20.glTexParameteri (GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR); 
    GLES20.glTexParameteri (GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR); 
    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); 

    return textureId[0]; 
} 

Tôi hiểu mã đang làm gì, nhưng phải thừa nhận rằng nó vẫn làm tôi bối rối vì vậy tôi có thể thiếu điều gì đó hiển nhiên do thiếu kiến ​​thức.

Tôi không thấy bất kỳ phần nào khác trong mã của tôi có vẻ như gây ra vấn đề mà tôi đang gặp phải, nhưng lập trình luôn đầy bất ngờ (Đặc biệt trong thế giới OpenGL) nghĩ điều gì đó khác là nguyên nhân tôi chắc chắn sẽ đăng bài đó cho bạn. Xin lỗi cho tất cả những rắc rối!

+0

Đảm bảo kênh alpha từ PNG được giữ nguyên khi tải ảnh vào kết cấu (thay vì tải ảnh RGB hoặc tạo kết cấu RGB). Và tất nhiên hãy chắc chắn bạn gọi 'glEnable (GL_BLEND)' (ngoài việc thiết lập 'glBlendFunc' đúng). Nhưng một số mã chắc chắn sẽ giúp đỡ nhiều hơn một chút để giúp bạn. Có lẽ chỉ là hình ảnh tải và kết cấu tạo mã và mã nơi bạn thiết lập trạng thái pha trộn. Và tất nhiên, vì bạn mới ở đây, đừng quên thông báo cho chính mình về các tính năng chấp nhận và bỏ phiếu. –

+0

Trình đổ bóng phân đoạn có vẻ hợp lệ, vì nó ủy quyền chính xác độ phân giải của kết cấu cho màu sắc phân đoạn. Vì vậy, bạn sẽ không nhận được xung quanh đăng một số tải của bạn và tạo mã kết cấu. –

+0

Bạn có thể thử 'gl_FragColor = vec4 (baseColor.aaa, 1.0)' với tính năng trộn bị tắt. Điều này sẽ cho bạn hình ảnh màu xám của kênh alpha. – trenki

Trả lời

3

Bạn rất có thể muốn sử dụng hàm glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) làm hàm pha trộn và bạn phải đảm bảo ghi giá trị alpha của kết cấu vào biến đầu ra của trình tạo bóng đổ gl_FragColor.

Đối với tất cả mọi thứ để làm việc dữ liệu kết cấu được tải lên của bạn phải chứa giá trị alpha và bạn phải sử dụng định dạng kết cấu hỗ trợ kênh alpha (RGBA, RGBA8, v.v.).

Bạn có thể xác minh điều này bằng cách chỉ định tuyến giá trị alpha cho các thành phần màu RGB và kiểm tra hình ảnh mà bạn nhận được.

EDIT:

Trong mã tải hình ảnh của bạn, bạn quên để sao chép trên các kênh alpha! Hãy thử đề xuất rằng davebytes cung cấp.

+0

Nếu tôi sử dụng thiết lập đó trên glBlendFunc, hình ảnh sẽ không hiển thị. Có vẻ như glBlendFunc (GL_ONE, GL_ONE_MINUS_SRC_ALPHA) hoạt động tốt nhất cho tôi, hoặc ít nhất là gần nhất để làm việc như nó cần. Tôi cũng nên đề cập rằng khi hình ảnh được pha trộn vào nền, nó dường như loại bỏ các phần trong suốt của hình ảnh quá. Tôi tin rằng sự cố của tôi nằm trong trình đổ bóng phân đoạn, bởi vì tôi chưa biết nhiều về nó và nó chủ yếu là bản sao mã từ ví dụ không sử dụng tính minh bạch. Tôi sẽ đăng nó trong bài chính. – DaeKo

1

trình đổ bóng ban đầu của bạn là tốt. alpha vốn có trong các op màu, nó chỉ có thể không được áp dụng tùy thuộc vào blend/mode/etc.

cho rằng kết cấu của bạn có màu đen nếu bạn làm fragcolor = base.aaa, điều đó ngụ ý rằng dữ liệu kết cấu của bạn là 'xấu'.

nhìn vào tải kết cấu của bạn, vâng, đó là sai. bạn không bao giờ sao chép qua alpha, chỉ là rgb. giả sử java xóa mảng byte thành 0s, tất cả alpha sẽ là số không, điều đó sẽ giúp bạn có được hộp đen của bạn, điều đó sẽ làm cho hình ảnh 'biến mất' khi bạn bật trộn alpha.

Để đơn giản hóa cuộc sống của bạn, thay vì tất cả việc sao chép tay và các công cụ, bạn chỉ có thể tải bitmap thông thường và sử dụng GLUtils helper để tải lên thay vì trực tiếp sử dụng glTexImage2d:

bitmap = BitmapFactory.decodeStream(is); 
    GLES20.glGenTextures (1, textureId, 0); 
    GLES20.glBindTexture (GLES20.GL_TEXTURE_2D, textureId[0]); 
    GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0); 

Something như thế. Sau đó, cho phép pha trộn, sử dụng chế độ hòa trộn src + invsrc nếu không được bắt đầu, và kết xuất, bạn sẽ nhận được kết quả mong muốn.

9

Thay đổi

for (int y = 0; y < bitmap.getHeight(); y++) 
    for (int x = 0; x < bitmap.getWidth(); x++) 
    { 
     int pixel = bitmap.getPixel(x, y); 
     buffer[(y * bitmap.getWidth() + x) * 4 + 0] = (byte)((pixel >> 16) & 0xFF); 
     buffer[(y * bitmap.getWidth() + x) * 4 + 1] = (byte)((pixel >> 8) & 0xFF); 
     buffer[(y * bitmap.getWidth() + x) * 4 + 2] = (byte)((pixel >> 0) & 0xFF); 
    } 

vào

for (int y = 0; y < bitmap.getHeight(); y++) 
    for (int x = 0; x < bitmap.getWidth(); x++) 
    { 
     int pixel = bitmap.getPixel(x, y); 
     buffer[(y * bitmap.getWidth() + x) * 4 + 0] = (byte)((pixel >> 16) & 0xFF); 
     buffer[(y * bitmap.getWidth() + x) * 4 + 1] = (byte)((pixel >> 8) & 0xFF); 
     buffer[(y * bitmap.getWidth() + x) * 4 + 2] = (byte)((pixel >> 0) & 0xFF); 
     buffer[(y * bitmap.getWidth() + x) * 4 + 3] = (byte)((pixel >> 24) & 0xFF); 
    } 

để bao gồm các thông tin alpha sau đó chỉ cần thêm

GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA); 
GLES20.glEnable(GLES20.GL_BLEND); 

ngay trước khi bạn rút ra những kết cấu. Hãy nhớ vô hiệu hóa GL_BLEND khi bạn đã hoàn tất.