2013-06-09 23 views
6

Tôi đang gặp phải tình huống sau:Bề mặt nào để sử dụng cho eglMakeCurrent cho ngữ cảnh chỉ hiển thị trong FBOs

Trong thư viện kết xuất nền tảng cho iOS và Android (viết bằng c (++)), tôi có hai chủ đề mà mỗi nhu cầu của riêng mình EGLContext: Chủ đề A là chủ đề chính; nó ám chỉ đến cửa sổ. Chủ đề B là một luồng máy phát điện, có tính toán khác nhau và hiển thị kết quả thành các kết cấu mà sau này được sử dụng bởi chủ đề A.

Vì tôi không thể sử dụng EGL trên iOS, thư viện sử dụng các con trỏ hàm tới tĩnh Obj.- C chức năng để tạo ra một bối cảnh mới và thiết lập nó hiện tại. này đã hoạt động, tôi tạo ra bối cảnh cho thread sử dụng

EAGLContext *contextA = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; 

Bối cảnh cho thread B được tạo ra sử dụng

EAGLContext *contextB = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2 sharegroup:[contextA sharegroup]]; 

sau đó tôi có thể thiết lập một trong hai dòng:

[EAGLContext setCurrentContext:context]; 

Để sử dụng cùng một logic (con trỏ hàm được chuyển đến thư viện) trên Android, tôi muốn thực hiện điều này ở phía C của các liên kết JNI, lần này sử dụng EGL thực thay vì EAGL của Apple. Tôi có thể dễ dàng tạo bối cảnh bằng cách sử dụng WindowSurface và Cửa sổ gốc, tôi có thể tạo contextB và chuyển contextA đến tham số shareContext của cuộc gọi eglCreateContext.

Nhưng khi tôi muốn làm cho contextB hiện tại, tôi phải vượt qua một bề mặt cho cuộc gọi eglMakeCurrent, và tôi đang cố gắng tìm ra loại bề mặt để vượt qua ở đó.

  • tôi không thể sử dụng WindowSurface tôi sử dụng cho contextA như spec nói trong phần 3.7 rằng "Tại nhiều nhất một bối cảnh cho từng API khách hàng được hỗ trợ có thể hiện tại đến một chủ đề cụ thể tại một thời điểm nhất định, và nhiều nhất là một bối cảnh có thể bị ràng buộc vào một bề mặt cụ thể tại một thời điểm nhất định. "
  • Tôi không thể chỉ định EGL_NO_SURFACE, vì điều đó sẽ dẫn đến lỗi EGL_BAD_MATCH trong cuộc gọi eglMakeCurrent.
  • Có vẻ như tôi có thể sử dụng bề mặt PBuffer, nhưng tôi do dự vì tôi phải chỉ định chiều rộng và chiều cao khi tạo bề mặt như vậy và chuỗi B có thể muốn tạo họa tiết với các kích thước khác nhau. Thêm vào đó, các trạng thái "OpenGL ES 2.0 Programming Guide" của Munshi, Ginsburg và Shreiner nêu trong phần 3.8 rằng "Pbuffers thường được sử dụng nhất để tạo bản đồ kết cấu. Nếu tất cả những gì bạn muốn làm là kết xuất với kết cấu, chúng tôi khuyên bạn nên sử dụng các đối tượng framebuffer [.. .] thay vì pbuffers vì chúng hiệu quả hơn ", đó là chính xác những gì tôi muốn làm trong chủ đề B.

Tôi không hiểu Munshi, Ginsurg và Shreiner có nghĩa là gì bởi câu đó, làm thế nào một bộ đệm khung đối tượng là một sự thay thế cho một bề mặt pbuffer? Điều gì sẽ xảy ra nếu tôi tạo một bề mặt pbuffer rất nhỏ (nói 1x1px) để làm cho ngữ cảnh hiện tại - tôi có thể vẫn hiển thị thành các FBO lớn tùy ý không? Có khả năng nào khác mà tôi chưa biết?

Cảm ơn rất nhiều sự giúp đỡ của bạn!

Trả lời

2

