2012-06-11 64 views
5

Tôi đã làm việc trên một dự án mà trong đó người dùng có thể tương tác với một số GLSurfaceView để vẽ hình trên màn hình. Điều này tất cả hoạt động tốt và dandy, nhưng bây giờ tôi đang cố gắng làm hai việc: 1) tạo ra một hình thu nhỏ của bản vẽ của họ, và 2) lưu bản vẽ của họ. Điều quan trọng cần lưu ý là người dùng có thể vẽ hình ảnh lớn hơn màn hình. Theo như nghiên cứu của tôi, điều này đạt được tốt nhất khi sử dụng Bitmap (có thể là 1) được hiển thị cho một hình thu nhỏ và 2) được lưu vào hệ thống tệp, đạt được cả hai mục tiêu của tôi).Buộc OpenGL Buffer sử dụng GL 1.0 hoặc 1.1?

Ban đầu, tôi đã cố gắng đọc số Renderer từ số GLSurfaceView qua glReadPixels, nhưng hóa ra tôi không thể lấy dữ liệu ngoài màn hình từ điều này. Thay vào đó, tôi đã chọn thực hiện một bộ đệm ngoài màn hình để tạo ra kết xuất của hình ảnh, có thể được chuyển đổi thành Bitmap.

Tôi đã tìm thấy lovely post cung cấp mã cho một lớp có tên là PixelBuffer mà tôi hiện đang sử dụng. (Tôi đã thực hiện một vài chỉnh sửa, nhưng tất cả các vấn đề tôi đã xảy ra có hoặc không có chỉnh sửa đã nói.)

Bây giờ, khi sử dụng mã getBitmap() (mà tôi sẽ đăng bên dưới) trong trường hợp chủ đề diễn đàn PixelBuffer là không đọc được), tôi nhận được một bó của called unimplemented OpenGL ES API. Điều này làm tôi giật mình lúc đầu, vì vậy tôi đã làm một số điều tra. Hóa ra, vì lý do nào đó, lớp học PixelBuffer đang sử dụng OpenGL ES 2.0, trong khi GLSurfaceView đang sử dụng OpenGL ES 1.1. Thiết bị tôi đang sử dụng (Galaxy Nexus) không hỗ trợ 2.0. (Và hơn nữa, tôi muốn hỗ trợ nhiều loại thiết bị nhất có thể.)

Vì vậy, đây là câu hỏi của tôi: Làm cách nào để sử dụng API OpenGL ES 1.1? Tôi đã thêm thông tin sau trong Tệp kê khai của mình:

<uses-feature android:glEsVersion="0x00010001" /> 

Ngoài ra, tôi đã cố gắng đặt phiên bản bằng cách sử dụng int[] version = new int[] { 1, 1 };, không có kết quả.

Mã số PixelBuffer Tôi đang sử dụng: Link. Dòng đang đề cập đến gọi là Renderer là trên dòng 91. Mã phiên bản nằm trên dòng 39-ish trở đi.

Đây là mã tôi sử dụng để tạo ra các PixelBuffer, được gọi là từ GLSurfaceView đối tượng:

setEGLConfigChooser(8, 8, 8, 8, 0, 0); 
    mRenderer = new MyRenderer(this); 
    setRenderer(mRenderer); 
    mPixelBuffer = new CPPixelBuffer(1440, 1280); // TODO Temporary hardcode for Galaxy Nexus wallpaper size 
    mPixelBuffer.setRenderer(mRenderer); 

Nếu nó không phải là có thể sử dụng phiên bản 1.1 cho một offscreen render, là những cách tốt nhất để chuyển đổi của tôi GL bề mặt để một Bitmap sử dụng phiên bản 1.1 hoặc thấp hơn?

EDIT: Thông qua một số thử nghiệm, tôi phát hiện ra rằng việc sử dụng mã dưới đây gây ra các lỗi này:

// int[] version = new int[2]; 
int[] version = new int[] { // When using this line, as well as the other marked lines, instead of the line above, the errors are produced. 
    1, 1 // Marked 
}; // Marked 
int[] attribList = new int[] { 
    EGL_WIDTH, mWidth, 
    EGL_HEIGHT, mHeight, 
    EGL_VERSION, 1, // Marked 
    EGL_NONE 
}; 

