使用C ++进行OpenGL纹理处理

时间:2014-07-23 15:18:00

标签: c++ opengl texturing

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)。有人可以向我解释上述编码是如何工作的吗?

2 个答案:

答案 0 :(得分:4)

你有点问“OpenGL如何工作”,这取决于你使用的是哪个版本。我建议:http://www.opengl-tutorial.org/beginners-tutorials

或者更好的是,阅读“红皮书”(第8版涵盖OpenGL 4.3)

http://www.opengl-redbook.com/

答案 1 :(得分:2)

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错误检查并导致程序崩溃。在发布版本中,不会检测和处理文件操作错误。

不要使用此代码!