在C ++ / OpenGL中加载tga / bmp文件 [英] Loading a tga/bmp file in C++/OpenGL
本文介绍了在C ++ / OpenGL中加载tga / bmp文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我正在尝试加载tga / bmp文件。这个工作正常,但最终结果如下所示:
我要加载的图片看起来像这样:
img src =http://i.stack.imgur.com/XMnH6.pngalt =enter image description here>
m使用:
GLuint纹理;
const char * filename =/ Users / Admin / Documents / Visual Studio 2013 / Projects / OpenGL / OpenGL / image.tga;
unsigned char * data;
data =(unsigned char *)malloc(128 * 128 * 3);
FILE * f;
fopen_s(& f,filename,rb);
fread(data,128 * 128 * 3,1,f);
glGenTextures(1,& texture);
glBindTexture(GL_TEXTURE_2D,texture);
glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,128,128,0,GL_RGB,GL_UNSIGNED_BYTE,data);
有人知道我做错了什么吗?
<$ c> $ c> #include< vector>
#include< fstream>
#ifdef __APPLE__
#include< OpenGL / gl.h>
#include< OpenGL / glu.h>
#endif
#ifdef _WIN32
#include< GL / gl.h>
#include< GL / glu.h>
#endif
class BMP
{
private:
std :: uint32_t width,height;
std :: uint16_t BitsPerPixel;
std :: vector< std :: uint8_t>像素;
public:
BMP(const char * FilePath);
std :: vector< std :: uint8_t> getPixels()const {return this-> Pixels;}
std :: uint32_t GetWidth()const {return this-> width;}
std :: uint32_t GetHeight > height;}
bool HasAlphaChannel(){return BitsPerPixel == 32;}
};
BMP :: BMP(const char * FilePath)
{
std :: fstream hFile(FilePath,std :: ios :: in | std :: ios :: binary );
if(!hFile.is_open())throw std :: invalid_argument(错误:找不到文件。
hFile.seekg(0,std :: ios :: end);
std :: size_t Length = hFile.tellg();
hFile.seekg(0,std :: ios :: beg);
std :: vector< std :: uint8_t> FileInfo(Length);
hFile.read(reinterpret_cast< char *>(FileInfo.data()),54);
if(FileInfo [0]!='B'&& FileInfo [1]!='M')
{
hFile.close();
throw std :: invalid_argument(Error:Invalid File Format。Bitmap Required。);
}
if(FileInfo [28]!= 24&& FileInfo [28]!= 32)
{
hFile.close();
throw std :: invalid_argument(错误:无效的文件格式。24或32位图像必需。
}
BitsPerPixel = FileInfo [28];
width = FileInfo [18] +(FileInfo [19]<< 8);
height = FileInfo [22] +(FileInfo [23]<< 8);
std :: uint32_t PixelsOffset = FileInfo [10] +(FileInfo [11]<< 8);
std :: uint32_t size =((width * BitsPerPixel + 31)/ 32)* 4 * height;
Pixels.resize(size);
hFile.seekg(PixelsOffset,std :: ios:beg);
hFile.read(reinterpret_cast< char *>(Pixels.data()),size);
hFile.close();
}
int main()
{
BMP info = BMP(C:/ Users /....../ Desktop / SomeBmp.bmp );
GLuint texture = 0;
glGenTextures(1,& texture);
glBindTexture(GL_TEXTURE_2D,texture);
glTexImage2D(GL_TEXTURE_2D,0,info.HasAlphaChannel()?GL_RGBA:GL_RGB,info.GetWidth(),info.GetWidth(),0,info.HasAlphaChannel()?GL_BGRA:GL_BGR,GL_UNSIGNED_BYTE,info.GetPixels )。数据());
}
TGA:
#include< vector>
#include< fstream>
#ifdef __APPLE__
#include< OpenGL / gl.h>
#include< OpenGL / glu.h>
#endif
#ifdef _WIN32
#include< GL / gl.h>
#include< GL / glu.h>
#endif
typedef union PixelInfo
{
std :: uint32_t Color;
struct
{
std :: uint8_t B,G,R,A;
};
} * PPixelInfo;
class Tga
{
private:
std :: vector< std :: uint8_t>像素;
bool ImageCompressed;
std :: uint32_t width,height,size,BitsPerPixel;
public:
Tga(const char * FilePath);
std :: vector< std :: uint8_t> getPixels(){return this-> Pixels;}
std :: uint32_t GetWidth()const {return this-> width;}
std :: uint32_t GetHeight()const {return this-> ; height;}
bool HasAlphaChannel(){return BitsPerPixel == 32;}
};
Tga :: Tga(const char * FilePath)
{
std :: fstream hFile(FilePath,std :: ios :: in | std :: ios :: binary );
if(!hFile.is_open()){throw std :: invalid_argument(File Not Found。);}
std :: uint8_t Header [18] = {0}
std :: vector< std :: uint8_t> ImageData;
static std :: uint8_t DeCompressed [12] = {0x0,0x0,0x2,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0}
static std :: uint8_t IsCompressed [12] = {0x0,0x0,0xA,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0}
hFile.read(reinterpret_cast< char *>(& Header),sizeof(Header));
if(!std :: memcmp(DeCompressed,& Header,sizeof(DeCompressed)))
{
BitsPerPixel = Header [16]
width = Header [13] * 256 + Header [12];
height = Header [15] * 256 + Header [14];
size =((width * BitsPerPixel + 31)/ 32)* 4 * height;
if((BitsPerPixel!= 24)&&(BitsPerPixel!= 32))
{
hFile.close();
throw std :: invalid_argument(Invalid File Format。Required:24 or 32 Bit Image。);
}
ImageData.resize(size);
ImageCompressed = false;
hFile.read(reinterpret_cast< char *>(ImageData.data()),size);
}
else if(!std :: memcmp(IsCompressed,& Header,sizeof(IsCompressed)))
{
BitsPerPixel = Header [16]
width = Header [13] * 256 + Header [12];
height = Header [15] * 256 + Header [14];
size =((width * BitsPerPixel + 31)/ 32)* 4 * height;
if((BitsPerPixel!= 24)&&(BitsPerPixel!= 32))
{
hFile.close();
throw std :: invalid_argument(Invalid File Format。Required:24 or 32 Bit Image。);
}
PixelInfo Pixel = {0};
int CurrentByte = 0;
std :: size_t CurrentPixel = 0;
ImageCompressed = true;
std :: uint8_t ChunkHeader = {0};
int BytesPerPixel =(BitsPerPixel / 8);
ImageData.resize(width * height * sizeof(PixelInfo));
do
{
hFile.read(reinterpret_cast< char *>(& ChunkHeader),sizeof(ChunkHeader));
if(ChunkHeader <128)
{
++ ChunkHeader;
for(int I = 0; I {
hFile.read(reinterpret_cast< char *>(& Pixel),BytesPerPixel );
ImageData [CurrentByte ++] = Pixel.B;
ImageData [CurrentByte ++] = Pixel.G;
ImageData [CurrentByte ++] = Pixel.R;
if(BitsPerPixel> 24)ImageData [CurrentByte ++] = Pixel.A;
}
}
else
{
ChunkHeader - = 127;
hFile.read(reinterpret_cast< char *>(& Pixel),BytesPerPixel);
for(int I = 0; I {
ImageData [CurrentByte ++] = Pixel.B;
ImageData [CurrentByte ++] = Pixel.G;
ImageData [CurrentByte ++] = Pixel.R;
if(BitsPerPixel> 24)ImageData [CurrentByte ++] = Pixel.A;
}
}
} while(CurrentPixel<(width * height));
}
else
{
hFile.close();
throw std :: invalid_argument(Invalid File Format。Required:24或32 Bit TGA File。);
}
hFile.close();
this-> Pixels = ImageData;
}
int main()
{
Tga info = Tga(C:/ Users /...../ Desktop / SomeTGA .tga);
GLuint texture = 0;
glGenTextures(1,& texture);
glBindTexture(GL_TEXTURE_2D,texture);
glTexImage2D(GL_TEXTURE_2D,0,info.HasAlphaChannel()?GL_RGBA:GL_RGB,info.GetWidth(),info.GetWidth(),0,info.HasAlphaChannel()?GL_RGBA:GL_RGB,GL_UNSIGNED_BYTE,info.GetPixels )。数据());
}
I'm trying to load a tga/bmp file. This works fine, but the end result looks like this:
The image I'm trying to load looks like this:
Some of the code I'm using:
GLuint texture;
const char* filename = "/Users/Admin/Documents/Visual Studio 2013/Projects/OpenGL/OpenGL/image.tga";
unsigned char* data;
data = (unsigned char *) malloc(128 * 128 * 3);
FILE* f;
fopen_s(&f, filename, "rb");
fread(data, 128 * 128 * 3, 1, f);
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 128, 128, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
Does anybody have an idea what I'm doing wrong?
解决方案
You can load a bitmap and a tga file using these..
#include <vector>
#include <fstream>
#ifdef __APPLE__
#include <OpenGL/gl.h>
#include <OpenGL/glu.h>
#endif
#ifdef _WIN32
#include <GL/gl.h>
#include <GL/glu.h>
#endif
class BMP
{
private:
std::uint32_t width, height;
std::uint16_t BitsPerPixel;
std::vector<std::uint8_t> Pixels;
public:
BMP(const char* FilePath);
std::vector<std::uint8_t> GetPixels() const {return this->Pixels;}
std::uint32_t GetWidth() const {return this->width;}
std::uint32_t GetHeight() const {return this->height;}
bool HasAlphaChannel() {return BitsPerPixel == 32;}
};
BMP::BMP(const char* FilePath)
{
std::fstream hFile(FilePath, std::ios::in | std::ios::binary);
if (!hFile.is_open()) throw std::invalid_argument("Error: File Not Found.");
hFile.seekg(0, std::ios::end);
std::size_t Length = hFile.tellg();
hFile.seekg(0, std::ios::beg);
std::vector<std::uint8_t> FileInfo(Length);
hFile.read(reinterpret_cast<char*>(FileInfo.data()), 54);
if(FileInfo[0] != 'B' && FileInfo[1] != 'M')
{
hFile.close();
throw std::invalid_argument("Error: Invalid File Format. Bitmap Required.");
}
if (FileInfo[28] != 24 && FileInfo[28] != 32)
{
hFile.close();
throw std::invalid_argument("Error: Invalid File Format. 24 or 32 bit Image Required.");
}
BitsPerPixel = FileInfo[28];
width = FileInfo[18] + (FileInfo[19] << 8);
height = FileInfo[22] + (FileInfo[23] << 8);
std::uint32_t PixelsOffset = FileInfo[10] + (FileInfo[11] << 8);
std::uint32_t size = ((width * BitsPerPixel + 31) / 32) * 4 * height;
Pixels.resize(size);
hFile.seekg (PixelsOffset, std::ios::beg);
hFile.read(reinterpret_cast<char*>(Pixels.data()), size);
hFile.close();
}
int main()
{
BMP info = BMP("C:/Users/....../Desktop/SomeBmp.bmp");
GLuint texture = 0;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, info.HasAlphaChannel() ? GL_RGBA : GL_RGB, info.GetWidth(), info.GetWidth(), 0, info.HasAlphaChannel() ? GL_BGRA : GL_BGR, GL_UNSIGNED_BYTE, info.GetPixels().data());
}
TGA's:
#include <vector>
#include <fstream>
#ifdef __APPLE__
#include <OpenGL/gl.h>
#include <OpenGL/glu.h>
#endif
#ifdef _WIN32
#include <GL/gl.h>
#include <GL/glu.h>
#endif
typedef union PixelInfo
{
std::uint32_t Colour;
struct
{
std::uint8_t B, G, R, A;
};
} *PPixelInfo;
class Tga
{
private:
std::vector<std::uint8_t> Pixels;
bool ImageCompressed;
std::uint32_t width, height, size, BitsPerPixel;
public:
Tga(const char* FilePath);
std::vector<std::uint8_t> GetPixels() {return this->Pixels;}
std::uint32_t GetWidth() const {return this->width;}
std::uint32_t GetHeight() const {return this->height;}
bool HasAlphaChannel() {return BitsPerPixel == 32;}
};
Tga::Tga(const char* FilePath)
{
std::fstream hFile(FilePath, std::ios::in | std::ios::binary);
if (!hFile.is_open()){throw std::invalid_argument("File Not Found.");}
std::uint8_t Header[18] = {0};
std::vector<std::uint8_t> ImageData;
static std::uint8_t DeCompressed[12] = {0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
static std::uint8_t IsCompressed[12] = {0x0, 0x0, 0xA, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
hFile.read(reinterpret_cast<char*>(&Header), sizeof(Header));
if (!std::memcmp(DeCompressed, &Header, sizeof(DeCompressed)))
{
BitsPerPixel = Header[16];
width = Header[13] * 256 + Header[12];
height = Header[15] * 256 + Header[14];
size = ((width * BitsPerPixel + 31) / 32) * 4 * height;
if ((BitsPerPixel != 24) && (BitsPerPixel != 32))
{
hFile.close();
throw std::invalid_argument("Invalid File Format. Required: 24 or 32 Bit Image.");
}
ImageData.resize(size);
ImageCompressed = false;
hFile.read(reinterpret_cast<char*>(ImageData.data()), size);
}
else if (!std::memcmp(IsCompressed, &Header, sizeof(IsCompressed)))
{
BitsPerPixel = Header[16];
width = Header[13] * 256 + Header[12];
height = Header[15] * 256 + Header[14];
size = ((width * BitsPerPixel + 31) / 32) * 4 * height;
if ((BitsPerPixel != 24) && (BitsPerPixel != 32))
{
hFile.close();
throw std::invalid_argument("Invalid File Format. Required: 24 or 32 Bit Image.");
}
PixelInfo Pixel = {0};
int CurrentByte = 0;
std::size_t CurrentPixel = 0;
ImageCompressed = true;
std::uint8_t ChunkHeader = {0};
int BytesPerPixel = (BitsPerPixel / 8);
ImageData.resize(width * height * sizeof(PixelInfo));
do
{
hFile.read(reinterpret_cast<char*>(&ChunkHeader), sizeof(ChunkHeader));
if(ChunkHeader < 128)
{
++ChunkHeader;
for(int I = 0; I < ChunkHeader; ++I, ++CurrentPixel)
{
hFile.read(reinterpret_cast<char*>(&Pixel), BytesPerPixel);
ImageData[CurrentByte++] = Pixel.B;
ImageData[CurrentByte++] = Pixel.G;
ImageData[CurrentByte++] = Pixel.R;
if (BitsPerPixel > 24) ImageData[CurrentByte++] = Pixel.A;
}
}
else
{
ChunkHeader -= 127;
hFile.read(reinterpret_cast<char*>(&Pixel), BytesPerPixel);
for(int I = 0; I < ChunkHeader; ++I, ++CurrentPixel)
{
ImageData[CurrentByte++] = Pixel.B;
ImageData[CurrentByte++] = Pixel.G;
ImageData[CurrentByte++] = Pixel.R;
if (BitsPerPixel > 24) ImageData[CurrentByte++] = Pixel.A;
}
}
} while(CurrentPixel < (width * height));
}
else
{
hFile.close();
throw std::invalid_argument("Invalid File Format. Required: 24 or 32 Bit TGA File.");
}
hFile.close();
this->Pixels = ImageData;
}
int main()
{
Tga info = Tga("C:/Users/...../Desktop/SomeTGA.tga");
GLuint texture = 0;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, info.HasAlphaChannel() ? GL_RGBA : GL_RGB, info.GetWidth(), info.GetWidth(), 0, info.HasAlphaChannel() ? GL_RGBA : GL_RGB, GL_UNSIGNED_BYTE, info.GetPixels().data());
}
这篇关于在C ++ / OpenGL中加载tga / bmp文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文