2013-05-12 40 views
5

Tôi đang cố gắng thực hiện một số kết xuất OpenGL ES 2.0 cho tệp hình ảnh, độc lập với hiển thị được hiển thị trên màn hình cho người dùng. Hình ảnh tôi đang hiển thị là kích thước khác với màn hình của người dùng. Tôi chỉ cần một mảng byte dữ liệu GL_RGB. Tôi quen thuộc với glReadPixels, nhưng tôi không nghĩ rằng nó sẽ làm các trick trong trường hợp này kể từ khi tôi không kéo từ một màn hình người dùng đã được trả lại.Làm cho OpenGL ES 2.0 thành hình ảnh

Mã giả:

// Switch rendering to another buffer (framebuffer? renderbuffer?) 

// Draw code here 

// Save byte array of rendered data GL_RGB to file 

// Switch rendering back to user's screen. 

Làm thế nào tôi có thể làm điều này mà không làm gián đoạn màn hình của người dùng? Tôi không muốn phải nhấp nháy màn hình của người dùng, vẽ thông tin mong muốn của tôi cho một khung hình duy nhất, glReadPixel-ing và sau đó làm cho nó biến mất.

Một lần nữa, tôi không muốn nó hiển thị bất cứ điều gì cho người dùng. Đây là mã của tôi. Không hoạt động .. Tôi đang thiếu một cái gì đó?

unsigned int canvasFrameBuffer; 
bglGenFramebuffers(1, &canvasFrameBuffer); 
bglBindFramebuffer(BGL_RENDERBUFFER, canvasFrameBuffer); 
unsigned int canvasRenderBuffer; 
bglGenRenderbuffers(1, &canvasRenderBuffer); 
bglBindRenderbuffer(BGL_RENDERBUFFER, canvasRenderBuffer); 
bglRenderbufferStorage(BGL_RENDERBUFFER, BGL_RGBA4, width, height); 
bglFramebufferRenderbuffer(BGL_FRAMEBUFFER, BGL_COLOR_ATTACHMENT0, BGL_RENDERBUFFER, canvasRenderBuffer); 

unsigned int canvasTexture; 
bglGenTextures(1, &canvasTexture); 
bglBindTexture(BGL_TEXTURE_2D, canvasTexture); 
bglTexImage2D(BGL_TEXTURE_2D, 0, BGL_RGB, width, height, 0, BGL_RGB, BGL_UNSIGNED_BYTE, 0); 
bglFramebufferTexture2D(BGL_FRAMEBUFFER, BGL_COLOR_ATTACHMENT0, BGL_TEXTURE_2D, canvasTexture, 0); 

Matrix::matrix_t identity; 
Matrix::LoadIdentity(&identity); 
bglClearColor(1.0f, 1.0f, 1.0f, 1.0f); 
bglClear(BGL_COLOR_BUFFER_BIT); 
Draw(&identity, &identity, this); 
bglFlush(); 
bglFinish(); 

byte *buffer = (byte*)Z_Malloc(width * height * 4, ZT_STATIC); 
bglReadPixels(0, 0, width, height, BGL_RGB, BGL_UNSIGNED_BYTE, buffer); 
SaveTGA("canvas.tga", buffer, width, height); 
Z_Free(buffer); 

// unbind frame buffer 
bglBindRenderbuffer(BGL_RENDERBUFFER, 0); 
bglBindFramebuffer(BGL_FRAMEBUFFER, 0); 
bglDeleteTextures(1, &canvasTexture); 
bglDeleteRenderbuffers(1, &canvasRenderBuffer); 
bglDeleteFramebuffers(1, &canvasFrameBuffer); 
+0

Tôi tìm thấy một số thông tin về làm-to -texture, nhưng tôi không chắc đó là những gì tôi muốn, vì tôi muốn kết xuất bằng te mảng để lưu/phân tích dữ liệu hình ảnh. Tôi tò mò muốn biết con đường chính xác là gì. – user1054922

+1

Liệu bộ đệm có kết thúc trên màn hình hay không, GPU vẫn phải hiển thị. Không có cách nào để hiển thị offscreen không ảnh hưởng đến hiệu suất ... –

+0

Tôi không nói về ảnh hưởng đến hiệu suất, tôi đang nói về việc không hiển thị bất kỳ điều gì cho người dùng (ví dụ: nhấp nháy) – user1054922

Trả lời

4

Dưới đây là các giải pháp, cho bất cứ ai cần nó:

// Create framebuffer 
unsigned int canvasFrameBuffer; 
glGenFramebuffers(1, &canvasFrameBuffer); 
glBindFramebuffer(GL_RENDERBUFFER, canvasFrameBuffer); 

// Attach renderbuffer 
unsigned int canvasRenderBuffer; 
glGenRenderbuffers(1, &canvasRenderBuffer); 
glBindRenderbuffer(GL_RENDERBUFFER, canvasRenderBuffer); 
glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA4, width, height); 
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, canvasRenderBuffer); 

    // Clear the target (optional) 
glClearColor(1.0f, 1.0f, 1.0f, 1.0f); 
glClear(GL_COLOR_BUFFER_BIT); 

    // Draw whatever you want here 

char *buffer = (char*)malloc(width * height * 3); 
glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, buffer); 
SaveTGA("canvas.tga", buffer, width, height); // Your own function to save the image data to a file (in this case, a TGA) 
free(buffer); 

// unbind frame buffer 
glBindRenderbuffer(GL_RENDERBUFFER, 0); 
glBindFramebuffer(GL_FRAMEBUFFER, 0); 
glDeleteRenderbuffers(1, &canvasRenderBuffer); 
glDeleteFramebuffers(1, &canvasFrameBuffer); 
+0

Bạn có thể vui lòng cho biết bạn sẽ làm gì nếu chiều rộng/chiều cao lớn hơn GL_MAX_RENDERBUFFER_SIZE? Vì vậy, nó không thể tạo renderbuffer kích thước mong muốn ... – XZen

+0

Tôi không thể làm cho nó hoạt động trên Linux. BGL_RGBA4, ZT_CACHE và Z_MALLOC, SAVE_TGA, Z_FREE là gì? –

+0

Xin lỗi, đây là những chức năng tôi đã tạo. Tôi đã chỉnh sửa bài đăng của mình để thay thế chúng bằng các tiêu chuẩn tương đương. – user1054922

1

Bạn có thể hiển thị kết cấu, đọc pixel và vẽ hình tứ giác có kết cấu đó (nếu bạn muốn hiển thị cho người dùng). Nó không nên nhấp nháy nhưng nó làm giảm hiệu suất rõ ràng.

Trên iOS ví dụ:

+0

Đã cập nhật bài đăng với một số mã tôi đang cố gắng hiển thị với kết cấu không có màn hình. – user1054922

+0

Cập nhật câu trả lời của tôi với một số câu hỏi có liên quan với câu trả lời tại stackoverflow. – Trax

+0

Tôi không thấy lệnh gọi hàm glBindFramebuffer, bên trong Draw? – Trax

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