Я пишу приложение с использованием OpenGL (freeglut и glew).C++ OpenGL glTexImage2D Нарушение прав доступа
Мне также нужны текстуры, поэтому я провел некоторое исследование формата файла битмапа и написал структуру для основного заголовка, а другую для заголовка DIB (заголовок info).
Затем я начал писать загрузчик. Он автоматически связывает текстуру с 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]
Это не ошибка с моим загрузчиком, потому что я загрузил другие загрузчики. Загруженный загрузчик, который я использовал, был this one от NeHe.
EDIT: (КОД ОБНОВЛЕНО ВЫШЕ)
я переписал загрузчик, но я все еще получаю аварию на одной и той же линии. Вместо этого аварии, иногда я получаю аварии на mlock.c (то же самое сообщение об ошибке я правильно помню):
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);
Кроме того, здесь есть снимок экрана один из тех случаев, приложения не сломается (текстура, очевидно, не так): http://i.stack.imgur.com/4Mtso.jpg
Edit2:
Обновленный код с новым рабочим. (Ответ помечается как ответ не содержит все, что нужно для этого, чтобы работать, но это крайне важно)
Эта ячейка памяти, похоже, не указана неинициализированным указателем ... Мое следующее предположение заключалось в том, что OpenGL пытается читать за пределами «данных». Можете ли вы проверить, что вы указали правильный объем данных для чтения? – kevintodisco
Это больше похоже на C, чем на C++ – Pubby
@ktodisco. Размер данных на самом деле правильный. – zeluisping