الكاكاو و OpenGL ، كيف يمكنني تعيين سمة قمة GLSL باستخدام صفيف؟
-
21-09-2019 - |
سؤال
أنا جديد إلى حد ما على OpenGL ، ويبدو أنني أواجه بعض الصعوبات. لقد كتبت تظليلًا بسيطًا في GLSL ، من المفترض أن يقوم بتحويل القمم بمصفوفات مفصلية معينة ، مما يسمح بالرسوم المتحركة الهيكلية البسيطة. كل قمة لها مؤثرات عظمية كحد أقصى (مخزنة كمكونات X و Y من VEC2) ، والمؤشرات والأوزان المقابلة المرتبطة بمجموعة من مصفوفات التحول ، ويتم تحديدها على أنها "متغيرات السمة" في تظليلتي ، ثم تعيينها باستخدام وظيفة "glvertexattribpointer".
إليك المكان الذي تنشأ فيه المشكلة ... لقد تمكنت من تعيين مجموعة "المتغير الموحد" من المصفوفات بشكل صحيح ، عندما أتحقق من تلك القيم في التظليل ، يتم استيراد جميعها بشكل صحيح وتحتوي على البيانات الصحيحة. ومع ذلك ، عندما أحاول تعيين متغير المؤشرات المشتركة ، يتم ضرب القمم بواسطة مصفوفات التحول التعسفي! إنهم يقفزون إلى مواقع عشوائية على ما يبدو في الفضاء (والتي تختلف في كل مرة) من هذا ، أفترض أن المؤشرات يتم تعيينها بشكل غير صحيح وأن تظليلتي يقرأ في نهاية صفيف مصفوفة المشترك في الذاكرة التالية. لست متأكدًا تمامًا من السبب ، لأنه عند قراءة جميع المعلومات التي يمكنني العثور عليها في هذا الموضوع ، فوجئت برؤية نفس الكود (إن لم يكن متشابهة جدًا) في أمثلةهم ، ويبدو أنه يعمل لصالحهم.
لقد حاولت حل هذه المشكلة لبعض الوقت الآن وبدأت حقًا في الحصول على أعصابي ... أعرف أن المصفوفات صحيحة ، وعندما أقوم بتغيير قيمة الفهرس يدويًا في التظليل إلى عدد صحيح تعسفي ، فإنها تقرأ قيم المصفوفة الصحيحة ويعمل بالطريقة التي ينبغي بها تحويل جميع القمم بهذه المصفوفة ، لكن عندما أحاول استخدام الكود الذي كتبته لتعيين متغيرات السمة ، لا يبدو أنه يعمل.
الرمز الذي أستخدمه لتعيين المتغيرات كما يلي ...
// this works properly...
GLuint boneMatLoc = glGetUniformLocation([[[obj material] shader] programID], "boneMatrices");
glUniformMatrix4fv( boneMatLoc, matCount, GL_TRUE, currentBoneMatrices );
GLfloat testBoneIndices[8] = {1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0};
// this however, does not...
GLuint boneIndexLoc = glGetAttribLocation([[[obj material] shader] programID], "boneIndices");
glEnableVertexAttribArray( boneIndexLoc );
glVertexAttribPointer( boneIndexLoc, 2, GL_FLOAT, GL_FALSE, 0, testBoneIndices );
وظللي في قمة الرأس يبدو مثل هذا ...
// this shader is supposed to transform the bones by a skeleton, a maximum of two
// bones per vertex with varying weights...
uniform mat4 boneMatrices[32]; // matrices for the bones
attribute vec2 boneIndices; // x for the first bone, y for the second
//attribute vec2 boneWeight; // the blend weights between the two bones
void main(void)
{
gl_TexCoord[0] = gl_MultiTexCoord0; // just set up the texture coordinates...
vec4 vertexPos1 = 1.0 * boneMatrices[ int(boneIndex.x) ] * gl_Vertex;
//vec4 vertexPos2 = 0.5 * boneMatrices[ int(boneIndex.y) ] * gl_Vertex;
gl_Position = gl_ModelViewProjectionMatrix * (vertexPos1);
}
لقد بدأ هذا حقًا في إحباطني ، وسيكون أي وجميع المساعدة موضع تقدير ،
-أندرو غوتو
المحلول
حسنًا ، لقد اكتشفت ذلك. يرسم OpenGL مثلثات مع وظيفة السحب من خلال قراءة كل 9 قيم كمثلث (3 رؤوس مع 3 مكونات لكل منها). ولهذا السبب ، يتم تجديد القمم بين المثلثات ، لذلك إذا كانت هناك مثلثتين متجاورتين تشتركان في قمة ، فإنها تظهر مرتين في الصفيف. لذا فإن المكعب الذي اعتقدت في الأصل لديه 8 رؤوس ، في الواقع 36!
ستة جوانب ، مثلثتان ، جانبان ، ثلاث رؤوس لكل مثلث ، كلها تضاعف ما مجموعه 36 رؤوسًا مستقلة بدلاً من 8 رؤوس مشتركة.
كانت المشكلة بأكملها مشكلة في تحديد عدد قليل جدًا من القيم. بمجرد أن قمت بتمديد مجموعة الاختبار الخاصة بي لتشمل 36 قيمًا عملت بشكل مثالي.