سؤال

لدي تأثير جسيم بسيط في OpenGL باستخدام GL_Points. يتم استدعاء ما يلي، يتم تمرير الجزيئات بالترتيب من الجسيمات من الكاميرا أولا إلى أقرب الكاميرا أخيرا:

void draw_particle(particle* part) {
    /* The following is how the distance is calculated when ordering.
     * GLfloat distance = sqrt(pow(get_camera_pos_x() - part->pos_x, 2) + pow(get_camera_pos_y() - part->pos_y, 2) + pow(get_camera_pos_z() - part->pos_z, 2));
     */

    static GLfloat quadratic[] = {0.005, 0.01, 1/600.0};
    glPointParameterfvARB(GL_POINT_DISTANCE_ATTENUATION_ARB, quadratic);
    glPointSize(part->size);
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glEnable(GL_POINT_SPRITE_ARB);
    glEnable(GL_TEXTURE_2D);

    glBegin(GL_POINTS);
        glColor4f(part->r, part->g, part->b, part->a);
        glVertex3f(part->pos_x, part->pos_y, part->pos_z);
    glEnd();

    glDisable(GL_BLEND);
    glDisable(GL_POINT_SPRITE_ARB);
}

ومع ذلك، هناك بعض القطع الأثرية عند التقديم كما يمكن رؤيته في التأثير التالي:صورة مصنعة http://img199.imageshack.us/img199/9574/particleeffect.png.

تختفي المشاكل إذا قمت بتعطيل اختبار العمق، لكنني أحتاج إلى التأثيرات لتكون قادرا على التفاعل مع العناصر الأخرى للمشهد، ويبدو أمام عناصر وخلفها من نفس GL_TRIANGLE_STRIP اعتمادا على العمق.

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

المحلول

إذا تم فرز الجسيمات الخاصة بك بالفعل، فيمكنك التجسيد مثل هذا:

  • جعل الجسيمات مع عمق الكتابة GL ولكن لا اختبار عمق (لا أتذكر الثوابت بالضبط)
  • تقديم بقية المشهد مع اختبار عمق.

وبهذه الطريقة، من المؤكد أنك ستحصل على تفاعل المشهد مع الجسيمات لطيفة المظهر.

نصائح أخرى

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

glEnable(GL_DEPTH_TEST);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_POINT_SPRITE);
glEnable(GL_CULL_FACE);

while(1)
{
    ...
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glDisable(GL_BLEND);
    glDepthMask(1);
    RenderOpaque();
    SortSprites();
    glEnable(GL_BLEND);
    glDepthMask(0);
    DrawSprites();
    ...
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top