我正在尝试使用OpenGL为C ++编写一个简单的C ++游戏。在我的游戏中,我将对象在屏幕上呈现为白色方块。我希望能够将图像作为纹理绑定到这些对象,这样我就可以在屏幕上渲染图像而不是白色正方形。虽然我一直在使用.png或.bmp进行测试,但对图像的格式没有限制。
我的一个对象类Character.h存储一个名为_texture的GLuint *成员变量和一个名为_data的无符号char *成员变量(分别作为图像句柄和像素数据)。在Character.h中,此函数用于将图像作为纹理绑定到Character对象:
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.
}
一旦绑定了图像,我就会尝试使用此函数渲染Character对象(这是在单独的类中找到的静态函数):
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();
}
无论我多么沉溺于此,我似乎无法让我的程序做任何事情,除了渲染一个没有纹理的纯白色方块。我已经检查过以确保变量file,_texture,_dimension和_data都包含值。任何人都可以发现我可能做错了吗?
答案 0 :(得分:0)
我不认为你可以只输入一个原始文件到glTexImage2D,除非你以那种格式存储纹理文件(你可能不会)。 glTexImage2D需要一个巨大的数组字节(代表纹素颜色),但文件格式通常不会存储这样的图像。即使是bmp也有一些标题信息。
使用第三方图像加载程序库(如DevIL或SOIL)加载纹理!这些库可以将最常见的图像文件格式(png,jpg,tga,...)转换为可以输入到OpenGL的字节流!
旁注: 调用glTexImage2D(...,data)后,数据内容将被复制到GPU内存(VRAM)中。从这一点开始,您只需使用它的id绑定纹理,因为它已经在VRAM中。在每个帧中调用glTexImage2D()会将每个帧中的整个纹理重新上载到vram中,从而导致性能损失。