GlTransTable, chính xác thì nó hoạt động như thế nào?


7

Tôi có một số khó khăn để hiểu làm thế nào để glTranslate hoạt động. Lúc đầu, tôi nghĩ rằng nó chỉ đơn giản là thêm các giá trị vào trục để thực hiện chuyển đổi.

Tuy nhiên, sau đó tôi đã tạo hai đối tượng sẽ tải bitmap, một đối tượng có ma trận được đặt thành GL_TEXTURE:

public class Background
{
    float[] vertices = new float[]
        { 0f, -1f, 0.0f, 
          4f, -1f, 0.0f, 
          0f, 1f, 0.0f, 
          4f, 1f, 0.0f };

    ....
    private float backgroundScrolled = 0;
    public void scrollBackground(GL10 gl)
    {
        gl.glLoadIdentity();
        gl.glMatrixMode(GL10.GL_MODELVIEW);
        gl.glTranslatef(0f, 0f, 0f);
        gl.glPushMatrix();

        gl.glLoadIdentity();
        gl.glMatrixMode(GL10.GL_TEXTURE);
        gl.glTranslatef(backgroundScrolled, 0.0f, 0.0f);
        gl.glPushMatrix();

        this.draw(gl);
        gl.glPopMatrix();

        backgroundScrolled += 0.01f;
        gl.glLoadIdentity();
    }
}

và một cái khác cho GL_MODELVIEW:

public class Box
{
    float[] vertices = new float[]
        { 0.5f, 0f, 0.0f, 
          1f, 0f, 0.0f, 
          0.5f, 0.5f, 0.0f, 
          1f, 0.5f, 0.0f };

    ....

    private float boxScrolled = 0;
    public void scrollBackground(GL10 gl)
    {
        gl.glMatrixMode(GL10.GL_MODELVIEW);
        gl.glLoadIdentity();
        gl.glTranslatef(0f, 0f, 0f);
        gl.glPushMatrix();

        gl.glMatrixMode(GL10.GL_MODELVIEW);
        gl.glLoadIdentity();
        gl.glTranslatef(boxScrolled, 0.0f, 0.0f);
        gl.glPushMatrix();

        this.draw(gl);
        gl.glPopMatrix();

        boxScrolled+= 0.01f;
        gl.glLoadIdentity();
    }
}

Bây giờ cả hai đều được vẽ trong Renderer.OnDraw. Tuy nhiên, nền di chuyển nhanh hơn chính xác 5 lần. Nếu tôi nhân hộp số được nhân với 5 thì chúng sẽ thành thật và sẽ di chuyển cùng nhau. Nếu tôi sửa đổi các đỉnh nền thành

    float[] vertices = new float[]
        { 1f, -1f, 0.0f, 
          0f, -1f, 0.0f, 
          1f, 1f, 0.0f, 
          0f, 1f, 0.0f };

Nó cũng sẽ chân thành với hộp. Vì vậy, những gì đang diễn ra dưới glTranslate?


có thể vấn đề là với số lượng cuộc gọi glpush / glpop bạn thực hiện. lưu ý rằng trong mọi chức năng bạn đang gọi glpush hai lần và chỉ một lần.
Ali1S 232

Không có lẽ, chắc chắn, OpenGL có một ngăn xếp chỉ với 32 đơn vị cho mỗi loại ma trận, nếu tôi không nhầm. Điều này cho phép một số độ sâu kết xuất trong cây cảnh của bạn, nhưng không quá nhiều. Nhưng như thế, chương trình sẽ bị sập trong vòng một giây :)
Grimshaw

tốt, tôi không nghĩ vậy, như tôi đã nói, nếu tôi sửa đổi các đỉnh nền, thành từ 0 đến 1 trong trục x, nó hoạt động tốt.
mykk

2
Tôi nghĩ rằng glPushMatrix thứ hai nên bị xóa. glPushMatrix giống như sao lưu ma trận hiện tại của bạn. Vì vậy, nếu bạn đang đẩy và không bật, stack bị tràn ...
zacharmarz

Và điều thứ hai: glTranslate không thêm thứ gì vào tọa độ. Đó là ma trận thay đổi (mô hình hoặc kết cấu trong trường hợp của bạn). Ma trận Modelview được sử dụng để nhân tọa độ đỉnh, ma trận kết cấu để nhân tọa độ kết cấu.
zacharmarz

Câu trả lời:


5

Đây là câu trả lời đầy đủ của tôi:

Số lượng glPushMatrix và glPopMatrix của bạn phải bằng nhau. Đó là vấn đề đầu tiên.

