Cách tốt nhất để vẽ một đường chiều rộng biến mà không sử dụng glLineWidth là gì? Chỉ cần vẽ một hình chữ nhật? Các đường song song khác nhau? Không có điều nào ở trên?Vẽ một đường có chiều rộng thay đổi trong OpenGL (Không có glLineWidth)
Trả lời
Giả sử điểm ban đầu của bạn là (x1, y1) -> (x2, y2). Sử dụng các điểm sau (x1-width/2, y1), (x1 + width/2, y1), (x2-width/2, y2), (x2 + width/2, y2) để tạo hình chữ nhật và sau đó sử dụng quads/tris để vẽ nó. Đây là cách ngây thơ đơn giản. Lưu ý rằng đối với chiều rộng dòng lớn, bạn sẽ nhận được hành vi điểm cuối kỳ lạ. Những gì bạn thực sự muốn làm sau đó là một số tính toán đường song song thông minh (mà không nên là xấu) bằng cách sử dụng toán học vector. Đối với một số lý do dot/cross sản phẩm và chiếu vector đến tâm trí.
Bạn có thể vẽ hai tam giác:
// Draws a line between (x1,y1) - (x2,y2) with a start thickness of t1 and
// end thickness t2.
void DrawLine(float x1, float y1, float x2, float y2, float t1, float t2)
{
float angle = atan2(y2 - y1, x2 - x1);
float t2sina1 = t1/2 * sin(angle);
float t2cosa1 = t1/2 * cos(angle);
float t2sina2 = t2/2 * sin(angle);
float t2cosa2 = t2/2 * cos(angle);
glBegin(GL_TRIANGLES);
glVertex2f(x1 + t2sina1, y1 - t2cosa1);
glVertex2f(x2 + t2sina2, y2 - t2cosa2);
glVertex2f(x2 - t2sina2, y2 + t2cosa2);
glVertex2f(x2 - t2sina2, y2 + t2cosa2);
glVertex2f(x1 - t2sina1, y1 + t2cosa1);
glVertex2f(x1 + t2sina1, y1 - t2cosa1);
glEnd();
}
Đây là cách quá phức tạp! Quá nhiều lượng giác, nơi nó không cần thiết quá. – PierreBdR
Hóa ra đây không phải là những gì OP muốn (xem câu trả lời của mình dưới đây). Nhưng tôi rất muốn thấy một thuật toán đơn giản hơn, nếu bạn muốn chia sẻ nó. –
Tôi đã thêm một phiên bản miễn phí trig ở đây bây giờ – bobobobo
Một hình chữ nhật (ví dụ: GL_QUAD hoặc hai GL_TRIANGLES) âm thanh như đặt cược tốt nhất của bạn bằng những âm thanh của nó, không chắc tôi có thể nghĩ ra cách nào khác.
Ok, làm thế nào về điều này: (Ozgar)
A /\ / \ . p1 \ / \ / D B - .p2 - - - C
Vậy AB là width1
và CD là width2
.
Sau đó,
// find line between p1 and p2
Vector p1p2 = p2 - p1 ;
// find a perpendicular
Vector perp = p1p2.perpendicular().normalize()
// Walk from p1 to A
Vector A = p1 + perp*(width1/2)
Vector B = p1 - perp*(width1/2)
Vector C = p2 - perp*(width2/2)
Vector D = p2 - perp*(width2/2)
// wind triangles
Triangle(A, B, D)
Triangle(B, D, C)
Note có khả năng một CW/CCW quanh co vấn đề với thuật toán này - nếu perp được tính như (-y, x) trong sơ đồ trên thì nó sẽ uốn lượn CCW, nếu (y, -x) thì nó sẽ là một cuộn dây CW.
Một cách khác để làm điều này, nếu bạn đang viết một bộ quét phần mềm một cách tình cờ, là sử dụng tọa độ barycentric trong điểm ảnh màu sắc của bạn sân khấu và màu pixel khi một trong những barycentric phối là gần 0. Bạn càng kiếm được nhiều khoản trợ cấp, các dòng càng dày.
Tôi đã phải làm điều tương tự vào đầu ngày hôm nay.
Đối với việc tạo ra một dòng kéo dài (x1,y1) -> (x2,y2)
của một width
nhất định, một phương pháp rất đơn giản là để biến đổi một đơn vị có kích thước vuông đơn giản kéo dài (0., -0.5) -> (1., 0.5)
sử dụng:
glTranslatef(...)
để di chuyển nó đến mong muốn(x1,y1)
vị trí của bạn;glScalef(...)
để chia tỷ lệ sang phảilength
và mong muốnwidth
: sử dụnglength = sqrt((x2-x1)^2 + (y2-y1)^2)
hoặc bất kỳ xấp xỉ độ phức tạp thấp nào khác;glRotatef(...)
đếnangle
theo đúng hướng: sử dụngangle = atan2(y2-y1, x2-x1)
.
Đơn vị vuông được tạo rất đơn giản từ dải hai tam giác GL_TRIANGLE_STRIP
, biến thành dòng liền mạch của bạn sau các phép biến đổi ở trên.
Gánh nặng ở đây được đặt chủ yếu vào OpenGL (và phần cứng đồ họa của bạn) thay vì mã ứng dụng của bạn. Quy trình trên được chuyển rất dễ dàng thành một hàm chung bằng các cuộc gọi xung quanh glPushMatrix()
và glPopMatrix()
.
Đối với những người đang tìm kiếm giải pháp tốt cho điều này, mã này được viết bằng LWJGL, nhưng có thể dễ dàng thích nghi với bất kỳ triển khai OpenGL nào.
import java.awt.Color;
import org.lwjgl.opengl.GL11;
import org.lwjgl.util.vector.Vector2f;
public static void DrawThickLine(int startScreenX, int startScreenY, int endScreenX, int endScreenY, Color color, float alpha, float width) {
Vector2f start = new Vector2f(startScreenX, startScreenY);
Vector2f end = new Vector2f(endScreenX, endScreenY);
float dx = startScreenX - endScreenX;
float dy = startScreenY - endScreenY;
Vector2f rightSide = new Vector2f(dy, -dx);
if (rightSide.length() > 0) {
rightSide.normalise();
rightSide.scale(width/2);
}
Vector2f leftSide = new Vector2f(-dy, dx);
if (leftSide.length() > 0) {
leftSide.normalise();
leftSide.scale(width/2);
}
Vector2f one = new Vector2f();
Vector2f.add(leftSide, start, one);
Vector2f two = new Vector2f();
Vector2f.add(rightSide, start, two);
Vector2f three = new Vector2f();
Vector2f.add(rightSide, end, three);
Vector2f four = new Vector2f();
Vector2f.add(leftSide, end, four);
GL11.glBegin(GL11.GL_QUADS);
GL11.glColor4f(color.getRed(), color.getGreen(), color.getBlue(), alpha);
GL11.glVertex3f(one.x, one.y, 0);
GL11.glVertex3f(two.x, two.y, 0);
GL11.glVertex3f(three.x, three.y, 0);
GL11.glVertex3f(four.x, four.y, 0);
GL11.glColor4f(1, 1, 1, 1);
GL11.glEnd();
}
- 1. Chiều rộng đường OpenGL
- 2. OpenGL 3.2 Cấu hình cốt lõi glLineWidth
- 3. OpenGL ES 1.1 đến 2.0 có thay đổi lớn không?
- 4. ggplot - dòng thay đổi chiều rộng
- 5. Đường dẫn Bezier với thay đổi động của chiều rộng
- 6. NSButton có chiều rộng kích thước thay đổi, góc tròn
- 7. Vẽ các đường với opengl trong Haskell
- 8. Vẽ đường cong Hermite trong OpenGL
- 9. Thay đổi chiều rộng của một UIBarButtonItem trong một UINavigationBar
- 10. Vẽ biểu đồ có chiều rộng đột quỵ 1 pixel trong bản vẽ khổ A4
- 11. Chiều rộng và chiều cao có thay đổi theo hướng không?
- 12. Có thể thay đổi chiều rộng của biểu tượng tab trong văn bản không?
- 13. Pyglet OpenGL vẽ anti-aliasing
- 14. jQuery - Phát hiện thay đổi chiều rộng cửa sổ nhưng không thay đổi chiều cao
- 15. GLFW có chiều cao/chiều rộng màn hình không?
- 16. OpenGL vẽ đường viền hình chữ nhật
- 17. Matplotlib vẽ một đường thẳng liên tục thay đổi màu
- 18. Cách vẽ hình chữ nhật tròn với đường viền có chiều rộng thay đổi bên trong các giới hạn cụ thể
- 19. Thay đổi chiều rộng của UIBarButtonItem
- 20. FancyBox thay đổi kích thước chiều rộng
- 21. Có thể lấy chiều cao/chiều rộng của hình ảnh không có trong DOM không?
- 22. Spinner Primefaces - Cách thay đổi chiều rộng
- 23. Thay đổi chiều rộng Spinner DropDown
- 24. openGL: đường kẻ có bóng đổ
- 25. UIScrollView - khi bật phân trang, tôi có thể "thay đổi" chiều rộng của trang không?
- 26. Thay đổi chiều rộng đường viền của các phần chia nhỏ trong VIM
- 27. Kích thước, Chỉ thay đổi chiều rộng/chiều cao
- 28. Không thể thay đổi chiều rộng nút twitter
- 29. Vẽ một đường có màu gradient
- 30. CSS: chiều rộng của một liên kết không thay đổi bằng cách thiết lập thuộc tính chiều rộng
@Ozgur 's câu trả lời là tốt hơn nhiều. Cân nhắc việc thêm phép tính vectơ mà bạn đang nói đến. – Valdrinit