OpenGL中多个纹理的问题
Posted
技术标签:
【中文标题】OpenGL中多个纹理的问题【英文标题】:Problems with multiple textures in OpenGL 【发布时间】:2013-03-03 11:21:58 【问题描述】:我正在尝试编写一个用于将对象加载到我的程序中的类/问题是 OpenGL 仅加载所有对象的最后一个纹理。
代码如下:
game.cpp 类:
object = new Object("table.obj", "wood.bmp",0); // a new object - obj file, texture and
object1 = new Object("aa.obj", "cloth.bmp",1); // texture number
object->draw();
object1->draw();
对象类:
AUX_RGBImageRec *texture;
Object::Object(char* filename, char* texname, int num)
tex_num = num;
is_loaded = false;
.... some vertex stuff here
texture = auxDIBImageLoadA(texname);
void Object::draw()
if(!is_loaded)
loadTexture();
is_loaded = true;
... vertex stuff again
void Object::loadTexture()
GLuint *tex = new GLuint[10];
unsigned int names[10];
glGenTextures(1, tex);
glBindTexture(GL_TEXTURE_2D, tex[tex_num]);
cout << tex_num << endl;
// glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexImage2D(GL_TEXTURE_2D, 0, 3,
texture->sizeX,
texture->sizeY,
0, GL_RGB, GL_UNSIGNED_BYTE,
texture->data);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
// free memory
delete tex;
cout << tex_num << endl;
【问题讨论】:
请停止使用 AUX 加载您的图像。如果您正在使用使用 AUX 的教程,请停止使用该教程并find better ones. 【参考方案1】:为什么要动态分配纹理 ID 变量?为什么在需要的时候在loadTexture
的末尾删除它,以便在绘制时实际参考纹理? OpenGL 不会神奇地将纹理与几何本身关联起来。
以下变化:
- Object::Object(char* filename, char* texname, int num)
+ Object::Object(char* filename, char* texfilename)
- tex_num = num;
is_loaded = false;
.... some vertex stuff here
- texture = auxDIBImageLoadA(texname);
+ loadTexture(texfilename);
class Object
/*...*/
+ GLuint texID;
void Object::draw()
-if(!is_loaded)
- loadTexture();
- is_loaded = true;
-
+ glBindTexure(GL_TEXTURE_2D, texID);
+ draw_geometry();
- void Object::loadTexture()
+ void Object::loadTexture(char const * const texfilename)
- GLuint *tex = new GLuint[10];
- unsigned int names[10];
- glGenTextures(1, tex);
- glBindTexture(GL_TEXTURE_2D, tex[tex_num]);
- cout << tex_num << endl;
+ glGenTexture(1, &texID);
+ glBindTexture(GL_TEXTURE_2D, texID);
+ cout << texID << endl;
+ // Image is a yet to implement class offering image loading
+ // in a RAII fashion.
+ Image img = Image::fromFile(texfilename);
- // glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
- glTexImage2D(GL_TEXTURE_2D, 0, 3,
- texture->sizeX,
- texture->sizeY,
- 0, GL_RGB, GL_UNSIGNED_BYTE,
- texture->data);
+ glPixelStorei(GL_UNPACK_ALIGNMENT, img.alignment());
+ glTexImage2D(GL_TEXTURE_2D, 0,
+ img.glinternalformat(), // don't use a channel count here!
+ img.width(),
+ img.height(),
+ 0,
+ img.glformat(),
+ img.gltype(),
+ img.data() );
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- // free memory
- delete tex;
- cout << tex_num << endl;
+ cout << texID << endl;
【讨论】:
非常感谢您的回答。但是我仍然需要在绘图函数中调用 if(!is_loaded) .. block 一次,没有这个纹理就不会显示。 @DarkSun:那么您可能在创建和激活 OpenGL 上下文之前创建“对象”实例。在这种情况下,在显示功能中按需加载资源是一种可能的解决方案。【参考方案2】:现在您的第一个 draw() 调用加载了您的纹理,您只需在每次绘制之前调用 glBindTexture(GL_TEXTURE_2D, your_generated_buffer)。
void Object::draw()
if(!is_loaded)
loadTexture();
is_loaded = true;
glBindTexture(GL_TEXTURE_2D, this->texture_buffer);
// Your vertex things..
如果 this->texture_buffer 代表您生成的纹理缓冲区,例如,顺便说一句,您正在做的事情很奇怪,您正在分配一个 GLuint* 数组?我宁愿向你推荐这个:
void Object::loadTexture()
glGenTextures(1, &this->texture_buffer);
glBindTexture(GL_TEXTURE_2D, this->texture_buffer);
glTexImage2D(GL_TEXTURE_2D, 0, 3,
texture->sizeX,
texture->sizeY,
0, GL_RGB, GL_UNSIGNED_BYTE,
texture->data);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
希望这会有所帮助:)
PS:如果你想知道为什么只应用了最后一个纹理,那是因为 OpenGL 的工作方式是,他画你想让他画的东西,这要归功于当前激活的纹理、灯光……以及你最后一次调用 object1->draw(),调用最后一个 loadtexture(),它通过调用 glBindTexture() 激活你最后一个纹理。
【讨论】:
以上是关于OpenGL中多个纹理的问题的主要内容,如果未能解决你的问题,请参考以下文章