tôi đã kết thúc bằng một bề mặt pBuffer (cỡ 1x1) - i sau đó tạo ra một FBO và đưa vào kết cấu tốt. Để hiển thị chúng (trong một chủ đề khác nhau và một bối cảnh khác nhau (chia sẻ) opengl), tôi sử dụng một cửa sổ với một ANativeWindow (có một mẫu của một nơi nào đó trong sdk).

3

Bề mặt bạn chuyển đến eglMakeCurrent() phải là bề mặt EGL từ eglCreateWindowSurface().Ví dụ:

EGLSurface EglSurface = mEgl.eglCreateWindowSurface(mEglDisplay, maEGLconfigs[0], surfaceTexture, null); 
    mEgl.eglMakeCurrent(mEglDisplay, EglSurface, EglSurface, mEglContext); 

Nhưng, eglCreateWindowSurface() đòi hỏi một SurfaceTexture mà được cung cấp cho onSurfaceTextureAvailable() gọi lại khi một TextureView được tạo ra, nhưng bạn cũng có thể tạo SurfaceTextures tắt màn hình mà không cần bất kỳ View.

Có một ứng dụng ví dụ sử dụng TextureView trong SDK Android ở đây, mặc dù nó sử dụng SurfaceTexture cho video camera chứ không phải là OpenGL ES rendering:

sources\android-17\com\android\test\hwui\GLTextureViewActivity.java 

Theo mặc định, bề mặt EGL cho FBOs sẽ có cùng kích thước với SurfaceTexture mà chúng được tạo ra từ đó. Bạn có thể thay đổi kích thước của SurfaceTexture bằng:

surfaceTexture.setDefaultBufferSize(width, height); 

Không sử dụng pbuffers trên Android vì một số nền tảng (Nvidia Tegra) không hỗ trợ chúng. Bài viết này giải thích những ưu điểm của FBOs qua pbuffers một cách chi tiết:

http://processors.wiki.ti.com/index.php/Render_to_Texture_with_OpenGL_ES

+1

Ông có thể vui lòng giải thích làm thế nào bạn có thể tạo một SurfaceTexture tắt màn hình mà không cần bất kỳ quan điểm? Tôi biết đó là một câu hỏi rộng, nhưng chỉ một vài gợi ý là đủ. –

+0

Về cơ bản, bạn sử dụng toán tử mới, như sau: mSurfaceTexture = new SurfaceTexture (1); mSurfaceTexture.setDefaultBufferSize (miMaxWidth, miMaxHeight); – ClayMontgomery

+0

Điều này có thể được thực hiện từ mã gốc không? Tôi đã cố gắng sử dụng SurfaceTexture (bao gồm tiêu đề từ khung công tác/native/include/gui/SurfaceTexture.h) nhưng tôi vẫn nhận được một lỗi biên dịch: không thể tìm thấy khai báo SurfaceTexture trong phạm vi này. –

0

Nếu vẽ FBO là thứ duy nhất bạn muốn làm, bạn có thể lấy bất kỳ EGLContext nào do bạn hoặc người khác tạo ra (ví dụ: GLSurfaceView) và làm cho nó hiện tại thì bạn chỉ cần tạo FBO của bạn rồi vẽ với nó. Vấn đề là cách chia sẻ ngữ cảnh được tạo bởi GLSurfaceView với thư viện đa nền tảng C++ của bạn. Tôi đã làm điều này bằng cách gọi một hàm tĩnh bên trong C++ để lấy eglcontext và bề mặt ngay lập tức sau khi bối cảnh được tạo ra bởi lớp Java. như mã bên dưới:

//This is a GLSurfaceView renderer method 
@override 
public void onSurfaceCreated(GL10 gl, EGLConfig config) { 
    //up to this point, we know the EGLContext 
    //has already been set current on this thread. 
    //call JNI function to setup context 
    graphics_library_setup_context(); 
} 

C++ đối

void setup_context() { 
    context = eglGetCurrentContext(); 
    display = eglGetCurrentDisplay(); 
    surface = eglGetCurrentSurface(EGL_DRAW); 
} 
Các vấn đề liên quan