LINUX.ORG.RU

Альфа-каналы в OpenGL


0

0

Сделал 32-битную BMPшку с альфа-каналом: типа значок радиации на прозрачнм фоне. Сам значок радиации в альфа-канале - белым, все остальное - черным. Пытаюсь подгрузить в OpenGL - выходит фигня, не видит он альфа-каналов, все так, как будто их нет вообще. Что делать?

Загрузка такстур сделана так: GLvoid LoadGLTextures(char* texpath, GLuint* texture) { // Загрузка картинки AUX_RGBImageRec* texture2;

texture2 = auxDIBImageLoadA(texpath); glBindTexture(GL_TEXTURE_2D, *texture); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, 3, texture2->sizeX, texture2->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, texture2->data); // glEnable(GL_TEXTURE_2D); }

Налепка текстуры сделана так: glBlendFunc(GL_SRC_ALPHA,GL_ONE); glEnable(GL_BLEND); glEnable(GL_TEXTURE_2D); glColor3f(1,1,1);

glBindTexture(GL_TEXTURE_2D, texture[10]); glBegin(GL_POLYGON); glTexCoord2f(0,0); glVertex3f(camera.x - WINDOWHOR/2, camera.y - WINDOWVERT/2,0.01); glTexCoord2f(1,0); glVertex3f(camera.x + WINDOWHOR/2, camera.y - WINDOWVERT/2,0.01); glTexCoord2f(1,1); glVertex3f(camera.x + WINDOWHOR/2, camera.y + WINDOWVERT/2,0.01); glTexCoord2f(0,1); glVertex3f(camera.x - WINDOWHOR/2, camera.y + WINDOWVERT/2,0.01); glEnd(); glDisable(GL_BLEND); glDisable(GL_TEXTURE_2D); glPushMatrix(); glTranslatef(camera.x-WINDOWHOR/2, camera.y - WINDOWVERT/2,0); glPopMatrix();

Кто знает, где же глюк?

anonymous

