GLuint createTexture(const char* filename, int width = 128, int height = 128)
{
GLuint texture;
char bitmap[width][height][3];
FILE* fp = fopen(filename, "rb");
assert(fp);
assert(fread(bitmap, 3*sizeof(char), width*height, fp) == width*height);
fclose(fp);
glGenTextures(1, &texture);
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, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, bitmap);
glBindTexture( GL_TEXTURE_2D,0);
return texture;
}
Привет люди, я хотел бы знать, как работает приведенный выше код. Предположительно, это код, который можно использовать для текстурирования твердых объектов в OpenGL (например: glutSolidSphere
). Может кто-нибудь объяснить мне, как работает вышеуказанная кодировка?
Вы как бы спрашиваете «Как работает OpenGL», и это зависит от того, какую версию вы используете. Я бы посоветовал: http://www.opengl-tutorial.org/beginners-tutorials
Или, что еще лучше, прочитайте «Красную книгу» (8-е издание, посвященное OpenGL 4.3)
GLuint createTexture(const char* filename, int width=128, int height=128)
{
GLuint texture;
Используйте массив переменных C99 для выделения ширины * высоты * 3 байта памяти в стеке. Если стека осталось недостаточно, программа вылетает с переполнением стека.
char bitmap[width][height][3];
Попробуйте открыть файл, чтобы получить текстуру. Файл должен быть необработанным массивом данных без заголовка, состоящим из 8 бит на канал RGB-данных.
FILE* fp=fopen(filename, "rb");
Завершите работу программы, если открыть файл не удалось. Технически использование assert для этой цели является ошибкой программирования, потому что a) assert ничего не делает в сборках релиза и b) это легко исправить после ошибки. Функция должна просто вернуть 0, если файл не может быть открыт.
assert(fp);
Считайте ширину * высоту кусков 3 байта. sizeof(char)
указывает, что автор этого понятия не имел о C, потому что стандарт C определяет sizeof(char) == 1
так что нет смысла делать это умножение.
Если не ожидаемый объем данных может быть прочитан, сбой программы, если в режиме отладки. В случае ошибки и сборки релиза делайте странные вещи.
assert(fread(bitmap, 3*sizeof(char), width*height, fp) == width*height);
Закройте файл.
fclose(fp);
Выделите дескриптор объекта текстуры OpenGL.
glGenTextures(1, &texture);
Свяжите дескриптор текстуры так, чтобы последующие операции OpenGL, влияющие на текстуры, работали с данным объектом.
glBindTexture(GL_TEXTURE_2D, texture);
Установите фильтры увеличения и минимизации текстуры. Используйте линейный, так что уровни MIPMAP не требуются.
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
Скопируйте данные в текстуру OpenGL. Так как при этом используется вновь выделенный дескриптор объекта текстуры, текстура также инициализируется этим.
Здесь пропущено много важных шагов. а именно glPixelStorei должен использоваться для подготовки OpenGL для чтения данных из массива. Выравнивание линий, шагов и так далее.
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE,bitmap);
Открепите текстуру объекта.
glBindTexture( GL_TEXTURE_2D,0);
Вернуть дескриптор объекта текстуры.
return texture;
}
Основные проблемы с этим кодом: нет ошибок OpenGL и не происходит сбой программы в отладочных сборках. В сборках релиза ошибки файловых операций не обнаруживаются и не обрабатываются.
НЕ ИСПОЛЬЗУЙТЕ ЭТОТ КОД!