【发布时间】:2014-08-17 15:44:35
【问题描述】:
我正在使用 OpenGL 创建一个简单的 3D 游戏,但我真的不明白为什么会出现这个错误。我正在尝试加载一个数字集(一组文件,名为“1.tga”、“2.tga”等)以用作乐谱显示,但由于某种原因,如果有任何一个图像'尺寸不是 2 的幂,然后我得到错误:
“此应用程序以异常方式请求运行时终止它。请联系应用程序的支持团队以获取更多信息。”
更奇怪的是,它不将 128、64、32 等视为 2 的幂。我不明白的是,在程序中我已经加载了不是 2 次方的纹理(天空盒,即 3072 x 2304),而且效果很好。但是,出于某种原因,这不是。
我不确定提供我的代码是否会有所帮助,但这里是:
void CNumberSet::Load(char *NumberSetDirectory, bool BottomLeftAlign) {
std::string NSD;
m_BottomLeftAlign = BottomLeftAlign;
for (int i = 0; i < 11; i++) {
// Load texture for each digit
NSD = NumberSetDirectory;
if (NSD.at(NSD.length() - 1) == '\\' || NSD.at(NSD.length() - 1) == '/') NSD += (ToString(i) + ".tga");
else NSD += ("/" + ToString(i) + ".tga");
m_Textures[i].LoadDataFromFile((char *) NSD.c_str(), CTexture::TARGA);
m_Textures[i].SetTextureParameter(GL_TEXTURE_MIN_FILTER, GL_LINEAR);
m_Textures[i].SetTextureParameter(GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// Load and create mesh for each digit, and associate with texture
float Width = m_Textures[i].GetWidth();
float Height = m_Textures[i].GetHeight();
if (BottomLeftAlign) {
float Vertices[] = {
0.0f, Height, 0.0f, 0.0f, 1.0f,
0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
Width, Height, 0.0f, 1.0f, 1.0f,
Width, 0.0f, 0.0f, 1.0f, 0.0f
};
m_Meshes[i].LoadData(Vertices, sizeof(Vertices), GL_STATIC_DRAW);
} else {
float Vertices[] = {
-Width, Height, 0.0f, 0.0f, 1.0f,
-Width, 0.0f, 0.0f, 0.0f, 0.0f,
0.0f, Height, 0.0f, 1.0f, 1.0f,
0.0f, 0.0f, 0.0f, 1.0f, 0.0f
};
m_Meshes[i].LoadData(Vertices, sizeof(Vertices), GL_STATIC_DRAW);
}
m_Meshes[i].SetTexture(&m_Textures[i]);
m_Meshes[i].SetVertexAttribute(m_ShaderProgram, "Vertex", 3, GL_FLOAT, 5 * sizeof(float), (void *)(0 * sizeof(float)));
m_Meshes[i].SetVertexAttribute(m_ShaderProgram, "TexCoord", 2, GL_FLOAT, 5 * sizeof(float), (void *)(3 * sizeof(float)));
}
}
LoadDataFromFile函数负责加载每张图片,其来源在这里:
bool CTexture::LoadDataFromFile(char *Filename, short Type) {
std::ifstream File(Filename, std::ios::in | std::ios::binary);
switch (Type) {
case BMP24: {
char Header[54];
char *Data;
int Width, Height;
if (File.is_open()) {
File.read(Header, 54);
if (Header[0] != 'B' || Header[1] != 'M') {
MessageBox(NULL, "Not a valid BMP24 file!", "Error", MB_OK | MB_ICONERROR);
return false;
}
Width = *(int*) & Header[18];
Height = *(int*) & Header[22];
Data = new char [Width * Height * 3];
File.read(Data, Width * Height * 3);
File.close();
} else {
MessageBox(NULL, "Cannot open BMP24 file!", "Error", MB_OK | MB_ICONERROR);
return false;
}
glBindTexture(GL_TEXTURE_2D, m_ID);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, Width, Height, 0, GL_BGR_EXT, GL_UNSIGNED_BYTE, Data);
m_Width = Width;
m_Height = Height;
delete Data;
return true;
break; }
case TARGA: {
char Header[12];
char ImageInfo[6];
char *Data;
int Width, Height, BitDepth;
char UncompressedTGA[12] = { 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
char CompressedTGA[12] = { 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
if (File.is_open()) {
File.read(Header, 12);
File.read(ImageInfo, 6);
Width = ImageInfo[1] * 256 + ImageInfo[0];
Height = ImageInfo[3] * 256 + ImageInfo[2];
BitDepth = ImageInfo[4];
int TGASize = Width * Height * BitDepth / 8;
Data = new char[TGASize];
m_Width = Width;
m_Height = Height;
if (BitDepth != 24 && BitDepth != 32) {
MessageBox(NULL, "Only bit depths of 24 and 32 are supported!", "Error", MB_OK | MB_ICONERROR);
return false;
}
if (memcmp(Header, UncompressedTGA, 12) == 0) {
// Uncompressed
File.read(Data, TGASize);
} else if (memcmp(Header, CompressedTGA, 12) == 0) {
// Compressed
unsigned char ChunkHeader = 0;
unsigned char *ColourBuffer = new unsigned char[BitDepth / 8];
unsigned int PixelCount = Width * Height;
unsigned int CurrentPixel = 0;
unsigned int CurrentByte = 0;
while (CurrentPixel < PixelCount) {
File.read((char *) &ChunkHeader, 1);
if (ChunkHeader < 128) { // RAW chunk
ChunkHeader++;
for (int i = 0; i < ChunkHeader; i++) {
File.read((char *)ColourBuffer, BitDepth / 8);
Data[CurrentByte + 0] = ColourBuffer[0]; // Write 'B' byte
Data[CurrentByte + 1] = ColourBuffer[1]; // Write 'G' byte
Data[CurrentByte + 2] = ColourBuffer[2]; // Write 'R' byte
if (BitDepth == 32) Data[CurrentByte + 3] = ColourBuffer[3]; // Write 'A' byte (if needed)
CurrentByte += BitDepth / 8;
CurrentPixel++;
}
} else { // Run-length encoded chunk
ChunkHeader -= 127;
File.read((char *) ColourBuffer, BitDepth / 8);
for (int i = 0; i < ChunkHeader; i++) {
Data[CurrentByte + 0] = ColourBuffer[0]; // Write 'B' byte
Data[CurrentByte + 1] = ColourBuffer[1]; // Write 'G' byte
Data[CurrentByte + 2] = ColourBuffer[2]; // Write 'R' byte
if (BitDepth == 32) Data[CurrentByte + 3] = ColourBuffer[3]; // Write 'A' byte (if needed)
CurrentByte += BitDepth / 8;
CurrentPixel++;
}
}
}
delete ColourBuffer;
} else {
MessageBox(NULL, "Not a valid TARGA file!", "Error", MB_OK | MB_ICONERROR);
return false;
}
File.close();
} else {
MessageBox(NULL, "Cannot open TARGA file!", "Error", MB_OK | MB_ICONERROR);
return false;
}
glBindTexture(GL_TEXTURE_2D, m_ID);
glTexImage2D(GL_TEXTURE_2D, 0, BitDepth == 24 ? GL_RGB : GL_RGBA, Width, Height, 0, BitDepth == 24 ? GL_BGR_EXT : GL_BGRA_EXT, GL_UNSIGNED_BYTE, Data);
delete Data;
return true;
break; }
default:
MessageBox(NULL, "Image format not recognised!", "Error", MB_OK | MB_ICONERROR);
return false;
break;
}
}
【问题讨论】:
-
您收到的消息意味着您的应用程序做了一些非常糟糕的事情,例如除以 0 或访问
null对象。你能通过 Debugger 运行它,看看是哪一行出现了这个错误吗? -
从我几天前的尝试来看,是 glTexImage2D 行导致了问题。
标签: c++ opengl graphics 3d textures