OpenGL:كيفية تحديد ما إذا كان 3D (المقدمة) نقطة مسدودة أخرى 3D (المقدمة) الأوليات أمام ذلك ؟

StackOverflow https://stackoverflow.com/questions/1311869

  •  19-09-2019
  •  | 
  •  

سؤال

في برنامج OpenGL برنامج, وأنا أفعل التالية في تسلسل:

// Drawing filled polyhedrons
// Drawing points using GL_POINTS
// Displaying information for each above point beside it

لعرض معلومات نقطة (أقول نقطة معرف/عدد), تحويل 3D إحداثيات نقطة 2D باستخدام إحداثيات النافذة gluProject().أنا أكتب نقطة معرف في 2D نافذة الموقع باستخدام glRasterPos() و 2D تقديم حرف رمز.

عندما أصدرت نقطة مسدودة أخرى بدائية ، فإنه تلقائيا لا عرض بسبب التلقائي انسداد اختبار و اختبار عمق ما يحدث في OpenGL خط أنابيب.ولكن وجهة نظري معرف يتم عرض النص بجوار نقطة ، حتى عندما المغطي منذ أن كنت لا تحصل على هذا الانسداد المعلومات.

كيفية تحديد ما إذا كان 3D (المقدمة) نقطة مسدودة أخرى 3D (المقدمة) الأوليات أمام ذلك ؟ أو هل هناك طريقة أفضل لعرض المعلومات نقطة النص بجانبه فقط عندما لا المغطي?

ملاحظة:أنا على بينة من الأساليب التي تتطلب إضافية التقديم تمر.أشعر أن تلك هي مكلفة هدفي.

هل كانت مفيدة؟

المحلول

إذا كنت لا ترغب في استخدام انسداد الاستعلام الثانية تمر يمكنك محاولة أخذ العينات Z-buffer مقارنة ضد نقطة الاختبار.

منذ إضافة النص التالي إلى نقطة ، والاستيلاء على تطبيع Z العازلة قيمة (أقول باستخدام gluProject) نقطة, ثم مقارنة هذه القيمة إلى عينات Z-buffer (باستخدام glReadPixels) قيمة عند هذه النقطة.إذا كان لديك نقطة خلف (أكبر من) قيمة عمق قمت بأخذها ، وينبغي أن تكون نقطة المغطي و يمكنك اختيار عدم رسم النص.

هذا بالطبع يتطلب منك أن تجعل كل ما تبذلونه من الهندسة قبل النص, ولكن هذا لا ينبغي أن يكون مشكلة.

نموذج التعليمات البرمجية:

// Assumed to already hold 3D coordinates of point
GLdouble point3DX, point3DY, point3DZ;

// Project 3D point coordinates to 2D
GLdouble point2DX, point2DY, point2DZ;  // 2D coordinates of point
gluProject( point3DX, point3DY, point3DZ,
            mMatrix, pMatrix, vMatrix,      // MVP matrices
            &point2DX, &point2DY, &point2DZ);

// Read depth buffer at 2D coordinates obtained from above
GLfloat bufDepth = 0.0;
glReadPixels(   static_cast<GLint>( point2DX ), static_cast<GLint>( point2DY ),     // Cast 2D coordinates to GLint
                1, 1,                                                               // Reading one pixel
                GL_DEPTH_COMPONENT, GL_FLOAT,
                &bufDepth);

// Compare depth from buffer to 2D coordinate "depth"
GLdouble EPSILON = 0.0001;  // Define your own epsilon
if (fabs(bufDepth - point2DZ) < EPSILON)
    // 3D point is not occluded
else
    // 3D point is occluded by something

نصائح أخرى

القراءة من Z-Buffer يمكن أن تكون بطيئة للغاية على الأجهزة الحديثة. لهذا السبب اخترع استعلام OcClusion. ابحث عن امتداد QURB-OcClusion-querion. لديها بضعة إطارات من التأخير قبل أن تتمكن من الحصول على النتائج، لكنها لن تضرب أدائك.

إذا كان استعلام OcClusion لن يعمل لأي سبب من الأسباب، فإن خيار التراجع التالي هو القيام بعملية عالمية بتقاطع البرامج باستخدام شجرة BSP (التي لا تستخدم GL على الإطلاق).

بالإضافة إلى إجابة آلان، يمكنك اختبار انسداد رياضيا عن طريق إسقاط أشعة من وضع الكاميرا الخاص بك إلى وجهة نظرك، وتحديد ما إذا كان يتقاطع أي من هندسةك. هناك الكثير من المراجع المتعلقة بالإنترنت للقيام باختبار تقاطع كائن راي (انظر، على سبيل المثال، صفحة تقاطع الكائن / كائن). إذا كان لديك الكثير من الهندسة، فقد ترغب في تسريع الأمور باستخدام وحدات التخزين المحيطة أو شجرة BSP.

ككافأة، يجب أن يكون رمز إنسدادك أسهل بكثير اختبار الوحدة، لأنه لا يعتمد على استخراج القيم من OpenGL.

الرد من أشوين ناناجابا كان مفيدا للغاية. أنا لست من خبير OpenGL، لذلك استغرق الأمر بعض الوقت لمعرفة كيفية الحصول على مصفوفات MVP. أشارك الكود هنا لاستكمال رسالته:

    GLint viewport[4];
    GLdouble modelview[16];
    GLdouble projection[16];
    glGetDoublev( GL_MODELVIEW_MATRIX, modelview );
    glGetDoublev( GL_PROJECTION_MATRIX, projection );
    glGetIntegerv( GL_VIEWPORT, viewport );
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top