У меня работает одна текстура, но я не могу понять, как переключаться между 2 или как на самом деле работает glBindTexture.
Я скопировал это откуда-то, и это работает, и я верю, что понимаю большинство из них. Проблема в том, что я могу раскомментировать glBindTexture(GL_TEXTURE_2D, texture[0].texID);
и это работает. Что я не понимаю. Этот код не должен быть проблемой, я думаю, что я упускаю что-то простое.
bool LoadTGA(TextureImage *texture, char *filename) // Loads A TGA File Into Memory
{
GLubyte TGAheader[12]={0,0,2,0,0,0,0,0,0,0,0,0}; // Uncompressed TGA Header
GLubyte TGAcompare[12]; // Used To Compare TGA Header
GLubyte header[6]; // First 6 Useful Bytes From The Header
GLuint bytesPerPixel; // Holds Number Of Bytes Per Pixel Used In The TGA File
GLuint imageSize; // Used To Store The Image Size When Setting Aside Ram
GLuint temp; // Temporary Variable
GLuint type=GL_RGBA; // Set The Default GL Mode To RBGA (32 BPP)
system("cd");
FILE *file = fopen(filename, "r"); // Open The TGA File
if( file==NULL || // Does File Even Exist?
fread(TGAcompare,1,sizeof(TGAcompare),file)!=sizeof(TGAcompare) || // Are There 12 Bytes To Read?
memcmp(TGAheader,TGAcompare,sizeof(TGAheader))!=0 || // Does The Header Match What We Want?
fread(header,1,sizeof(header),file)!=sizeof(header)) // If So Read Next 6 Header Bytes
{
if (file == NULL) // Did The File Even Exist? *Added Jim Strong*
{
perror("Error");
return false; // Return False
}
else
{
fclose(file); // If Anything Failed, Close The File
perror("Error");
return false; // Return False
}
}
texture->width = header[1] * 256 + header[0]; // Determine The TGA Width (highbyte*256+lowbyte)
texture->height = header[3] * 256 + header[2]; // Determine The TGA Height (highbyte*256+lowbyte)
if( texture->width <=0 || // Is The Width Less Than Or Equal To Zero
texture->height <=0 || // Is The Height Less Than Or Equal To Zero
(header[4]!=24 && header[4]!=32)) // Is The TGA 24 or 32 Bit?
{
fclose(file); // If Anything Failed, Close The File
return false; // Return False
}
texture->bpp = header[4]; // Grab The TGA's Bits Per Pixel (24 or 32)
bytesPerPixel = texture->bpp/8; // Divide By 8 To Get The Bytes Per Pixel
imageSize = texture->width*texture->height*bytesPerPixel; // Calculate The Memory Required For The TGA Data
texture->imageData=(GLubyte *)malloc(imageSize); // Reserve Memory To Hold The TGA Data
if( texture->imageData==NULL || // Does The Storage Memory Exist?
fread(texture->imageData, 1, imageSize, file)!=imageSize) // Does The Image Size Match The Memory Reserved?
{
if(texture->imageData!=NULL) // Was Image Data Loaded
free(texture->imageData); // If So, Release The Image Data
fclose(file); // Close The File
return false; // Return False
}
for(GLuint i=0; i<int(imageSize); i+=bytesPerPixel) // Loop Through The Image Data
{ // Swaps The 1st And 3rd Bytes ('R'ed and 'B'lue)
temp=texture->imageData[i]; // Temporarily Store The Value At Image Data 'i'
texture->imageData[i] = texture->imageData[i + 2]; // Set The 1st Byte To The Value Of The 3rd Byte
texture->imageData[i + 2] = temp; // Set The 3rd Byte To The Value In 'temp' (1st Byte Value)
}
fclose (file); // Close The File
// Build A Texture From The Data
glGenTextures(1, &texture[0].texID); // Generate OpenGL texture IDs
//glBindTexture(GL_TEXTURE_2D, texture[0].texID); // Bind Our Texture
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // Linear Filtered
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // Linear Filtered
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
if (texture[0].bpp==24) // Was The TGA 24 Bits
{
type=GL_RGB; // If So Set The 'type' To GL_RGB
}
glTexImage2D(GL_TEXTURE_2D, 0, type, texture[0].width, texture[0].height, 0, type, GL_UNSIGNED_BYTE, texture[0].imageData);
return true;
Теперь, когда я рисую, у меня есть это:
glEnable(GL_TEXTURE_2D);
//glBindTexture(GL_TEXTURE_2D, texturesList[0].texID);
glColor4f(1, 1, 1, 1);
glBegin(GL_POLYGON);
glTexCoord2f(0.0f, 0.0f);
glVertex4f(-50, 0, 50, 1);
glTexCoord2f(50.0f, 0.0f);
glVertex4f(-50, 0, -50, 1);
glTexCoord2f(50.0f, 50.0f);
glVertex4f(50, 0, -50, 1);
glTexCoord2f(0.0f, 50.0f);
glVertex4f(50, 0, 50, 1);
glEnd();
glDisable(GL_TEXTURE_2D);
И это в начале программы:
LoadTGA(&texturesList[0], "\snow.tga");
LoadTGA(&texturesList[1], "\snow2.tga");
Так что после загрузки их texturesList содержит 2 текстуры с идентификаторами 1 и 2.
Так я не звоню glBindTexture(GL_TEXTURE_2D, texturesList[0].texID);
прежде чем рисовать, чтобы выбрать правильную текстуру? Потому что я должен сказать glTexCoord2f над чем работать?
Это работает отлично, если я никогда не вызываю glBind в моем дро, но если я делаю, ничего не появляется. Что меня больше смущает, так это то, что glBind не нужно вызывать, чтобы он работал.
Но будет показана последняя созданная мной текстура (snow2.tga).
Если я смогу что-нибудь прояснить, дай мне знать.
Так я не звоню glBindTexture (GL_TEXTURE_2D, texturesList [0] .texID); прежде чем рисовать, чтобы выбрать правильную текстуру? Потому что я должен сказать glTexCoord2f над чем работать?
glTexCoord2f (...)
работает на уровне каждой вершины. Это не зависит от того, какую текстуру вы загрузили, в этом и заключается весь смысл. Вы можете нанести на карту любую текстуру, которую хотите, просто изменив, какая текстура будет привязана при рисовании.
Это отлично работает, если я никогда не позвоню glBind в моем розыгрыше, но если я делаю, ничего не появляется. Что меня больше смущает, так это то, что glBind не нужно вызывать его для работы.
LoadTGA (...)
потому что «генерировать» одно имя недостаточно.Все это glGenTextures (...)
Он возвращает одно или несколько неиспользуемых имен из списка имен, имеющихся в OpenGL для текстур, и резервирует их, чтобы при последующем вызове не выдавалось одно и то же имя.
Это не фактически создавая текстуру, возвращаемое имя не становится текстурой, пока вы не свяжете ее. До этого времени название просто в зарезервированный государство. Такие команды как glTexParameterf (...)
а также glTexImage2D (...)
работать на В настоящее время связанная текстура, поэтому в дополнение к генерации текстуры вы должны также связать ее перед выполнением этих вызовов.
Сделай все возможное, чтобы избавиться от своего system ("cd");
линия. Есть гораздо лучшие способы изменить рабочий каталог.
SetCurrentDirectory (...)
(Windows)chdir (...)
(Linux / OS X / BSD / POSIX)Не используйте имя файла «\ Snow.tga» как строковый литерал, потому что компилятор C может видеть «\» и интерпретировать все, что последует за ним, как часть последовательности побега. Рассматривать «\\ snow.tga» вместо или «/Snow.tga» (да, это даже работает на Windows — «\» ужасный символ для использования в качестве разделителя пути).
«\ S» на самом деле не распознана escape-последовательность компиляторами C, а использует «\» Чтобы начать свой путь, нужно играть с огнем, потому что есть несколько зарезервированных персонажей, где это будет иметь значение. «\ Fire.tga», например, на самом деле сокращение для {0x0c} «ire.tga». Компилятор заменит ваш строковый литерал этой последовательностью байтов и позволит вам почесать голову, пытаясь выяснить, что пошло не так.
Других решений пока нет …