2012-01-21 17 views
7

Sau khi tìm kiếm và đọc về OpenGL hiện đại để nâng cấp dự án hiện tại của tôi, tôi hơi bối rối vì khung 3D của tôi dựa trên OpenGL 2.1.OpenGL hiện đại: VBO, GLM và Ma trận Stacks

như vậy, như xa như tôi tìm hiểu ...

  • Chúng tôi cần phải tạo ra của chúng tôi Vertex-đệm-Objects từ đỉnh, chỉ số, normals, màu sắc, UVs vv

  • sau đó chúng ta có thể sử dụng GLM cho chuyển đổi ma trận, và chúng tôi chỉ sử dụng VBO để tạo ra hoặc thao tác mắt lưới, cuối cùng chúng tôi vượt qua tất cả mọi thứ vào GLSL vertex như thế này ...

    glm::mat4 MVP = projection * view * model; 
    glUniformMatrix4fv(glGetUniformLocation(shaderProgramID, "MVP"), 1, GL_FALSE, glm::value_ptr(MVP)); //or &MVP[0][0] 
    
    // uniform mat4 MVP; 
    // in vec3 Vertex; 
    // void main(void) 
    // { 
    // gl_Position = MVP * vec4(Vertex, 1.0); //instead of ftransform(); 
    // } 
    

CÂU HỎI: Cách chúng tôi thực hiện các phép biến đổi phân cấp mà không có pushMatrix/popMatrix? (hoặc có thể chúng tôi thực hiện chuyển đổi phân cấp bằng cách sử dụng các VBO của chúng tôi, có thể không?)

Nếu không, thì làm cách nào để đạt được kết quả tương tự như pushMatrix/popMatrix bằng cách sử dụng thư viện GLM và C++ < stack?

phép nói rằng tôi cần một cái gì đó như thế này:

> Set identity 
> Translate to X, Y, Z 
> Draw Mesh 1 
> Rotate 0.5 by X axis 
> Draw Mesh 2 
> Scale down to 0.1 
> Draw Mesh 3 
+1