Nhưng vấn đề chính là ở chế độ ma trận. Trong trường hợp đầu tiên (nền), bạn đang sử dụng ma trận kết cấu, được sửa đổi bởi glTranslate. Điều đó có nghĩa là, trong mỗi bước tọa độ kết cấu sẽ được nhân với bản dịch này.

Vì tọa độ kết cấu nằm trong phạm vi <0,1> và hình chữ nhật nền của bạn rộng 4 đơn vị, nên nó sẽ không được dịch 0,01 mỗi khung hình, nhưng nó sẽ được dịch bởi 0,04 đơn vị trên thế giới.

Trong trường hợp thứ hai (hộp), bạn đang thay đổi ma trận modelview. Điều này sẽ gây ra dịch hộp của bạn bằng 0,01 đơn vị mỗi khung hình trên thế giới.

Khi bạn thay đổi hình chữ nhật nền thành tọa độ mới (tọa độ x là 0 và 1), thì mọi tọa độ kết cấu khung thực sự được dịch bằng 0,01 đơn vị.


Cảm ơn bạn! Tôi đã nhận ra nó sau khi nhận xét của bạn và bây giờ thì rõ ràng hơn nhiều
mykk

(tôi chỉ muốn thêm nền rộng 5 đơn vị)
mykk

6

glTranslatef

glTranslatefdịch (một trường hợp đặc biệt của "biến đổi") ma trận tương ứng với chế độ ma trận hiện được chọn. Vì vậy, gọi nó sau glMatrixMode(GL_MODELVIEW)nghĩa là bạn biến đổi ma trận khung nhìn mô hình và sau khi glMatrixMode(GL_TEXTURE)bạn biến đổi ma trận kết cấu. Xem bài viết Wikipedia về ma trận dịch thuật để tìm hiểu thêm về điều này.

Các ma trận model-view được áp dụng cho tọa độ đối tượng để có được tọa độ mắt, mà có nghĩa là tọa độ thế giới tuyệt đối được chuyển đến tọa độ tương đối so với "máy ảnh". (Trước khi đối tượng thực sự được hiển thị, tọa độ của nó được chuyển đổi thêm một số lần nữa, các chi tiết có trong Câu hỏi thường gặp về OpenGL về các biến đổi , nhưng chúng không quan trọng ngay bây giờ.)

Các ma trận kết cấu làm điều gì đó hoàn toàn khác nhau, nó được áp dụng cho tọa độ texture trước khi chúng được ánh xạ. Sử dụng nó sẽ cho phép bạn đạt được hiệu ứng kết cấu cuộn, xoay, chia tỷ lệ hoặc uốn cong phối cảnh.

Hy vọng rằng bạn sẽ thấy rằng hai ma trận này không thể thay thế cho nhau theo cách bạn nghĩ. Chúng được áp dụng trong các giai đoạn khác nhau của quá trình kết xuất. Khi kết quả chuyển đổi cả hai ma trận thẳng hàng trên màn hình của bạn, đó hoàn toàn là một sự trùng hợp phụ thuộc vào vị trí và tọa độ kết cấu của các đối tượng của bạn, giữa các đối tượng khác.

Một số lưu ý thêm

Sau đó, một cái gì đó khác, các bình luận đã đúng khi nói bạn nên cân bằng các cuộc gọi của bạn glPush/PopMatrix. Không nhìn thấy phần còn lại của mã của bạn và biết những đối tượng khác đang được hiển thị, thật khó để nói, nhưng có thể một phần của hiệu ứng bạn đang gặp phải (tỷ lệ dịch theo hệ số 5) là do chế độ xem mô hình ma trận cho một đối tượng được áp dụng không chính xác cho một đối tượng khác vì nó vẫn nằm trên ngăn xếp ma trận.

Hơn nữa:

  • Gọi glMatrixModeliên tiếp với cùng một đối số sẽ không thay đổi bất cứ điều gì vì trạng thái OpenGL vẫn giữ nguyên.
  • glLoadIdentitytải ma trận danh tính: một ma trận trả về chính tọa độ tương tự mà nó được áp dụng. Nó có thể được xem như là một "thiết lập lại" của ma trận hiện tại. Gọi nó nhiều lần sẽ không có hiệu lực (trừ khi bạn làm gì đó với ma trận hiện tại ở giữa).
  • glTranslatef(0f, 0f, 0f) sẽ không có hiệu lực.

1

Chính xác thì glTranslate làm gì? Trước hết, nó tính toán một ma trận dịch - đây chỉ là một ma trận nhận dạng với các giá trị dịch trong các khe 3 (cho x), 7 (cho y) và 11 (cho z) (giả sử là cột chính). Sau đó, nó nhân ma trận hiện tại với ma trận dịch này để có được một ma trận mới, sau đó nó thay thế ma trận hiện tại bằng. Về cơ bản là vậy.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.