2012-02-14 37 views
6

(Chỉnh sửa: Tôi đã thử một mẫu chỉ vẽ một hình tam giác mà không có bất kỳ kết cấu hoặc đổ bóng nào và chỉ có OpenGL-ES 1.1 trên thiết bị của tôi và có thể thấy cùng một hiện vật. Tôi đã thử cùng một mẫu trong trình giả lập và không có hiện vật nào ở đó Có thể đây là một vấn đề Tegra 2 hay tôi cần phải thiết lập một trạng thái cụ thể hoặc cái gì đó không cần thiết trong trình mô phỏng?)Tại sao màu pixel không chính xác trong OpenGL ES 2.0 trên Android?

Tôi vẽ một hình vuông chính xác pixel trên màn hình nhưng khi tôi tạo ra một màn hình và nhìn vào điểm ảnh sau đó một số trong số đó là hơi tắt như antialised hoặc lọc hoặc một cái gì đó như thế. Bạn chỉ nhìn thấy nó khi bạn phóng to chúng nhưng đó không phải là điểm. Tôi muốn làm một số toán trong trình đổ bóng pixel và nếu các điểm ảnh hơi bị tắt và điều đó không tốt với tôi. Tôi cần chúng chính xác như trong bitmap tôi đặt chúng vào.

Dưới đây là một screengrab mở rộng của vấn đề. Khoảng Line trắng các giá trị tối hơi sáng hơn họ sẽ:

enter image description here

Tôi đã cố gắng:

GLES20.glDisable(GLES20.GL_DITHER); 
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); 
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); 

nhưng nó không có hiệu lực. Các pixel chỉ hơi tắt. Nó dễ dàng nhìn thấy giữa một điểm ảnh tối và trắng bởi vì điểm ảnh tối bên cạnh nó hơi sáng hơn và kiểm tra giá trị r, g, b với một chương trình vẽ cho tôi thấy điều đó.

Có thể ai đó vui lòng hỗ trợ tôi với điều này không?

Một số thông tin khác:

CPU của thiết bị của tôi là Tegra 2.0. Tôi làm cho một hình vuông 256x256 chính xác vào 256x256 pixel (tôi đã kiểm tra bằng cách lấy một màn hình lấy với nhật thực DDMS). Độ trong suốt bị tắt và bitmap có giá trị alpha là 255 cho mỗi pixel. Tôi tạo ra các bề mặt như một bề mặt 32bit với alpha với:

glSurface.setEGLConfigChooser(8, 8, 8, 8, 0, 0); 

tôi đơn giản hóa mã nhưng vẫn có thể thấy vấn đề khi tôi làm với shaders sau:

String vshaderquad = "attribute vec4 a_pos;    \n" + // in  position 
          "attribute vec2 a_tex;    \n" + // in  Texture coordinates 
          "varying vec2 vtex;     \n" + // out  Texture coordinates 
          "void main(void) {     \n" + 
          " gl_Position = vec4(a_pos);  \n" + 
          " vtex = a_tex;     \n" + 
          "}"; 

    String fshaderquad = "precision mediump float;      \n" + 
          "varying vec2  vtex;      \n" + 
          "uniform sampler2D samp0;      \n" + 
          "void main() {         \n" + 
          " gl_FragColor = texture2D(samp0, vtex);  \n" + 
          "}"; 

và lệnh:

GLES20.glActiveTexture(GLES20.GL_TEXTURE0); 
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mapid[0]); 
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); 
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); 
GLES20.glUniform1i(handlesampler0, 0); 
GLES20.glDisable(GLES20.GL_DITHER); 



GLES20.glViewport(0, 0, screenx, screeny); 

float screenx = (float)ddimx; 
float screeny = (float)ddimy; 
// 
vdata.put(0*4+0,  0.0f * (2.0f/screenx)); 
vdata.put(0*4+1, 256.0f * (2.0f/screeny)); 
vdata.put(0*4+2,  0.0f * (1.0f/256f)); 
vdata.put(0*4+3, 256.0f * (1.0f/256f)); 
// 
vdata.put(1*4+0,  0.0f * (2.0f/screenx)); 
vdata.put(1*4+1,  0.0f * (2.0f/screeny)); 
vdata.put(1*4+2,  0.0f * (1.0f/256f)); 
vdata.put(1*4+3,  0.0f * (1.0f/256f)); 
// 
vdata.put(2*4+0, 256.0f * (2.0f/screenx)); 
vdata.put(2*4+1, 256.0f * (2.0f/screeny)); 
vdata.put(2*4+2, 256.0f * (1.0f/256f)); 
vdata.put(2*4+3, 256.0f * (1.0f/256f)); 
// 
vdata.put(3*4+0, 256.0f * (2.0f/screenx)); 
vdata.put(3*4+1,  0.0f * (2.0f/screeny)); 
vdata.put(3*4+2, 256.0f * (1.0f/256f)); 
vdata.put(3*4+3,  0.0f * (1.0f/256f)); 

GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4); 

PS: Sự thay đổi màu sắc nhẹ không thực sự nhìn thấy được nếu không phóng to cực đại nhưng tôi muốn thực hiện các phép tính với các giá trị và điều đó có nghĩa là chúng phải chính xác.

Chỉnh sửa: Tôi đã thêm hình ảnh có độ phân giải đầy đủ. Các màu trên các đường thẳng phải từ (0,0,0) đến (255,255,255) và nghịch đảo với độ dốc nền. Tôi đã thực hiện hình ảnh này chỉ để kiểm tra độ chính xác của kết cấu và ở đó tôi thấy vấn đề không thực sự chính xác. Bạn phải phóng to mặc dù để tạo ra sự khác biệt đó là lý do tại sao tôi đăng hình ảnh mở rộng là tốt. Lưu ý: Các tọa độ khác với mã được đăng ở trên nhưng vấn đề là như nhau (tôi đã thử các tọa độ trên màn hình khác nhau và sự cố vẫn tiếp diễn).

enter image description here

+0

Một Screengrab sẽ là tuyệt vời để hiển thị các vấn đề, nhưng từ những gì bạn viết tôi nghi ngờ nó [dither] (http://www.curious-creature.org/2010/12/08/bitmap-quality-banding-and-dithering/). Đó là một quá trình hậu xử lý, vì vậy nó không ảnh hưởng đến trình tối ưu hóa pixel của bạn. –

+0

Xin chào, cảm ơn bạn đã trả lời và tôi đã thêm hình ảnh để hiển thị tốt hơn vấn đề. Tôi cũng không nghĩ rằng nó chỉ là một lỗi hậu xử lý bởi vì tôi thực hiện một số tính toán trong các shader và các giá trị mong đợi đã được tắt và chỉ ra rằng đó là vấn đề. – HardCoder

+0

Tôi hỏi là một ứng dụng Android: có cách nào bạn đang sử dụng màn hình PenTile và đọc lại các màu được tính toán từ các phần tử hiển thị thực tế không? – Tommy

Trả lời

3

Ok, tôi nghĩ mình đã tìm được giải pháp.

Như tôi đã viết, tôi đã thực hiện một ảnh chụp màn hình với nhật ký DDMS và điều đó dường như đang gây ra sự cố. Ảnh chụp màn hình đó không phải là framebuffer chính xác nhưng một số loại làm mịn/chống răng cưa đang diễn ra ở đó.

Điều này có vẻ không phải là kết quả của DDMS mà chỉ xuất hiện khi được sử dụng trên thiết bị thực tế của tôi. Khi tôi thử nó với giả lập rằng vấn đề không xuất hiện nên có thể thiết bị của tôi có màn hình năm (nó chỉ được phát hành ở Nhật Bản và tôi không tìm thấy thông tin nào để xác nhận hay phủ nhận nó, nhưng sony và sony của nó sử dụng màn hình pentile trong các thiết bị) hoặc có thể nó phải làm với chip tegra 2 hoặc có thể là một loại nén nào đó xảy ra khi hình ảnh đang được truyền hoặc có thể vì một lý do nào đó hoàn toàn. Dù bằng cách nào, khi tôi sử dụng chức năng sau đây, tôi có thể lưu ảnh chụp màn hình hoàn toàn hoàn hảo vì nó có bộ đệm Framebuffer OpenGL-ES 2.0 và lưu nó vào một tệp png mà sau đó tôi có thể dễ dàng chuyển với một tệp hàng loạt ("adb kéo /mnt/sdcard/info/Testfile.txt ") và xem trên máy tính của tôi:

public boolean SaveFrameBuffer(int x, int y) 
{ try 
    { IntBuffer pinbuffer = IntBuffer.allocate(x*y*4); 
     IntBuffer poutbuffer = IntBuffer.allocate(x*y*4); 
     int   i,j,z; 
     int []  pin   = pinbuffer.array(); 
     int []  pout  = poutbuffer.array(); 
     // 
     GLES20.glReadPixels(0, 0, x, y, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, pinbuffer);    
     for(i=0;i<y;i++) 
     { for(j=0;j<x;j++) 
      { z = pin[(y-1-i)*x+j]; 
       pout[i*x+j] = (z & 0xff000000) | ((z >> 16) & 0x000000ff) | ((z << 16) & 0x00ff0000) | (z & 0x0000ff00); 
      } 
     } 
     Bitmap map = Bitmap.createBitmap(x, y, Bitmap.Config.ARGB_8888); 
     map.setPixels(pout, 0, x, 0,0, x, y); 
     OutputStream stream = new FileOutputStream("/sdcard/info/test.png"); 
     map.compress(CompressFormat.PNG, 100, stream); 
     stream.close(); 
     return true; 
    } catch (Exception e) 
    { e.printStackTrace(); 
     return false; 
    } 
} 
Các vấn đề liên quan