как сдвинуть данные u16 * - PullRequest
1 голос
/ 01 января 2012

Извините, если это не имеет смысла, но я стараюсь изо всех сил, чтобы понять это сам.

Так что у меня в основном есть указатель на данные для текстуры в openGL, это 16 bpp (pcx).image.data16), и мне нужно включить альфа-бит для каждого пикселя.Итак, я придумал это, но, как вы можете сказать, это действительно плохо.

for(int i = 0; i < (TEXTURE_SIZE_128 * TEXTURE_SIZE_128); i++){
        pcx.image.data16 |=  1 << ((16 * i) + 15);
    }

Я получаю эти ошибки:

c:/Users/me/Desktop/neronds/source/neroedge.cpp:40:43: error: invalid operands of types 'u16* {aka short unsigned int*}' and 'int' to binary 'operator|'
c:/Users/me/Desktop/neronds/source/neroedge.cpp:40:43: error:   in evaluation of 'operator|=(u16* {aka short unsigned int*}, int)'

Как мне исправить эти ошибкии я на правильном пути к изменению альфа-бита на пиксель?

Ответы [ 2 ]

5 голосов
/ 01 января 2012

Попробуйте:

for(unsigned i = 0; i < (TEXTURE_SIZE_128 * TEXTURE_SIZE_128); i++)
    {
        constexpr u16 ALPHA_BIT = 1 << 15;
        pcx.image.data16[i] |= ALPHA_BIT;
    }

Если ваш компилятор еще не поддерживает constexpr (функция c ++ 11), используйте const вместо.

0 голосов
/ 01 января 2012

Вам уже были даны ответы, как это исправить, но нет объяснения, почему ваш код был неправильным.Давайте посмотрим на этот фрагмент кода:

pcx.image.data16 |=  1 << ((16 * i) + 15);

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

(int) << (((int) * (int)) + (int));

хорошо, там только int, так что типом операции будет int.В зависимости от платформы число битов ограничено.Но скажем для удобства, что int имеет 64 бита.Это означает, что любой сдвиг влево на 1 из более чем 65 битов сместит бит из доступных битов, и вы получите нулевые биты.Но мы еще не закончили.

После этого вы назначаете int для uint16_t.Теперь вот следующее заблуждение.Тип uint16_t указан для предоставления не менее 16 бит (C не очень точен в этих вещах, потому что он может работать на платформе, где размер слова не кратен 8 битам).Но ради этого объяснения давайте предположим, что это ровно 16 бит.Присвоение

(uint16_t) = (int)

приводит к тому, что оно отбрасывает биты, не вписываясь в значение L.

Последнее, но не менее важное: выражение pcx.image.data16 является указателем.Этот указатель указывает на самый первый элемент вашего массива данных.Назначая этот указатель, вы изменяете только этот указатель, а не данные, на которые он указывает.Таким образом, вы должны разыменовать указатель.Вы можете разыменовать указатель, добавив к нему * или добавив оператор индексирования […]. Обратите внимание, что * и [0] идентичны! Так что, если вы сделали

 *pcx.image.data16;

, это будет только разыменование первого элемента массива (который, вероятно, будет иметь 16 бит, номожет больше).В любом случае: Вы не можете назначить ему больший битовый вектор, который «оборачивается» в следующие элементы (и это хорошо!).

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

for(int i = 0; i < (TEXTURE_SIZE_128 * TEXTURE_SIZE_128); i++){
    pcx.image.data16[i] |=  1 << 15;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...