glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid*)data);
Сначала положительные вещи. Вы используете размер внутреннего формата (GL_RGBA8, а не GL_RGBA). Это очень хорошо; продолжай делать это. Вы четко понимаете разницу между внутренним форматом (GL_RGBA8) и форматом передачи пикселей (GL_RGBA). Это тоже хорошо.
Проблема заключается в следующем. Вы сказали OpenGL, что ваши данные представляют собой поток неподписанных байтов. Но это , а не поток байтов без знака; это поток беззнаковых целых чисел . Вот как вы объявили data
, вот как вы заполнили data
. Так почему ты лжешь OpenGL?
Проблема с вашими цветами. Это одно из ваших значений цвета:
((156 << 24) | (256 << 16) | (156 << 8) | (200 << 0))
Во-первых, 256 не является допустимым цветом. 256 в шестнадцатеричном формате - это 0x100, то есть два байта, а не один.
Целое число без знака, которое вы получите из этого:
0x9D009CC8
Если предполагается, что это цвета RGBA в указанном порядке, то красный - 0x9D, зеленый - 0x00, синий - 0x9C, а альфа - 0xC8.
Теперь, поскольку вы, вероятно, работаете на компьютере с прямым порядком байтов, эти 4 байта хранятся в перевернутом виде, например:
0xC89C009D
Когда вы говорите OpenGL притвориться, что это байтовый массив (а это не так), вы теряете преобразование с прямым порядком байтов. Таким образом, OpenGL видит байтовый массив, начинающийся с 0xC8, так что это красное значение. И так далее.
Вам нужно сообщить OpenGL, что вы на самом деле делаете: вы храните четыре 8-разрядных значения без знака в одном 32-разрядном целом числе без знака. Для этого используйте следующее:
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 256, 256, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, (GLvoid*)data);
GL_UNSIGNED_INT_8_8_8_8 говорит, что вы передаете OpenGL массив беззнаковых 32-битных целых чисел (которыми вы являетесь). Первые 8 битов 32-разрядного целого числа - красные, вторые - зеленые, третьи - синие, а четвертые - альфа.
Итак, чтобы полностью исправить ваш код, вам нужно:
GLuint* data = new GLuint[256*256]; //Use OpenGL's types
for (int y = 0; y < 256; ++y)
for (int x = 0; x < 256; ++x)
if ((x - 100)*(x - 100) + (y - 156)*(y - 156) < 75*75)
data[256*y + x] = ((0x9C << 24) | (0xFF << 16) | (0x9C << 8) | (0xC8 << 0));
else
data[256*y + x] = 0; // I'd expect this to be transparent and the above to be slightly transparent and green, but it's red somehow.
glBindTexture(GL_TEXTURE_2D, texid);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); //Always set the base and max mipmap levels of a texture.
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 256, 256, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, (GLvoid*)data);
// Я бы ожидал, что он будет прозрачным, а вышеприведенный будет слегка прозрачным и зеленым, но каким-то образом красным.
Альфа не означает прозрачный ; это вообще ничего не значит, если вы не придете этому смысла. Альфа представляет прозрачность, только если вы используете смешивание и устанавливаете режим смешивания, который заставляет низкий альфа сделать вещи прозрачными. В противном случае это вообще ничего не значит.