كيف ترسم نسيجًا كخلفية ثنائية الأبعاد في OpenGL ES 2.0؟

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

  •  26-09-2019
  •  | 
  •  

سؤال

لقد بدأت للتو مع OpenGL ES 2.0 ، ما أود القيام به هو إنشاء بعض الإخراج ثنائي الأبعاد البسيط. بالنظر إلى حل 480 × 800 ، كيف يمكنني رسم نسيج الخلفية؟

بيئة التطوير الخاصة بي هي Java / Android ، لذا فإن الأمثلة المتعلقة مباشرة بذلك ستكون الأفضل ، لكن اللغات الأخرى ستكون على ما يرام.

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

المحلول

على الرغم من أنك على Android ، قمت بإنشاء تطبيق نموذج iPhone يقوم بذلك لإطارات الفيديو القادمة. يمكنك تنزيل الرمز لهذه العينة من هنا. لديّ كتابة حول هذا التطبيق ، والذي يقوم بتتبع الكائنات القائمة على الألوان باستخدام الفيديو المباشر ، يمكنك القراءة هنا.

في هذا التطبيق ، أرسم مثلثتين لإنشاء مستطيل ، ثم نسيج باستخدام الإحداثيات التالية:

   static const GLfloat squareVertices[] = {
        -1.0f, -1.0f,
        1.0f, -1.0f,
        -1.0f,  1.0f,
        1.0f,  1.0f,
    };

    static const GLfloat textureVertices[] = {
        1.0f, 1.0f,
        1.0f, 0.0f,
        0.0f,  1.0f,
        0.0f,  0.0f,
    };

لتمرير إطار الفيديو كملمس ، أستخدم برنامجًا بسيطًا مع تظليل Vertex التالي:

attribute vec4 position;
attribute vec4 inputTextureCoordinate;

varying vec2 textureCoordinate;

void main()
{
    gl_Position = position;
    textureCoordinate = inputTextureCoordinate.xy;
}

وتظليل الشظية التالي:

varying highp vec2 textureCoordinate;

uniform sampler2D videoFrame;

void main()
{
    gl_FragColor = texture2D(videoFrame, textureCoordinate);
}

الرسم مسألة بسيطة لاستخدام البرنامج الصحيح:

glUseProgram(directDisplayProgram);

ضبط زي الملمس:

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, videoFrameTexture);

glUniform1i(uniforms[UNIFORM_VIDEOFRAME], 0);   

تعيين السمات:

glVertexAttribPointer(ATTRIB_VERTEX, 2, GL_FLOAT, 0, 0, squareVertices);
glEnableVertexAttribArray(ATTRIB_VERTEX);
glVertexAttribPointer(ATTRIB_TEXTUREPOSITON, 2, GL_FLOAT, 0, 0, textureVertices);
glEnableVertexAttribArray(ATTRIB_TEXTUREPOSITON);

ثم رسم المثلثات:

glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

نصائح أخرى

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

هناك الكثير من الأماكن التي توضح كيفية القيام بذلك ، وربما يكون هناك حتى مشروع مثال Android يعرض ذلك.

الجزء الصعب هو الحصول على شيء لعرضه أمام شيء آخر أو وراءه. لكي يعمل هذا ، تحتاج إلى إعداد مخزن مؤقت للعمق وتمكين اختبار العمق (glenable (gl_depth_test)). تحتاج رؤوسك إلى إحداثيات Z (وأخبر Gldrawelements أن رؤوسك تتكون من ثلاث قيم ، وليس قيمتين).

إذا لم تفعل ذلك ، فسيتم تقديم الكائنات بالترتيب التي تسمى وظائف GldrawElements () (بمعنى أيهما ترسم آخر مرة ستحجب الباقي).

نصيحتي هي عدم وجود صورة خلفية أو القيام بأي شيء يتوهم حتى تحصل على تعليق منه. يحتوي OpenGL ES 2.0 على نوع من منحنى التعلم الحاد ، ولا تساعد البرامج التعليمية على ES 1.x حقًا في الحصول على ثلاثية الأبعاد لأنها يمكن أن تستخدم وظائف مساعد مثل Gluperseptive ، والتي لا يوجد بها 2.0 فقط. ابدأ بإنشاء مثلث على خلفية لا شيء. بعد ذلك ، اجعلها مربعًا. ثم ، إذا كنت تريد أن تتخيل بالفعل ، أضف نسيجًا. العب مع المناصب. تعرف على ما يحدث عند تغيير قيمة Z لرؤوسك. (تلميح: ليس كثيرًا ، إذا لم يكن لديك اختبار عمق تم تمكينه. وحتى ذلك الحين ، إذا لم يكن لديك عرض منظور ، فلن تصبح الكائنات أصغر كلما كانت بعيدًا ، لذلك سيظل يبدو كما لو لم يكن هناك شيء حدث)

بعد بضعة أيام ، يتوقف عن الإحباط اللعين ، وأخيراً "تحصل عليه" ، في الغالب.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top