في OpenGL، هل هناك طريقة للحصول على قائمة بجميع الزي الرسمي والسمات التي يستخدمها برنامج التظليل؟

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

  •  22-07-2019
  •  | 
  •  

سؤال

أرغب في الحصول على قائمة بجميع الزي الرسمي والسمات التي يستخدمها كائن برنامج التظليل. glGetAttribLocation() & glGetUniformLocation() يمكن استخدامها لتعيين سلسلة إلى موقع ما، ولكن ما أريده حقًا هو قائمة السلاسل دون الحاجة إلى تحليل كود glsl.

ملحوظة:في برنامج OpenGL 2.0 glGetObjectParameteriv() لقد بدل بواسطة glGetProgramiv().والتعداد هو GL_ACTIVE_UNIFORMS & GL_ACTIVE_ATTRIBUTES.

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

المحلول

المتغيرات المشتركة بين المثالين:

GLint i;
GLint count;

GLint size; // size of the variable
GLenum type; // type of the variable (float, vec3 or mat4, etc)

const GLsizei bufSize = 16; // maximum name length
GLchar name[bufSize]; // variable name in GLSL
GLsizei length; // name length

صفات

glGetProgramiv(program, GL_ACTIVE_ATTRIBUTES, &count);
printf("Active Attributes: %d\n", count);

for (i = 0; i < count; i++)
{
    glGetActiveAttrib(program, (GLuint)i, bufSize, &length, &size, &type, name);

    printf("Attribute #%d Type: %u Name: %s\n", i, type, name);
}

الزي الرسمي

glGetProgramiv(program, GL_ACTIVE_UNIFORMS, &count);
printf("Active Uniforms: %d\n", count);

for (i = 0; i < count; i++)
{
    glGetActiveUniform(program, (GLuint)i, bufSize, &length, &size, &type, name);

    printf("Uniform #%d Type: %u Name: %s\n", i, type, name);
}

وثائق OpenGL / الأنواع المتغيرة

يمكن العثور على مختلف وحدات الماكرو التي تمثل أنواع متغيرة في المستندات.مثل GL_FLOAT, GL_FLOAT_VEC3, GL_FLOAT_MAT4, ، إلخ.

نصائح أخرى

لقد كان هناك تغيير في كيف يتم هذا النوع من شيء في OpenGL. لذلك دعونا الطريقة القديمة والطريقة الجديدة في .

قديم الطريق

وتظليل مرتبط لديها مفهوم عددا من الزي نشطة وسمات النشطة (المدخلات قمة المرحلة تظليل). هذه هي زي / الصفات التي هي قيد الاستخدام من قبل أن تظليل. يمكن الاستعلام عن عدد هذه (وكذلك عدد غير قليل من الأشياء الأخرى) مع glGetProgramiv :

GLint numActiveAttribs = 0;
GLint numActiveUniforms = 0;
glGetProgramiv(prog, GL_ACTIVE_ATTRIBUTES, &numActiveAttribs);
glGetProgramiv(prog, GL_ACTIVE_UNIFORMS, &numActiveUniforms);

ويمكنك الاستعلام كتل موحدة نشطة، وتحويل varyings ردود الفعل، ويتعارض الذرية، وأشياء مماثلة في هذا السبيل.

وبمجرد الانتهاء من عدد من الصفات النشطة / زي، يمكنك أن تبدأ الاستعلام عن المعلومات المتعلقة بها. للحصول على معلومات حول سمة، يمكنك استخدام glGetActiveAttrib . للحصول على معلومات حول موحدة، يمكنك استخدام glGetActiveUniform . وكمثال على ذلك، امتدت من أعلاه:

GLint maxAttribNameLength = 0;
glGetProgramiv(prog, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH​, &maxAttribNameLength);
std::vector<GLchar> nameData(maxAttribNameLength)
for(int attrib = 0; attrib < numActiveAttribs; ++attrib)
{
  GLint arraySize = 0;
  GLenum type = 0;
  GLsizei actualLength = 0;
  glGetActiveAttrib(prog, attrib, nameData.size(), &actualLength, &arraySize, &type, &nameData[0]);
  std::string name((char*)&nameData[0], actualLength - 1);
}

ويمكن أن يتم شيء مماثل للزي الرسمي. ومع ذلك، يمكن للخدعة GL_ACTIVE_UNIFORM_MAX_LENGTH​ يكون عربات التي تجرها الدواب على بعض السائقين. لذلك أود أن أقترح هذا:

std::vector<GLchar> nameData(256);
for(int unif = 0; unif < numActiveUniforms; ++unif)
{
  GLint arraySize = 0;
  GLenum type = 0;
  GLsizei actualLength = 0;
  glGetActiveUniform(prog, unif, nameData.size(), &actualLength, &arraySize, &type, &nameData[0]);
  std::string name((char*)&nameData[0], actualLength - 1);
}

وأيضا، لالزي الرسمي، وهناك glGetActiveUniforms، والتي يمكن الاستعلام عن كافة أطوال اسم لكل موحدة في كل مرة (وكذلك جميع أنواع وأحجام مجموعة، خطوات، وغيرها من المعالم).

طريقة جديدة

وهذه الطريقة تمكنك من الوصول الى حد كبير <م> كل شيء حول المتغيرات النشطة في برنامج مرتبط بنجاح (باستثناء غلوبالس العادية). و ARB_program_interface_query التمديد هو غير متوفر على نطاق واسع حتى الآن، لكنه سوف نصل الى هناك .

ويبدأ مع دعوة glGetProgramInterfaceiv ، للاستعلام عن عدد من الصفات النشطة / الزي الرسمي. أو أي شيء آخر قد ترغب.

GLint numActiveAttribs = 0;
GLint numActiveUniforms = 0;
glGetProgramInterfaceiv(prog, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, &numActiveAttribs);
glGetProgramInterfaceiv(prog, GL_UNIFORM, GL_ACTIVE_RESOURCES, &numActiveUniforms);

وصفات مدخلات تظليل فقط قمة الرأس. GL_PROGRAM_INPUT يعني مدخلات البرنامج الأول في الكائن البرنامج.

ويمكنك بعد ذلك حلقة على عدد من الموارد الفعالة، وطلب لمزيد من المعلومات حول كل واحد بدوره، من <لأ href = "http://www.opengl.org/wiki/GLAPI/glGetProgramResource" يختلط = "noreferrer" > glGetProgramResourceiv و glGetProgramResourceName :

std::vector<GLchar> nameData(256);
std::vector<GLenum> properties;
properties.push_back(GL_NAME_LENGTH​);
properties.push_back(GL_TYPE​);
properties.push_back(GL_ARRAY_SIZE​);
std::vector<GLint> values(properties.size());
for(int attrib = 0; attrib < numActiveAttribs; ++attrib)
{
  glGetProgramResourceiv(prog, GL_PROGRAM_INPUT, attrib, properties.size(),
    &properties[0], values.size(), NULL, &values[0]);

  nameData.resize(values[0]); //The length of the name.
  glGetProgramResourceName(prog, GL_PROGRAM_INPUT, attrib, nameData.size(), NULL, &nameData[0]);
  std::string name((char*)&nameData[0], nameData.size() - 1);
}

وقال إن نفس رمز بالضبط تعمل من أجل GL_UNIFORM. مجرد مبادلة numActiveAttribs مع numActiveUniforms.

لأي شخص هناك أن يجد هذا السؤال تتطلع إلى القيام بذلك في تقنية WebGL، وهنا ما يعادل تقنية WebGL:

var program = gl.createProgram();
// ...attach shaders, link...

var na = gl.getProgramParameter(program, gl.ACTIVE_ATTRIBUTES);
console.log(na, 'attributes');
for (var i = 0; i < na; ++i) {
  var a = gl.getActiveAttrib(program, i);
  console.log(i, a.size, a.type, a.name);
}
var nu = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS);
console.log(nu, 'uniforms');
for (var i = 0; i < nu; ++i) {
  var u = gl.getActiveUniform(program, i);
  console.log(i, u.size, u.type, u.name);
}

وهنا هو رمز المقابلة في بيثون للحصول على الزي الرسمي:

from OpenGL import GL
...
num_active_uniforms = GL.glGetProgramiv(program, GL.GL_ACTIVE_UNIFORMS)
for u in range(num_active_uniforms):
    name, size, type_ = GL.glGetActiveUniform(program, u)
    location = GL.glGetUniformLocation(program, name)

ويبدو أن "طريقة جديدة" من قبل نيكول بولاس المذكورة لا يعمل في بيثون.

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