Создание элементов из аргументов макроса с переменным числом аргументов

Я пытаюсь создать структуры вершин в OpenGL, используя макросы для определения основ вершин, и макрос в конечном итоге генерирует шаблонный код, необходимый для использования с OpenGL (glGetAttribLocation, glEnableVertexAttribArray, glVertexAttribPointer и т. д.).

Мои макросы определены как таковые:

#define DEFINE_GPU_VERTEX_ATTRIBUTE(R, DATA, ELEM) BOOST_PP_CAT(ELEM, DATA);

#define DEFINE_GPU_VERTEX(NAME, ...) struct NAME##_gpu_vertex_t \
{ \
    BOOST_PP_SEQ_FOR_EACH(DEFINE_GPU_VERTEX_ATTRIBUTE, _, __VA_ARGS__) \
}

Это пример того, как я собираюсь использовать макрос:

DEFINE_GPU_VERTEX(bsp,
((vec3_t), position),
((vec3_t), normal),
((vec2_t), texcoord));

Где первый аргумент (bsp) — это префикс имени, а все переменные аргументы — это пары типов и имен атрибутов.

Я ожидаю, что он сгенерирует определение структуры следующим образом:

struct bsp_gpu_vertex_t
{
    vec3_t position;
    vec3_t normal;
    vec2_t texcoord;
}

Однако, похоже, он генерирует пустую структуру. Что я здесь делаю неправильно?

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

Любая помощь приветствуется!


person Colin Basnett    schedule 26.07.2014    source источник
comment
Получите предварительно обработанную форму (например, с помощью g++ -C -E или с помощью соответствующего компилятора и IDE) и загляните внутрь с помощью редактора или пейджера (например, less). Также сообщите, какой компилятор и операционную систему вы используете, и какова ваша команда компиляции.   -  person Basile Starynkevitch    schedule 26.07.2014
comment
Я использую Visual Studio 2013.   -  person Colin Basnett    schedule 26.07.2014
comment
BOOST_PP_**SEQ**_FOR_EACH требуется последовательность, а вы ее не предоставляете. Существует макрос, который преобразует вариативные данные в последовательность, может помочь. Я считаю, что обычный способ сделать это (по крайней мере, тот, который используется в адаптациях/определениях структур слияния) состоит в том, чтобы использовать непосредственно последовательность. Второй и третий подходы в этом ответе может помочь.   -  person llonesmiz    schedule 28.07.2014


Ответы (1)


Предупреждение: это может не ответить на ваш первоначальный вопрос. Это даже не ответ, а скорее вопрос:

Рассматривали ли вы создание этих struct с использованием языка высокого уровня вместо макросов C?

Как вы уже поняли, макросы C неуклюжи и сложны для отладки. Я бы предпочел написать сценарий (скажем, на Python, но подойдет любой язык сценариев с хорошо развитыми возможностями обработки строк), который выводит файл opengl_boilerplate.h, содержащий ваши объявления struct. Затем вы будете вызывать этот сценарий при сборке вашего программного обеспечения. Я не знаю, как это сделать с VS2013, но, возможно, достаточно запустить его один раз (зависит от вашего проекта).

person Laryx Decidua    schedule 26.07.2014
comment
Интересная идея, но она делает пару вещей, которых я не хочу. Во-первых, он создает зависимость от того, установлен ли Python на машине, на которой он компилируется. Он также добавляет еще один шаг сборки, которого можно было бы избежать, используя макросы, как я изначально планировал. - person Colin Basnett; 27.07.2014
comment
Да, это важные моменты, которые следует учитывать. FWIW, я всегда использую CMake (cmake.org) для создания своих проектов C++, и его можно использовать для такого рода генерации заголовочных файлов с меньшими трудностями. В любом случае проект зависит от CMake, и CMake бесплатно позаботится о дополнительном этапе сборки. Он может генерировать проекты VS. Может быть, вы тоже присмотритесь к этому варианту. - person Laryx Decidua; 27.07.2014