2012-10-22 2 views
2

В спецификации OpenGL есть определенные параметры, которые принимают набор значений от GL_OBJECTENUMERATIONi с i от 0 до некоторого числа, обозначенного чем-то вроде GL_MAX_OBJECT. (Горит как «объект», как один пример.) Кажется очевидным, что указанное число должно быть передано через верхнюю границу через функцию glGet, обеспечивающую некоторую косвенность.Каков наилучший способ подписи числовых параметров для OpenGL?

Однако, согласно буквальному толкованию спецификации OpenGL параметр «текстуры» для glActiveTexturemust be one of GL_TEXTUREi, where i ranges from 0 (GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1) означает, что множество принятых констант должно быть GL_TEXTURE0 к GL_TEXTURE35660, поскольку константа является константой значения 35661.

Language-адвокатская практика в сторону, эта установка означает, что подтип может быть не только не пересекаются, но из того, как хорошо, так что следующий C-иш отображение будет действительным:

#define GL_TEXTURE0    0x84C0 
#define GL_TEXTURE1    0x84C1 
#define GL_TEXTURE2    0x84C2 
#define GL_TEXTURE3    0x84A0 
#define GL_TEXTURE4    0x84A4 
#define GL_TEXTURE5    0x84A5 
#define GL_TEXTURE6    0x84A8 
#define GL_TEXTURE7    0x84A2 

Во-первых, это проблема на самом деле проблема или константы всегда выложено как GL_OBJECTi = GL_OBJECTi-1 +1?

Если это соотношение справедливо, то есть возможность использования функции подтипа Ады, чтобы избежать передачи в недопустимых параметров ...

В идеале, что-то вроде:

-- This is an old [and incorrect] declaration using constants. 
-- It's just here for an example. 
SubType Texture_Number is Enum Range 
    GL_TEXTURE0..Enum'Max(
      GL_MAX_TEXTURE_COORDS - 1, 
      GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1); 

Но, если максимум определяется динамически, то мы должны сделать некоторые monkeying о:

With GL_Constants; 
Generic 
    GL_MAX_TEXTURE : Integer; 
    -- ...and one of those for EACH maximum for the ranges. 
Package Types is 
    Use GL_Constants; 

    SubType Texture_Number is Enum Range 
     GL_TEXTURE0..GL_MAX_TEXTURE;  
End Types; 

с конкретизации Package GL_TYPES is new Types( GL_MAX_TEXTURE => glGet(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS));, а затем использовать этот новый GL_TYPES пакет ... немного больше работы и немного более громоздкий, чем простой подтипирование.

Большая часть этого происходит от того, чтобы быть совершенно новым для OpenGL и не полностью знать/понимать его; но он вызывает интересные вопросы о том, как лучше всего приступить к построению хорошей, толстой привязки Ады.

+1

Hat подскажите вам, задав этот вопрос, вместо того, чтобы просто игнорировать проблему, как это было в моей привязке OpenGLAda. – flyx

ответ

4

означает, что множество принятых констант должны быть GL_TEXTURE0 к GL_TEXTURE35660, потому что постоянная константа значения 35661.

Нет, это не означает, что это. GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS является значение в зависимости от реализации, то есть быть запрошен во время выполнения с помощью glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, out)

Что касается остального: спецификации OpenGL состояний, что GL_TEXTURE = GL_TEXTURE0 + I, и аналогично для всех остальных типов объектов, с i < n, где п является некоторым разумным числом.

3

Это одна из тех ситуаций, когда я не думаю, что получение лишней сексуальности с типами покупает вас много.

