私はOpenGL(freeglutとglew)を使ってアプリケーションを書いています。C++ OpenGL glTexImage2Dアクセス違反
私はビットマップファイルフォーマットに関するいくつかの研究を行い、メインヘッダ用の構造体とDIBヘッダ(情報ヘッダ)用の構造体を書きました。
その後、私はローダーの作成を開始しました。 OpenGLにテクスチャを自動的にバインドします。
static unsigned int ReadInteger(FILE *fp)
{
int a, b, c, d;
// Integer is 4 bytes long.
a = getc(fp);
b = getc(fp);
c = getc(fp);
d = getc(fp);
// Convert the 4 bytes to an integer.
return ((unsigned int) a) + (((unsigned int) b) << 8) +
(((unsigned int) c) << 16) + (((unsigned int) d) << 24);
}
static unsigned int ReadShort(FILE *fp)
{
int a, b;
// Short is 2 bytes long.
a = getc(fp);
b = getc(fp);
// Convert the 2 bytes to a short (int16).
return ((unsigned int) a) + (((unsigned int) b) << 8);
}
GLuint LoadBMP(const char* filename)
{
FILE* file;
// Check if a file name was provided.
if (!filename)
return 0;
// Try to open file.
fopen_s(&file, filename, "rb");
// Return if the file could not be open.
if (!file)
{
cout << "Warning: Could not find texture '" << filename << "'." << endl;
return 0;
}
// Read signature.
unsigned char signature[2];
fread(&signature, 2, 1, file);
// Use signature to identify a valid bitmap.
if (signature[0] != BMPSignature[0] || signature[1] != BMPSignature[1])
{
fclose(file);
return 0;
}
// Read width and height.
unsigned long width, height;
fseek(file, 16, SEEK_CUR); // After the signature we have 16bytes until the width.
width = ReadInteger(file);
height = ReadInteger(file);
// Calculate data size (we'll only support 24bpp).
unsigned long dataSize;
dataSize = width * height * 3;
// Make sure planes is 1.
if (ReadShort(file) != 1)
{
cout << "Error: Could not load texture '" << filename << "' (planes is not 1)." << endl;
return 0;
}
// Make sure bpp is 24.
if (ReadShort(file) != 24)
{
cout << "Error: Could not load texture '" << filename << "' (bits per pixel is not 24)." << endl;
return 0;
}
// Move pointer to beggining of data. (after the bpp we have 24 bytes until the data)
fseek(file, 24, SEEK_CUR);
// Allocate memory and read the image data.
unsigned char* data = new unsigned char[dataSize];
if (!data)
{
fclose(file);
cout << "Warning: Could not allocate memory to store data of '" << filename << "'." << endl;
return 0;
}
fread(data, dataSize, 1, file);
if (data == NULL)
{
fclose(file);
cout << "Warning: Could no load data from '" << filename << "'." << endl;
return 0;
}
// Close the file.
fclose(file);
// Create the texture.
GLuint texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); //NEAREST);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, width, height, GL_BGR_EXT, GL_UNSIGNED_BYTE, data);
return texture;
}
私はペイントで開いた画像と比較して、コンソールにそれのデータを出力しているため、ビットマップのデータが正しく読み込まれていることを知っている:ここでは関数です。
ここでの問題は、この行です:
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, dibheader.width,
dibheader.height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
私は、この行がエラーでクラッシュしたアプリケーションを実行する時間のほとんど:
Unhandled exception at 0x008ffee9 in GunsGL.exe: 0xC0000005: Access violation reading location 0x00af7002.
これは、エラーが発生した場所の分解であります:
movzx ebx,byte ptr [esi+2]
他のローダーをダウンロードしたので、私のローダーでエラーは発生しません。 ダウンロードしたローダーはNeHeのthis oneでした。
編集:私はローダーを書き直し
(上記のコードは更新された)が、私はまだ同じライン上でクラッシュを取得します。行で
void __cdecl _lock (
int locknum
)
{
/*
* Create/open the lock, if necessary
*/
if (_locktable[locknum].lock == NULL) {
if (!_mtinitlocknum(locknum))
_amsg_exit(_RT_LOCK);
}
/*
* Enter the critical section.
*/
EnterCriticalSection(_locktable[locknum].lock);
}
:
EnterCriticalSection(_locktable[locknum].lock);
はまた、ここでのスクリーンショットは、その代わりにクラッシュした、時々私は(同じエラーメッセージは、私が正しくリコールされる)mlock.cにクラッシュを取得しますアプリケーションがクラッシュしない当時の1(テクスチャは右、明らかではありません): http://i.stack.imgur.com/4Mtso.jpg
EDIT2:
新しいコードでコードを更新しました。 (応答としてマークされた応答には、これが動作するために必要なものすべてが含まれているわけではありませんでしたが、重要でした)
そのメモリ位置は、初期化されていないポインタを示すものではないようです...私の次の推測は、OpenGLが 'data'の境界を越えて読み込もうとしていることです。正しいデータ量を指定していることを確認できますか? – kevintodisco
これはC++よりCのように見える – Pubby
@ktodiscoデータサイズは実際には正しいです。 – zeluisping