2011-02-09 36 views
5

Tôi muốn triển khai trình xem thời gian cho phép người dùng phóng to và thu gọn.Sử dụng chỉ mục làm tọa độ trong OpenGL

Tôi đã thực hiện một số chế độ trước mắt ngay trước đây, nhưng điều đó hiện không còn được ưa chuộng vì lợi ích của VBO. Tất cả các ví dụ về VBO tôi có thể tìm thấy các tọa độ XYZ của mỗi cửa hàng và mọi điểm.

Tôi nghi ngờ rằng tôi cần giữ tất cả dữ liệu của mình trong VRAM để nhận được tốc độ khung hình trong khi có thể gọi là "trơn tru", nhưng tôi chỉ có dữ liệu Y (biến phụ thuộc). X là một biến độc lập có thể được tính từ chỉ mục và Z là hằng số. Nếu tôi phải lưu trữ X và Z thì yêu cầu bộ nhớ của tôi (cả kích thước bộ đệm và CPU-> chuyển khối GPU) được tăng gấp ba lần. Và tôi có hàng chục triệu điểm dữ liệu mà người dùng có thể xoay, do đó việc sử dụng bộ nhớ sẽ không nhỏ.

Có một số kỹ thuật để vẽ một mảng đỉnh 1-D hay không, nơi chỉ mục được sử dụng làm tọa độ khác hoặc lưu trữ mảng 1-D (có thể trong kết cấu?) Và sử dụng chương trình đổ bóng để tạo XYZ? Tôi ấn tượng rằng tôi cần một trình đổ bóng đơn giản theo mô hình đường ống cố định-ít tính năng mới để thực hiện mở rộng và dịch, vì vậy nếu tôi có thể kết hợp thế hệ tọa độ X và Z và mở rộng/dịch Y lý tưởng.

Điều này có thể thực hiện được không? Bạn có biết mã mẫu nào không? Hoặc bạn có thể ít nhất là cho tôi một số giả mã nói những gì GL chức năng để gọi theo thứ tự nào?

Cảm ơn!

EDIT: Để đảm bảo điều này là rõ ràng, đây là tương đương đang trực tiếp-mode, và mã mảng đỉnh:

// immediate 
glBegin(GL_LINE_STRIP); 
for(int i = 0; i < N; ++i) 
    glVertex2(i, y[i]); 
glEnd(); 

// vertex array 
struct { float x, y; } v[N]; 
for(int i = 0; i < N; ++i) { 
    v[i].x = i; 
    v[i].y = y[i]; 
} 
glVertexPointer(2, GL_FLOAT, 0, v); 
glDrawArrays(GL_LINE_STRIP, 0, N); 

lưu ý rằng v[] là hai lần kích thước của y[].

Trả lời

4

Điều đó hoàn toàn phù hợp với OpenGL.

Đối tượng đệm Vertex (VBO) có thể lưu trữ bất kỳ thông tin nào bạn muốn theo một định dạng được hỗ trợ GL. Bạn có thể điền một VBO với chỉ một số phối hợp:

glGenBuffers(1, &buf_id); 
glBindBuffer(GL_ARRAY_BUFFER, buf_id); 
glBufferData(GL_ARRAY_BUFFER, N*sizeof(float), data_ptr, GL_STATIC_DRAW); 

Và sau đó ràng buộc định dạng thuộc tính đỉnh thích hợp cho một trận hòa:

glBindBuffer(GL_ARRAY_BUFFER, buf_id); 
glEnableVertexAttribArray(0); // hard-coded here for the sake of example 
glVertexAttribPointer(0, 1, GL_FLOAT, false, 0, NULL); 

Để sử dụng nó, bạn sẽ cần một chương trình đổ bóng đơn giản .Vertex shader thể trông giống như:

#version 130 
in float at_coord_Y; 

void main() { 
    float coord_X = float(gl_VertexID); 
    gl_Position = vec4(coord_X,at_coord_Y,0.0,1.0); 
} 

Trước khi liên kết các chương trình đổ bóng, bạn nên gắn nó at_coord_Y để chỉ số thuộc tính mà bạn sẽ sử dụng (= 0 trong mã của tôi):

glBindAttribLocation(program_id,0,"at_coord_Y"); 

Ngoài ra, bạn có thể yêu cầu chương trình sau khi liên kết cho chỉ mục mà thuộc tính này được gán tự động và sau đó sử dụng nó:

const int attrib_pos = glGetAttribLocation(program_id,"at_coord_Y"); 

Chúc may mắn!

+0

Cảm ơn. Tôi đoán tôi không rõ OpenGL biết tôi muốn 'coord_X' có nghĩa là chỉ số của đỉnh. –

+0

@Ben Voigt: Tôi đã bỏ lỡ bước đầu, xin lỗi :) Câu trả lời đã được sửa ngay bây giờ (sử dụng gl_VertexID). – kvark

+0

Cảm ơn, điều đó đã có ý nghĩa hơn rất nhiều. Và tôi có thể sử dụng 'glDrawArrays' để biểu hiện sự kiện này? Tôi hỏi vì [manpage của 'glDrawArrays'] (http://www.opengl.org/sdk/docs/man/xhtml/glDrawArrays.xml) nói" Nếu GL_VERTEX_ARRAY không được kích hoạt, không có primitives hình học nào được tạo ra. " Điều đó không áp dụng trong thế giới OpenGL 3 nơi các vị trí đỉnh được tạo bởi trình đổ bóng không? –

0

Bạn có lưu trữ mười triệu tọa độ XY, trong VRAM không?

Tôi sẽ đề xuất tính toán các tọa độ đó trên CPU và chuyển chúng vào đường ống đổ bóng như đồng phục (vì tọa độ được cố định với hình ảnh được quét).

Hãy đơn giản.

+0

Khi tôi xoay, tôi cần xóa một số đoạn đường khỏi màn hình đã di chuyển ngoài màn hình, thêm một số đoạn đã được tiết lộ và bù đắp phần còn lại theo hằng số. Thêm một hằng số vào một vài nghìn tọa độ là nhanh chóng trên CPU, nhưng sau đó tôi phải chuyển tất cả dữ liệu vào GPU một lần nữa, và tôi phải làm điều này trên mỗi khung trong khi panning đang diễn ra. Ok, ngay cả ở 60 FPS, nó sẽ không phải là một phần lớn băng thông PCIe, nhưng tại sao lại lãng phí nó? GPU có thể thực hiện việc tính toán dễ dàng như vậy nếu tôi chỉ đơn giản là gửi cho nó chỉ mục mới nhất bên trái để được vẽ và dịch mới, và có thể thực hiện nó song song. –

+0

Xin lỗi, nhưng tôi không thể hiểu cách tiếp cận của bạn. Panning một hình ảnh nên được thực hiện bằng cách dịch quad kết cấu (lớn hơn khung nhìn). Kết cấu là (có thể) cư trú, và dữ liệu duy nhất là một bù đắp X/Y để dịch quad kết cấu. Nhiều quad có thể được sử dụng để hiển thị nhiều hình ảnh. – Luca

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