Если вы хотите сделать особый целочисленный тип для GL_TEXTURE (type GL_TEXTURE is 16#84C0# .. 16#8B4C#;) и использовать этот тип для всех параметров, ищущих GL Textures, компилятор не позволит пользователю выполнять математику между этими и другими целыми объектами. Этого, наверное, будет много. Это очень качественно, чем то, к чему привязаны бедные кодеры C/C++!

С другой стороны, я никогда не был сторонником сверхплотных привязок Ады. Связывание Ada должно использоваться, чтобы сделать типы более Ada-like и преобразовать коды ошибок C в исключения. Если есть другие способы сохранить пользователю немного работы, продолжайте и делайте это. Однако не отвлекайте ни одну из возможностей API!


Было несколько вопросов в комментариях к моему выбору использования отдельного числового типа, а не подтема Integer.

Это обычная ошибка Ada noob, чтобы начать создавать пользовательские числовые типы, когда будут выполняться подтипы integer, а затем раздражаться при всех преобразованиях типов, которые вы должны выполнить. Классическим примером является то, что кто-то делает тип для скорости, затем другой тип для расстояния, затем другой для силы, а затем обнаруживает, что они должны делать преобразование типа на каждой отдельной проклятой математической операции.

Тем не менее, бывают случаи, когда требуются пользовательские числовые типы. В частности, вы хотите использовать пользовательский числовой тип, когда объекты этого типа должны жить в юниверсе отдельного типа из нормальных чисел. Наиболее распространенное происхождение этого происходит в привязках API, где указанное число фактически является обозначением C-ish для некоторого ресурса. Точная ситуация здесь. Единственная математика, которую вы когда-либо захотите сделать на GL_Texture, - это сравнение с границами типа и простое добавление и вычитание буквальной суммы. (Скорее всего, GL_Texture'next() будет достаточным.)

В качестве огромного бонуса, сделав его особым типом, будет предотвращена общая ошибка при подключении значения GL_Texture к неправильному параметру в вызове API. C API звонки действительно любят их int s ...

На самом деле, если было разумно сидеть и набирать их все, я подозреваю, что у вас возникнет соблазн просто сделать это перечислением. Это было бы еще менее совместимо с Integer без конверсий, но никто здесь не подумал бы дважды об этом.

+0

Математика - вот почему я хочу использовать подтип, а не весь новый тип, для параметров со спецификацией «принимает GL_RGB или GL_RGBA» новый тип является хорошим выбором. – Shark8

+0

Почему не подтип: 'подтип gl_texture является целым числом 16 # 84C0 # .. 16 # 8B4C#;' Это должно позволить вам проверить, является ли оно 'in' gl_texture, но не ограничивает числовые операции (слишком плохо!). – NWS

+0

@NWS и Shark8. В свое время я сделал довольно много привязок API на основе C, и да, использование пользовательского числового типа является преднамеренным. Я попытался добавить свою логику в ответ выше. Короче говоря, не стучите, пока не попробуете. :-) –

2

ОК, первое правило, которое вы должны знать о OpenGL: когда вы видите что-то, что говорит, «идет от X до Y», и один из этих значений является GL_THINGY, они не говорить о числовой значение GL_THINGY. Они говорят о зависящем от реализации значении, которое вы запрашиваете у сGL_THINGY. Обычно это целое число, поэтому для его запроса используется некоторая форма glGetIntegerv.

Следующая:

эта установка означает, что подтип может быть не только не пересекаются, но из того, как хорошо, так что следующий C-иш отображение будет действительным:

Нет , это не так.

Каждому действительному счетчику в OpenGL назначается определенное значение ARB. И ARB присвоены значения для именованного GL_TEXTURE''i «» счетчиками являются:

#define GL_TEXTURE0 0x84C0 
#define GL_TEXTURE1 0x84C1 
#define GL_TEXTURE2 0x84C2 
#define GL_TEXTURE3 0x84C3 
#define GL_TEXTURE4 0x84C4 
#define GL_TEXTURE5 0x84C5 
#define GL_TEXTURE6 0x84C6 
#define GL_TEXTURE7 0x84C7 
#define GL_TEXTURE8 0x84C8 

Обратите внимание, как все они находятся в последовательном упорядочении.

Что касается остальных, позвольте мне процитировать вас из OpenGL 4.3 на glActiveTexture:

Ошибка INVALID_ENUM, если указана недопустимая текстура. текстура является символической константой формы TEXTURE''i '', указывая, что текстурная единица 'i' 'должна быть изменена. Константы подчиняются TEXTURE''i '' = TEXTURE0 + '' i '', где '' i '' находится в диапазоне от 0 до '' k '' - 1, а '' k '' - значение MAX_COMBINED_TEXTURE_IMAGE_UNITS).

Если вы создаете привязку на каком-то языке, общая идея такова: '' не сильно набирать определенные значения ''. Это, в частности. Просто возьмите то, что дает вам пользователь, и передайте его. Если пользователь получает сообщение об ошибке, он получает сообщение об ошибке.

Еще лучше, выведите более разумную версию glActiveTexture, которая берет «целое число» вместо перечислителя и делает дополнение самостоятельно.

+0

Ах, хорошая точка [о определениях ARB]; Я должен был сказать, не мог бы; первый вопрос: «все ** итераторы в OpenGL последовательны?» – Shark8

+0

@ Shark8: Это имеет значение? Единственными, к которым вы должны добавить значения, являются индексируемые, такие как TEXTURE0 и COLOR_ATTACHMENT0. –

+0

Очень. В этом весь смысл вопроса, реализация. Если все значения итератора являются последовательными, я могу сказать, что подтип TEXTURE - это целочисленный диапазон 16 # 84C0 # .. 16 # 84C0 # + NUMBER_OF_TEXTURES; '- Только потому, что примеры, которые я видел, соответствовали этим ограничениям, не означает, что все сделаю. – Shark8

Смежные вопросы