glTexImage2D(GL_TEXTURE_2D, 0, 4, texture2->sizeX, texture2->sizeY, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture2->data);
Документацию внимательнее читай [;

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

Из того, что в приведённом куске кода (с GL_RGB), текстура отображалась, можно сделать вывод, что текстура или загружается без альфа-канала, или сохранена была без него.

anonymous
()

Функции загрузки _кошерной_ 32-битной BMPшки с альфа-каналом (TGA),
проверенно работают:

typedef struct
  {
    GLubyte* imageData; // Содержит всю информацию о цвете изображения
    GLuint  bpp;        // Содержит количество бит на пиксель      
    GLuint width;       // Ширина изображения  
    GLuint height;      // Высота изображения  
    GLuint texID;       // идентификатор текстуры для использования совместно с glBindTexture.  
    GLuint type;        // Информация хранимая в * ImageData (GL_RGB или GL_RGBA)

  } Texture;

typedef struct
  {
    GLubyte Header[12];   // Заголовок файла определяющий его тип
  } TGAHeader;
 
  typedef struct
  {
    GLubyte header[6];    // Содержит первые полезные 6 байт файла
    GLuint bytesPerPixel; // Количество байт на пиксель (3 или 4)
    GLuint imageSize;     // Размер памяти необходимый для хранения изображения
    GLuint type;          // Тип изображения, GL_RGB или GL_RGBA
    GLuint Height;        // Высота изображения          
    GLuint Width;         // Ширина изображения        
    GLuint Bpp;           // Количество бит на пиксель (24 или 32)
  } TGA;

TGAHeader tgaheader; // Используется для хранения заголовка файла
TGA tga;             // Используется для хранения информации о файле

// Заголовок несжатого TGA
GLubyte uTGAcompare[12] = {0,0, 2,0,0,0,0,0,0,0,0,0};
// Заголовок сжатого TGA
GLubyte cTGAcompare[12] = {0,0,10,0,0,0,0,0,0,0,0,0};
// Загружает несжатый файл
bool LoadUncompressedTGA(Texture *, char *, FILE *);
// Загружает несжатый файл
bool LoadTGA(Texture * texture, char * filename)
//bool LoadUncompressedTGA(Texture *, char *, FILE *);
{
	FILE * fTGA; // Объявляем указатель на файл
	fTGA = fopen(filename, "rb"); // Открываем файл на чтение
	if(fTGA == NULL)        // Если была ошибка
	{
		printf("Can't open file!\n");//...Error code...
		return false;         // Возвращаем False
	}

	// Попытка прочитать заголовок файла
	if(fread(&tgaheader, sizeof(TGAHeader), 1, fTGA) == 0)
	{
		printf("Can't read file header!\n");//...Здесь код ошибки...
		return false;        // При ошибки возвращаем false
	}  

	// Если заголовок файла соответствует заголовку несжатого файла
	if(memcmp(uTGAcompare, &tgaheader, sizeof(tgaheader)) == 0)
	{
		// Загружаем несжатый TGA
		LoadUncompressedTGA(texture, filename, fTGA);
	}
	// Если заголовок файла соответствует заголовок сжатого файла
	else if(memcmp(cTGAcompare, &tgaheader, sizeof(tgaheader)) == 0)
	{                      
		// Загружаем сжатый TGA
		printf("Image is compressed TGA, is is not suported!\n");//LoadCompressedTGA(texture, filename, fTGA);
		return false;
	}
	else            // Если не соответствует никакому
	{
		printf("Unkown header format!\n");//... Здесь код ошибки...            
		return false;        // Возвращаем false False
	}  
}

// Загружаем несжатый TGA!
bool LoadUncompressedTGA(Texture * texture, char * filename, FILE * fTGA)
{
	// Пытаемся прочитать следующие 6 байт
	if(fread(tga.header, sizeof(tga.header), 1, fTGA) == 0)
	{                    
		printf("Can't read file header!\n");//...Здесь код ошибки...
		return false;        // Возвращаем False
	}
	texture->width  = tga.header[1] * 256 + tga.header[0];  // Вычисляем высоту
	texture->height = tga.header[3] * 256 + tga.header[2];  // Вычисляем ширину
	texture->bpp = tga.header[4]; // Вычисляем количество бит на пиксель
	tga.Width = texture->width;   // Вычисляем высоту в локальной структуре
	tga.Height = texture->height; // Вычисляем ширину в локальной структуре
	tga.Bpp = texture->bpp;       // Вычисляем количество бит на пиксель в локальной структуре

	// Убеждаемся что вся информация корректна
	if((texture->width <= 0) || (texture->height <= 0) || ((texture->bpp != 24) && (texture->bpp !=32)))
	{
		printf("Unknown or corrupted TGA header!\n");//...Здесь код ошибки...
		return false;        // Возвращаем False
	}

	if(texture->bpp == 24)        // Это изображение 24bpp?
		texture->type  = GL_RGB;    // Если да, устанавливаем GL_RGB
	else                          // если не 24, тогда 32
		texture->type  = GL_RGBA;   // устанавливаем GL_RGBA


	tga.bytesPerPixel = (tga.Bpp / 8); // Высчитываем количество байт на пиксель
	// Считаем размер памяти необходимый для хранения изображения
	tga.imageSize = (tga.bytesPerPixel * tga.Width * tga.Height);


	// Выделяем память
	texture->imageData = (GLubyte *) new char[tga.imageSize];
	if(texture->imageData == NULL)      // Убеждаемся что она была выделена
	{
		printf("Can't allocate memory for image!\n");//...Здесь код ошибки...
		return false;        // Если нет, возвращаем False
	}
	// Пытаемся считать все изображение
	if(fread(texture->imageData, 1, tga.imageSize, fTGA) != tga.imageSize)
	{
		printf("Can't read image data!\n");//...Здесь код ошибки...                
		return false;        // Если не получилось, возвращаем False
	}
	// Начинаем цикл
	for(GLuint cswap = 0; cswap < (int)tga.imageSize; cswap += tga.bytesPerPixel)
	{
		// Первый байт XOR третий байт XOR первый байт XOR третий байт
		texture->imageData[cswap] ^= texture->imageData[cswap+2] ^=
		texture->imageData[cswap] ^= texture->imageData[cswap+2];
	}

	fclose(fTGA);          // Закрываем файл
	return true;          // Возвращаем true
}

GLuint loadTexture(char *filename)
{	
	Texture img;
	GLuint texture;
	img.imageData = NULL;
	if(LoadTGA(&img, filename))
	{
		glGenTextures(1, &texture);
		glBindTexture(GL_TEXTURE_2D, texture);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR/*EST*/);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR/*EST*/);
		glTexImage2D(GL_TEXTURE_2D, 
					 0, img.type, 
					 img.width, img.height, 
					 0, img.type,
					 GL_UNSIGNED_BYTE,
					 img.imageData
					);
		printf("Loaded!\n");
	}
	delete img.imageData;
	return texture;
}

И не забудь сделать:

    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glEnable(GL_TEXTURE_2D);


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

> Гошпади, да тут потенциальных утечек памяти полно. Не используйте этот код.

На скорую руку писался, никто не просит его использовать, может человек не тот параметр в ОГЛную функцию передвавал, посмотрит и подправит свое, просто оно работает с альфа-каналом.

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

Тем не менее, я не мог не поорать (;

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