@ BЈовић: [OpenGL Toán học (GLM)] (http://glm.g-truc.net/), thư viện C++ tiêu đề chỉ dành cho ma trận/toán học vector. – genpfault

Trả lời

5
  • Chúng tôi cần phải tạo ra của chúng tôi Vertex-đệm-Objects từ đỉnh, chỉ số, normals, màu sắc, UVs vv

Nó không thực sự cần thiết để sử dụng VBOs, phía máy khách Vertex Mảng cũng hoạt động tốt. Tuy nhiên, bạn nên sử dụng VBO, vì nó làm cho cuộc sống của người lái xe dễ dàng hơn và về lâu dài cũng là của bạn với tư cách là người phải sắp xếp dữ liệu. Các chi phí mã là bỏ qua (nó về giống như tạo và tải lên dữ liệu kết cấu) và hiệu suất sẽ chỉ tăng lên.

  • sau đó chúng ta có thể sử dụng GLM cho chuyển đổi ma trận, và chúng tôi chỉ sử dụng VBO để tạo ra hoặc thao tác mắt lưới, cuối cùng chúng tôi vượt qua tất cả mọi thứ vào GLSL vertex như thế này ...

Bạn không giới hạn GLM. Bất kỳ thư viện toán học ma trận nào cũng sẽ làm được. Nếu bạn đang tìm kiếm thứ gì đó bạn có thể sử dụng trong C99, hãy xem số (01) vẫn chưa hoàn thành của tôi linmath.hhttps://github.com/datenwolf/linmath.h chỉ là một tệp tiêu đề có chức năng static inline.Tôi chưa đạt điểm chuẩn nếu trùng lặp mã có tác động tiêu cực đến hiệu suất (kích thước mã tạo áp lực bộ nhớ cache L1).

CÂU HỎI: Cách chúng tôi thực hiện chuyển đổi phân cấp mà không có pushMatrix/popMatrix? (hoặc có thể chúng tôi thực hiện chuyển đổi phân cấp bằng cách sử dụng các VBO của chúng tôi, có thể không?)

Các VBO không liên quan gì đến điều này. Điều gì làm cho hầu hết người dùng gặp rắc rối OpenGL cũ thời là những chức năng xếp chồng ma trận, khiến cho OpenGL trông hơi giống một biểu đồ cảnh. Nhưng nó không phải như vậy.

Nếu bạn quên về ma trận ngăn xếp OpenGL cũ, nó trở nên rõ ràng làm thế nào để làm biến dạng phân cấp: Tại mỗi chi nhánh trong hệ thống phân cấp tạo một bản sao của ma trận chuyển đổi và hoạt động trên đó. Bạn nhận được một cây phân cấp biến đổi, tại mỗi nút ma trận tương ứng được lưu trữ. Sau đó, bạn chuyển các ma trận đó làm đồng phục cho đổ bóng đỉnh; hoặc chỉ một ma trận nếu bạn vẽ một đối tượng cứng nhắc chỉ có một biến đổi. Nhiều ma trận bạn thường chỉ cần cho deformables như hoạt hình xương của một nhân vật như

worldtransform -> 
    pelvis -> 
     left upper leg -> left lower leg -> left foot 
     right upper leg -> right lower leg -> right foot 
    torso -> 
     neck -> head -> 
      left eye 
      right eye 
      facial deformation // this is a whole chapter of it's own 
     left upper arm -> left lower arm -> left hand 
     right upper arm -> right lower arm -> right hand 

Mỗi lần này bạn enounter một -> trong một hệ thống phân cấp như vậy, bạn tạo một bản sao của ma trận và tiến hành làm việc trên một đó. Khi rơi trở lại mức cao hơn của cây, bạn bắt đầu làm việc từ ma trận đó một lần nữa.

+1

"biến dạng khuôn mặt" // đây là toàn bộ chương riêng của nó => bao gồm hàm rơi :) – mlvljr

4

Vâng, nếu bạn cần hierarchical chuyển đổi, sau đó bạn phải làm điều đó một mình. Tuy nhiên, đó là khá nhiều tầm thường nếu tất cả bạn cần là một ngăn xếp. Chỉ cần lấy mục cuối cùng trên ngăn xếp và nhân nó với ma trận tiếp theo bạn muốn áp dụng, và đẩy kết quả vào ngăn xếp.

[Trên câu hỏi đã chỉnh sửa]: Bạn không cần một ngăn xếp nào cả cho điều này và cũng không có chuyển đổi phân cấp. Chỉ cần có một ma trận đơn và áp dụng bản dịch của bạn, vẽ, nhân nó với ma trận xoay của bạn, vẽ, nhân tỷ lệ của bạn, vẽ.

+1

Er? Nếu bạn có ma trận M ban đầu, và bản dịch T, vòng quay R và thang đo S, thì ma trận đầu tiên của bạn là M = T, thứ hai là M * = R = (T * R == dịch đầu tiên, quay thứ hai), và thứ ba là M * = S = (T * R * S == tất cả các ma trận.) Đối với cánh tay robot, bạn cũng có thể bắt đầu ở trên cùng và phát lệnh gọi trong khi đi xuống cây của bạn. Nó không quan trọng nếu "ngăn xếp" là một std :: stack hoặc chỉ là một phần của thói quen đi qua cảnh đệ quy của bạn. – Anteru

+0

Nếu bạn không thực hiện M * = S, nhưng chỉ sử dụng M * S (bản sao!) Thì ma trận gốc sẽ không bị thay đổi. Chồng của bạn sẽ trông như thế này: [M], sau đó bạn đẩy T (dẫn đến một ngăn xếp [M, M * T]), sau đó bạn bật ([M]), sau đó đẩy lại R ([M, M * R]). Tôi không nhận được vấn đề của bạn? – Anteru

+0

Dừng chỉnh sửa ý nghĩa của nhận xét của bạn. Tôi nói bạn có thể thực hiện nó thông qua một ngăn xếp, hoặc rằng bạn chỉ có thể sao chép ma trận của bạn bên trong chức năng vẽ đệ quy của bạn (mà ngầm tạo ra một ngăn xếp.) [M, ..] _is một stack_, nếu bạn muốn điều này, chỉ cần sử dụng nó . Nhưng bạn có thể dễ dàng lấy đi mà không có bất kỳ std :: stack nào. – Anteru

4

Nếu hiển thị của bạn đã xảy ra theo cấp bậc sử dụng, ví dụ: đệ quy hàm thì bạn đã có ngăn xếp ma trận!

void renderMesh(Matrix transform, Mesh mesh) 
{ 
    // here call glDrawElements/glDrawArrays and send transform matrix to MVP uniform 
    mesh->draw(transform); 

    // now render all the sub-meshes, then will be transformed relative to current mesh 
    for (int i=0; i<mesh->subMeshCount(); i++) 
    { 
     Matrix subMeshTransform = mesh->getSubMeshTransform(i); 
     Mesh subMesh = mesh->getSubMesh(); 

     renderMesh(subMeshTransform * transform, subMesh); 
    } 
} 

// somwhere in main function 
... 
Matrix projection = Matrix::perspective(...); 
Matrix view = camera->getViewMatrix(); 

Matrix transform = view * projectIon; 
renderMesh(transform, rootMesh); 
0

Đối với VAO và VBO hiệu suất Tôi không đồng ý rằng VBO là nhanh hơn, tôi đề nghị để xem liên kết này

http://www.openglsuperbible.com/2013/12/09/vertex-array-performance/

Bạn có thể nhìn thấy từ kết quả trên đó, ít nhất là cho bộ mẫu nhỏ của chúng tôi , VAO nhanh hơn trên tất cả các triển khai. Nó là viết tắt của lý do - có ít thông số để xác nhận khi gọi glBindVertexArray hơn glBindBuffer hoặc glVertexAttribPointer. Ngay cả khi chỉ có một thuộc tính đỉnh đơn, có một nửa số lượng cuộc gọi vào OpenGL với công tắc VAO hơn là với cập nhật rõ ràng của một VAO toàn cầu. Bên cạnh các "cuộc gọi API ít hơn có nghĩa là thực hiện nhanh hơn", VAO là một nơi mà một trình điều khiển OpenGL có thể ngăn chặn thông tin cần thiết để lập trình GPU bên dưới. Tổng số thay đổi trạng thái được gửi tới GPU cũng giống nhau.

+0

Làm thế nào điều này có liên quan đến câu hỏi? –