无法渲染四维纹理

问题描述:

我想用C++编写一个简单的游戏,使用OpenGL进行图形编程。在我的游戏中,我有作为白色方块呈现在屏幕上的对象。我希望能够将图像作为纹理绑定到这些对象,以便我可以在屏幕上呈现图像而不是白色方块。对图像的格式没有限制,但我一直在使用.png或.bmp进行测试。无法渲染四维纹理

我的一个对象类Character.h存储名为_texture的GLuint *成员变量和名为_data(分别作为图像句柄和像素数据)的无符号char *成员变量。内Character.h是这个函数意味着将图像结合作为纹理的字符对象:

void loadTexture(const char* fileName) 
    { 
     /* read pixel data */ 
     FILE* file; 
     file = fopen(fileName, "rb"); 
     if (file == NULL) {cout << "ERROR: Image file not found!" << endl;} 
     _data = (unsigned char*)malloc(_dimension * _dimension * 3); 
     fread(_data, _dimension * _dimension * 3, 1, file); 
     fclose(file); 
     /* bind texture */ 
     glGenTextures(1, &_texture); // _texture is a member variable of type GLuint 
     glBindTexture(GL_TEXTURE_2D, _texture); 
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, _dimension, _dimension, 0, GL_RGB, GL_UNSIGNED_BYTE, _data); // _dimension = 64.0f. 
    } 

一旦图像被绑定,我然后尝试使与该功能角色对象(这是一个静态函数在一个单独的类中找到):

static void drawTexturedRectangle(float x, float y, float w, float h, GLuint texture, unsigned char* data) 
    { 
     /* fractions are calculated to determine the position onscreen that the object is drawn at */ 
     float xFraction = (x/GlobalConstants::SCREEN_WIDTH) * 2; 
     float yFraction = (y/GlobalConstants::SCREEN_HEIGHT) * 2; 
     float wFraction = (w/GlobalConstants::SCREEN_WIDTH) * 2; 
     float hFraction = (h/GlobalConstants::SCREEN_HEIGHT) * 2; 
     glEnable(GL_TEXTURE_2D); 
     glClear(GL_COLOR_BUFFER_BIT); 
     glBindTexture(GL_TEXTURE_2D, texture); 
     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, data); 
     glPushMatrix(); 
     glEnable(GL_BLEND); 
     glBegin(GL_QUADS); 
     glTexCoord2f(0.0f, 0.0f); glVertex2f(xFraction, yFraction); // bottom left corner 
     glTexCoord2f(0.0f, 1.0f); glVertex2f(xFraction, yFraction + hFraction); // top left corner 
     glTexCoord2f(1.0f, 1.0f); glVertex2f(xFraction + wFraction, yFraction + hFraction); // top right corner 
     glTexCoord2f(1.0f, 0.0f); glVertex2f(xFraction + wFraction, yFraction); // bottom right corner 
     glEnd(); 
     glDisable(GL_BLEND); 
     glPopMatrix(); 
    } 

不管我有多么混乱围绕这个问题,我似乎无法让我的程序做比呈现纯白色的广场上也没有质感其他任何东西。我已经检查过以确保变量文件,_texture,_dimension和_data都包含值。任何人都可以发现我可能做错了什么?

+0

我不认为这是你的问题的原因,但你不应该叫'glTexImage2D'要绘制纹理每一次 - 你怎么称呼它一次,加载纹理时。之后,您可以丢弃客户端内存中的数据,因为您已将其交给OpenGL,后者将对其进行管理,并且您只需再次绑定纹理即可告知OpenGL您想使用它。 – orost

+0

我不知道其他代码,但在调用loadTexture()函数之前,请确保您有一个'glEnable(GL_TEXTURE_2D);'调用。 – aslg

我不认为你可以只输入一个原始文件到glTexImage2D,除非你存储纹理文件的格式(你可能不会)。 glTexImage2D需要一个巨大的数组字节(代表纹理颜色),但文件格式通常不会像这样保存图像。即使bmp也有一些标题信息。

使用像Devil或SOIL的第三方图像加载器库来加载您的纹理!这些库可以将最常见的图像文件格式(png,jpg,tga,...)转换为可以输入到OpenGL的字节流!

附注: 调用glTexImage2D(...,data)后,数据内容被复制到GPU内存(VRAM)中。从这一点开始,你只需要使用它的id来绑定纹理,因为它已经在VRAM中了。在每个帧中调用glTexImage2D()会将每帧中的整个纹理重新上传到vram中,从而导致较大的性能损失。

+0

非常感谢agnu17!我用它来使用SOIL。 loadTexture方法简单地变为:_texture = SOIL_load_OGL_texture(fileName,SOIL_LOAD_AUTO,SOIL_CREATE_NEW_ID,SOIL_FLAG_INVERT_Y);我读过这可能只适用于8位.png出于任何原因。 – tomdunkle0