OpenGL/GLEW: Как да изберем правилния/съществуващ enum, без да провокираме грешка по време на компилиране

В момента използвам glew за откриване на някои GPU характеристики на обвързания openGL контекст.

Представете си текстурен клас, където искам да използвам преброяванията на openGL 3.0, ако са налични, и да се върна към разширения, ако opengl 3.0 не е на място, но разширението е, т.е.

uint32 chooseGlInternalFormat(uint32 _pixelType, uint32 _pixelFormat)
{
    uint32 ret;
    //...
    if(GLEW_EXT_texture_integer || GLEW_VERSION_3_0)
    {
        bool bUseExt = !GLEW_VERSION_3_0; //if only the extension is available but not gl 3.0, fallback
        ret = bUseIntEXT ? GL_LUMINANCE8UI_EXT : GL_R8UI;
    }
    //...
}

очевидно това причинява грешка при компилиране, тъй като GL_R8UI няма да съществува, ако opengl 3.0 не се поддържа. - Какъв е обичайният начин за решаване на това?


person moka    schedule 21.09.2011    source източник
comment
Защо това не работи? IIRC, тези макроси се разширяват до извиквания на функции по време на изпълнение (или в противен случай глобални променливи, попълнени от glewInit). Докато изброяванията винаги се предоставят от заглавния файл.   -  person Ben Voigt    schedule 21.09.2011
comment
добре, например, в момента разработвам на OSX, която не поддържа пълна функционалност на ogl 3.0. - Все пак искам да взема това предвид за бъдеща употреба. - Сега, когато на моята платформа ogl 3.0 не е завършен, някои от неговите изброявания просто не са дефинирани , като по този начин причинява грешка при компилиране. в горния пример GL_R8UI не е дефиниран.   -  person moka    schedule 21.09.2011
comment
@moka: Наличието на enum в заглавките ви не вреди, без значение дали OpenGL-3 се предоставя от вашата целева платформа или не. Също така специфичните за платформата корекции на кодовата пътека се изпълняват чрез условна компилация, т.е. #ifdef … {foobarblah;} #endif; GLEW задава няколко дефиниции, в зависимост от това кои функции са активирани по време на компилация. Те се задават в зависимост от това какво може да направи целевата платформа.   -  person datenwolf    schedule 21.09.2011
comment
добре, да кажем, че искам да използвам glGenerateMipmap на ogl 3.0 и по-нови версии и glGenerateMipmapEXT на всички по-ранни версии. - Каква би била надеждна проверка на времето за компилиране, за да се използва правилната функция? коментарите за отговора на pmr показват, че #ifdef GL_VERSION_3_0 не работи в повечето случаи, някакви идеи?   -  person moka    schedule 23.09.2011


Отговори (1)


Някои по-големи приложения приемат най-новата enum спецификация и добавят свои собствени enum въз основа на нея. Ако ви трябва само този път, можете просто да дефинирате свой собствен enum за този единствен случай.

person pmr    schedule 21.09.2011
comment
няма ли тези преброявания да са в конфликт с тези, които всъщност вече са там, ако opengl 3.x съществува? - person moka; 21.09.2011
comment
@moka Трябва да им дадете различни имена, разбира се. Важни са ценностите, а не имената. - person pmr; 21.09.2011
comment
а, добре, мисля, че сега разбирам. Друго нещо, което току-що разбрах е, че въпреки че GLEW работи само по време на изпълнение, мога да използвам обикновен стар #ifdef GL_VERSION_3_0 препроцесор дефинира да включва неща само ако се достигне определена GL версия. Благодаря за съветите! - person moka; 21.09.2011
comment
Препроцесорът не е опция, ако се опитате да разпространявате двоични файлове и кодът е болезнен и труден за тестване/отстраняване на грешки. Ето защо повечето проекти предпочитат хакерското решение. - person pmr; 21.09.2011
comment
бихте ли изяснили защо дефиницията на GL_VERSION_3_0 няма да работи на двоичен файл, ако се използва в .cpp? - person moka; 21.09.2011
comment
@moka Тъй като препроцесорът се задейства само когато приложението е компилирано, но GL версията на платформата, върху която се изпълнява двоичният файл, може да бъде определена само по време на изпълнение. - person pmr; 21.09.2011
comment
@moka: Можете да използвате препроцесора, за да откриете SDK, с който изграждате, като #ifdef GL_R8UI, но не тествайте #ifdef GL_VERSION_3_0, тъй като това винаги ще бъде дефинирано, то се разширява до тест по време на изпълнение. - person Ben Voigt; 21.09.2011
comment
добра идея Бен, мислиш ли, че ако направя това за всички формати, от които се нуждая: #ifndef GL_RGB8UI #define GL_RGB8UI GL_RGB8UI_EXT #endif ще бъде безопасно? тогава бих могъл да използвам само GL_RGB8UI в действителния си код и ако автоматично ще се върна към GL_RGB8UI_EXT, ако е необходимо, нали? - person moka; 21.09.2011