2009-12-26 37 views
16

glLoadIdentity nóiKhi nào nên gọi glGetError?

GL_INVALID_OPERATION được tạo ra nếu glLoadIdentity được thực hiện giữa thực hiện glBegin và thực hiện tương ứng của glEnd.

Nhưng GL_INVALID_OPERATION là cờ trả về glGetError.

Câu hỏi của tôi là, khi nào chúng ta nên gọi glGetError (để biết liệu chúng tôi đang gọi opengl theo đúng trình tự)?

+1

Lưu ý: 'glBegin' và' glEnd' [không được chấp nhận] (http://gamedev.stackexchange.com/questions/34108/opengl-vbo-or-glbegin-glend). –

Trả lời

22

Tôi không chắc chắn nếu câu hỏi của bạn là về khi bạn có thể gọi glGetError nếu bên trong glBegin/End hoặc cho dù đó là một câu hỏi chung chung về sử dụng glGetError nói chung. Vì vậy, tôi sẽ trả lời cả hai.

Điều bạn có thể làm giữa glBegin và glEnd là rất hạn chế. Đây là mục đích, khi bạn đặt GL trong một chế độ rất cụ thể - ở giữa một Draw. Như vậy, bất kỳ thứ gì không liên quan trực tiếp đến thuộc tính trên mỗi đỉnh chỉ đơn giản là không hợp lệ. Ngay cả một glGetError là không hợp lệ trong bối cảnh đó.Try và suy nghĩ của glBegin + tất cả các cuộc gọi GL ở giữa + glEnd như là một cuộc gọi Vẽ duy nhất để GL, giúp nhận được gần gũi hơn với những gì GL thực sự anyways.

Bây giờ, bạn không bao giờ thực sự có lỗi GL được kích hoạt khi bên trong cặp Bắt đầu/Kết thúc nếu bạn tuân theo quy tắc đơn giản để chỉ gọi các phương thức thuộc tính (glNormal, glTexCoord, glColor, glSecondaryColor, glIndex, glMultiTexCoord, glVertexAttrib, glVertex và một vài người khác). Bất cứ điều gì khác sẽ gây ra lỗi. (err ... tốt, glMaterial là một chút ngoại lệ. Nó hoạt động, nhưng việc sử dụng nó đã được nản lòng)

Nếu câu hỏi của bạn là khi bạn có thể gọi glGetError khi lỗi được kích hoạt bên trong cặp Begin/End, ChrisF trả lời trong một bình luận: sau cuộc gọi glEnd.

Bây giờ, theo nghĩa rộng hơn, chỉ sử dụng glGetError làm công cụ gỡ lỗi. thiên vị cá nhân của tôi có hai phần:

  • séc glGetError một lần cho mỗi khung hình để chắc chắn không có lỗi
  • bọc nhất GL gọi với một macro có thể kiểm tra mã lỗi GL, và chỉ bật tính năng này khi mỗi kiểm tra khung hình không thành công.

Tất nhiên, vì các phương pháp thuộc tính có thể được gọi là bên ngoài cặp Bắt đầu/Kết thúc, hơi phức tạp để làm đúng. Nhưng trong thực tế, những phương pháp đó không bao giờ thất bại, vì vậy tôi không bận tâm kiểm tra macro chúng.

Một chút thông tin bên lề: API GL ban đầu được thiết kế sao cho việc triển khai ứng dụng khách thực sự có thể không biết liệu có lỗi tại trang cuộc gọi hay không. Ví dụ. nếu GL thực sự được thực hiện trong một máy từ xa (như trong SGI ngày), một cuộc gọi đến, nói, glTexEnv với một mục tiêu không phải của GL_TEXTURE_ENV chỉ đơn giản có thể được thêm vào bộ đệm lệnh, và không có lỗi sẽ được ghi vào thời điểm đó.

Nếu sau đó bạn gọi là glGetError, phía máy khách sẽ phải xóa bộ đệm lệnh đến máy chủ GL, đợi các lệnh được xử lý đệm, lấy lại mã lỗi và trả về mã lỗi thích hợp ứng dụng.

Nếu điều này nghe có vẻ nặng nề, đó là bởi vì nó đã được. Đây là lý do chính tại sao không phải mỗi cuộc gọi đã trả lại mã lỗi, bằng cách này, và tại sao gọi glGetError chỉ được coi là ok cho mục đích gỡ lỗi. Những ngày này, hầu hết các triển khai GL đang xử lý tất cả các nhà quản lý nhà nước trong cùng một quá trình, vì vậy như tôi đã nói, nó thực sự là đố cho hầu hết người dùng.

Cuối cùng, bất cứ khi nào tôi nói về Bắt đầu/Kết thúc, tôi cảm thấy tôi cần phải nói rằng bạn có lẽ nên xem xét việc không sử dụng nó chút nào. Đó là về cách thực hiện tồi tệ nhất để Vẽ bằng GL.

4

Thông thường bạn nên gọi glGetError sau mỗi gl... gọi khác là một trong những ảnh hưởng của cuộc gọi là để xóa các lỗi từ ngăn xếp (from the MSDN):

Khi một lỗi xảy ra, cờ lỗi được thiết lập với giá trị mã lỗi thích hợp. Không có lỗi nào khác được ghi lại cho đến khi glGetError được gọi, mã lỗi được trả về và cờ được đặt lại thành GL_NO_ERROR.

Tuy nhiên, nếu bạn có các cuộc gọi được bọc trong glBeginglEnd gọi glError sau glEnd. Điều này sẽ trả lại cho bạn mã lỗi chính xác (nếu có) và xóa ngăn xếp lỗi.

+0

Tuy nhiên, glGetError tạo ra một lỗi GL_INVALID_OPERATION nếu được gọi giữa một glBegin và một cuộc gọi glEnd. Vì vậy, glGetError không thể được gọi sau mỗi gl ... gọi. –

+0

Ah - Tôi hiểu lầm. Nếu bạn có các cuộc gọi được bao bọc trong 'glBegin' và' glEnd', hãy gọi 'glError' sau' glEnd'. – ChrisF

3

Một số triết lý mã hóa mong đợi mọi chương trình kiểm tra mọi lỗi có thể và xử lý thích hợp các lỗi đó. Tuy nhiên, sau một trong những triết lý đó đòi hỏi rất nhiều mã phụ, và có thể làm chậm đáng kể một chương trình. Trong thực tế, tôi chỉ sử dụng glGetError khi tôi chẩn đoán một vấn đề, hoặc viết một số mã có một khả năng đáng kể của thất bại và một hành động thích hợp sau khi lỗi.

Trong trường hợp đầu tiên, chẩn đoán sự cố, tôi sử dụng một trong hai chiến lược. Bởi vì OpenGL không ghi lại lỗi mới cho đến khi glGetError được gọi, tôi có thể kiểm tra lỗi một lần mỗi lần thông qua vòng lặp chính của tôi. Điều đó cho tôi biết lỗi đầu tiên, sau đó tôi theo dõi và hy vọng sửa chữa. Chiến lược khác tôi sử dụng khi tôi đã thu hẹp xuống một số mã có vấn đề, nhưng tôi không chắc chắn cuộc gọi nào đang gây ra sự cố. Sau mỗi gl ... gọi bên ngoài một glBegin. . . khối glEnd Tôi sẽ gọi glGetError và báo cáo bất kỳ lỗi nào. Điều này sẽ cho tôi biết chính xác mà gl ... gọi là gây ra vấn đề, và hy vọng bắt đầu tôi trên con đường để sửa chữa một.

Trong trường hợp thứ hai, lập trình phòng thủ cho một lỗi có thể xảy ra, tôi sẽ gọi glGetError để xóa cờ lỗi, thực hiện các cuộc gọi gl ... của tôi, sau đó gọi glGetError. Sau đó, tôi thực hiện bất kỳ hành động nào là cần thiết để đối phó với bất kỳ báo cáo glGetError nào.

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