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

4

2 回答 2

4

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

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

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

于 2014-07-23T15:26:08.883 回答
2
GLuint createTexture(const char* filename, int width=128, int height=128)
{
    GLuint texture;

使用 C99 可变参数数组在栈上分配 width*height*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 纹理中。由于 this 使用了新分配的纹理对象句柄,因此纹理也由 this 初始化。

这里缺少很多重要的步骤。即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 错误检查和程序崩溃。在发布版本中,不会检测和处理文件操作错误。

不要使用此代码!

于 2014-07-23T16:35:20.487 回答