Sự cố của bạn có nhiều khả năng không phải do lỗi làm tròn, mà là sự hiểu lầm về cách OpenGL ánh xạ tới các pixel. Nếu bạn nhận thấy các lỗi off-by-one, có thể là do các UV của bạn, các vị trí đỉnh của bạn hoặc cặp ma trận/khung nhìn chiếu của bạn không được căn chỉnh với vị trí mà chúng phải là.
Để đơn giản hóa, tôi sẽ chỉ nói về 1D, và được giả sử bạn sử dụng một máy chiếu và một khung nhìn mà map X, Y tọa độ đến vị trí điểm ảnh tương đương (tức là một glOrtho(0,width,0,height,zmin,zmax)
và glViewport(0,width,0,height)
.
Giả sử bạn muốn vẽ 5 texels (bắt đầu từ 0 để đơn giản) của kết cấu 64 inch của bạn hiển thị trên 10 pixel (tỷ lệ 2) của màn hình của bạn bắt đầu từ pixel 20.
Để đến đó, vẽ hình tam giác với tọa độ X 20 và 30, và U (của cặp UV) của 10/64 và 15/64. Việc rasterization OpenGL sẽ tạo ra 10 pixel để bóng râm, với X tọa độ 20.5, 21.5, ... 29.5. Lưu ý rằng vị trí itions không phải là số nguyên đầy đủ. OpenGL rasterizes ở giữa pixel.
Tương tự, nó sẽ tạo tọa độ U là 10,25/64, 10,75/64, 11,25/64, 11,75/64 ... 14,25/64, 14,75/64. Lưu ý một lần nữa rằng tọa độ texel, đưa trở lại vị trí texel trong không gian kết cấu, không phải là số nguyên đầy đủ. OpenGL mẫu từ giữa các địa điểm texel, do đó, điều này là tốt. Làm thế nào các samplers sử dụng các tia UV này để tạo ra các giá trị texel phụ thuộc vào các chế độ lọc, nhưng nó là gần nhất hoặc tuyến tính, các pixel nên được chứa bên trong các texas quan tâm (0.25 với kích thước 0.5 chỉ nên sử dụng màu từ 0, 0, 0, 10, 04835). đến 0,5, tất cả nằm trong texel đầu tiên).
Nói chung, nếu bạn tuân thủ các nguyên tắc chung tôi đã nêu, bạn sẽ không bao giờ thấy hiện vật.
- Sử dụng Ortho và Viewport chính xác kích thước bộ đệm khung hình của bạn
- Sử dụng vị trí của X, X + chiều rộng chính xác
- Sử dụng UVs tương ứng với chính xác texels bạn muốn (nếu bạn muốn 10 texels bắt đầu từ texel 0, sử dụng U = 0 đến U = 10.
Nếu bạn có -1 ở đâu đó trong môn toán, có thể không chính xác (đối với vị trí hoặc UV).
Để quay lại ví dụ của bạn, không rõ cách bạn liên kết các uv bạn tính toán với các vị trí (vì bạn không hiển thị tính toán vị trí). Nó cũng không rõ làm thế nào bạn có xpos_in_texture (bạn nên giải thích cách bạn tính chúng cho các góc của sprite của bạn). Tôi đoán là bạn đã tính sai.
Điều này là sai. Nói width_of_texture = 2 (với 1, nó thậm chí còn thú vị hơn), và bạn muốn vẽ 2 quads mà bản đồ chính xác đến 2 texels. Bạn cần U = 0, U = 0,5 cho các góc quad 0 và U = 0,5, U = 1 cho quad 1 góc. Đó chính xác là công thức mà Sirp cung cấp (nếu bạn cho nó ăn với xpos đúng, tức là 0, 1, 2), và không phải cái bạn làm (bạn chỉ cung cấp số nguyên với chiều rộng = 2). – Bahbar
Đúng, tôi đã nghĩ rằng anh ta đang chỉ định vị trí pixel, nhưng nếu anh ta chỉ định vị trí giữa các pixel, thì nó sẽ hoạt động. Tôi đã từng làm việc ở các vị trí pixel, tất nhiên là hoàn toàn bị phá vỡ khi kết cấu nhỏ đến 2x2. –