06-11 15:41:52.316: E/libEGL(5618): eglMakeCurrent:674 error 3009 (EGL_BAD_MATCH) 
06-11 15:41:52.316: E/libEGL(5618): call to OpenGL ES API with no current context (logged once per thread) 

Tuy nhiên, không ai trong số những thiết lập làm giảm bớt vấn đề này trong tầm tay. Chúng chỉ vừa hiện diện trong mã PasteBin của tôi, nên tôi nghĩ sẽ tốt hơn nếu chỉ ra nó.

+0

Thực ra Galaxy Nexus hỗ trợ OpenGL ES 2.0 tốt. Cuộc gọi chức năng nào chính xác cung cấp cho bạn "API OpenGL ES chưa được triển khai"? Nếu đó là PBufferSurface sáng tạo, sau đó cố gắng sử dụng các thuộc tính khác nhau cho nó. Hoặc tốt hơn là bỏ qua nó, và sử dụng glGreadPixels từ framebuffer. –

+0

Tất cả các phương thức (trong lệnh gọi 'onDrawFrame') đưa nó cho tôi. Ngay cả 'gl.glLoadIdentity()'; cửa sổ của tôi theo nghĩa đen bị spam. Đó là không có gì cụ thể 2.0, đó là lý do tại sao điều này rất lạ với tôi. _ (Tuy nhiên, điều này không giải quyết được vấn đề đối với các thiết bị tương thích 1.1 cũ hơn ...) _ – Eric

+0

Bạn có ngữ cảnh GL được tạo cho chuỗi nơi bạn đang gọi các hàm gl ...? –

Trả lời

2

Tôi không tìm thấy lý do nào đó liên kết để đăng nhận xét, vì vậy xin lỗi vì đã đăng câu trả lời này làm câu trả lời.Về chủ đề GL, thông thường bạn chỉ có trong chủ đề GL trong

public void onDrawFrame(GL10 gl) 

Phương pháp nào của Trình kết xuất. Tất cả mọi thứ phải được thực hiện bên trong phương pháp này. Bạn có thể chỉ cần đặt một boolean, cho phép nói, vào renderer, và thiết lập nó thành true khi bạn muốn một cái gì đó được thực hiện trong renderer, và đó là nó. Nếu bạn thực hiện bất kỳ cuộc gọi nào bên ngoài phương thức này, bạn sẽ nhận được lệnh xóa.

Ngoài ra, hãy nhìn vào ví dụ này: Android OpenGL Screenshot Tôi đã sử dụng nó và nó làm việc cho tôi, nhưng tôi không cần phải tiết kiệm diện tích tắt màn hình, vì vậy tôi không biết nếu nó sẽ làm việc, có lẽ không :)

Phương thức phải được gọi bên trong onDrawFrame

+0

Ngay cả với đối tượng 'GL10' hợp lệ được truyền vào nó? Nó chỉ cần piggy-back trên mã hóa của Renderer (hầu hết trong số đó là bởi tôi, không phải từ lớp 'Renderer'), và render vào đối tượng GL của nó. – Eric

+0

Bạn có nghĩa là một phương pháp khác trong chủ đề khác nhau? Nếu có, thì có, bạn sẽ không thể sử dụng ngay cả khi bạn đã vượt qua một đối tượng GL10 hợp lệ. Bạn phải sử dụng nó chỉ ở đó. Hãy tưởng tượng làm thế nào tất cả các trò chơi được viết: có một vòng lặp trong khi tất cả mọi thứ được thực hiện. Tính toán toán học ví dụ có thể được thực hiện trong các chủ đề khác, nhưng bạn xử lý các kết quả trong chủ đề mà bạn render, và các đối tượng GL là hợp lệ trong các chủ đề rendering, như GL đối tượng quá. Android thông minh hơn và chỉ cho bạn điều này, trong C++ bạn sẽ chỉ nhận được sự cố hoặc vi phạm truy cập :) – XMight

+0

Cả hai đều chia sẻ cùng một chuỗi GL. Về cơ bản, nó là đối tượng thứ hai ('PixelBuffer') có' Renderer' làm biến thành viên; họ chia sẻ một chủ đề và một ngữ cảnh. Về cơ bản nó gọi 'mRenderer.onDrawFrame ()'. – Eric

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