LINUX.ORG.RU
ФорумTalks

Палю годноту или OpenGL готов для десктопа

 ,


0

0

Тем, кто использует OpenGL, clang 3.2 и функции glVertexPointer/glNormalPointer, предлагаю заценить фишку. Вставьте это где-нибудь после включения <GL/gl.h> или <GL/glew.h> в том файле, где используется glVertexPointer или glNormalPointer

#if defined(__has_attribute)
extern void GLAPIENTRY glNormalPointer (GLenum type, GLsizei stride, const GLvoid *pointer)
        __attribute__((pointer_with_type_tag(opengl, 3, 1)));
extern void GLAPIENTRY glVertexPointer (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
__attribute__((pointer_with_type_tag(opengl, 4, 2)));

GLenum opengl_predefined_t_double
__attribute__(( type_tag_for_datatype(opengl,const double) )) = GL_DOUBLE;
GLenum opengl_predefined_t_float
__attribute__(( type_tag_for_datatype(opengl,const float) )) = GL_FLOAT;
GLenum opengl_predefined_t_unsigned_byte
__attribute__(( type_tag_for_datatype(opengl,const unsigned char) )) = GL_UNSIGNED_BYTE;
GLenum opengl_predefined_t_unsigned_int
__attribute__(( type_tag_for_datatype(opengl,const unsigned int) )) = GL_UNSIGNED_INT;

#undef GL_DOUBLE
#undef GL_FLOAT
#undef GL_UNSIGNED_BYTE
#undef GL_UNSIGNED_INT
#define GL_DOUBLE opengl_predefined_t_double
#define GL_FLOAT opengl_predefined_t_float
#define GL_UNSIGNED_BYTE opengl_predefined_t_unsigned_byte
#define GL_UNSIGNED_INT opengl_predefined_t_unsigned_int

#endif

А потом попробуйте заменить работающий...

glNormalPointer(GL_DOUBLE, 0, m_normales.front());
...на заведомо бажный...
glNormalPointer(GL_FLOAT, 0, m_normales.front());
...и скомпилировать. В данном случае m_normales — массив векторов, а вектор имеет оператор приведения к типу к const double *.

Ответ на: комментарий от Reinar
AppDelegate.cpp:122: warning: argument type 'const double *' doesn't match specified 'opengl' type tag that requires 'const float *' [-Wtype-safety]
    glNormalPointer(GL_FLOAT, 0, m_normales.front());
                    ~~~~~~~~     ^~~~~~~~~~~~~~~~~~
quiet_readonly ★★★★ ()
Ответ на: комментарий от x0r

Варнинга нет

    typedef const float arr[3];
    arr array = {1, 2, 3};
    glVertexPointer(3, GL_FLOAT, 0, array);
Варнинг есть
    typedef const float arr[3];
    arr array = {1, 2, 3};
    glVertexPointer(3, GL_DOUBLE, 0, array);
AppDelegate.cpp:123: warning: argument type 'const float *' doesn't match specified 'opengl' type tag that requires 'const double *' [-Wtype-safety]
    glVertexPointer(3, GL_DOUBLE, 0, array);
                       ~~~~~~~~~     ^~~~~

quiet_readonly ★★★★ ()

А вообще — это же такие костыли. По стилю похоже на скалу, где на каждую задачу свой DSL изобретают.

note173 ★★★★★ ()
Ответ на: комментарий от note173

По стилю похоже на скалу, где на каждую задачу свой DSL изобретают.
По стилю похоже на руби, где на каждую задачу свой DSL изобретают.

удвоил

ZuBB ★★★★★ ()

Хренотень какая-то. Если хочется проверки типов, достаточно использовать подобные обертки:

static inline void GL_VertexFloatPointer(GLint size, GLsizei stride, const GLfloat *pointer)
{   
    glVertexPointer(size, GL_FLOAT, sizeof(GLfloat) * stride, pointer); 
}

static inline void GL_VertexDoublePointer(GLint size, GLsizei stride, const GLdouble *pointer)
{   
    glVertexPointer(size, GL_DOUBLE, sizeof(GLdouble) * stride, pointer); 
}

Работать будет в любом компиляторе и не нужно ломать заголовочные файлы.

Deleted ()
Ответ на: комментарий от Deleted

Работать будет в любом компиляторе и не нужно ломать заголовочные файлы.

Одна беда — надо переписывать существующие исходники. Предлагаемое clang'ом расширение позволяет один раз добавить аттрибуты в системном заголовке и проверять типы всегда.

К сожалению, пока только две реализации MPI используют эту фичу. Попробую в будущем сделать патчик для GLEW хотя бы.

quiet_readonly ★★★★ ()
Ответ на: комментарий от Daeloce

Ругнётся при компиляции, если stdlib.h не подключен.

DELIRIUM ☆☆☆☆☆ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.