代码
//纹理(材质)加载函数
unsigned int loadTexture(const char* path)
{
unsigned int textureID;
glGenTextures(1, &textureID);
int width, height, nrComponents;
unsigned char* data = stbi_load(path, &width, &height, &nrComponents, 0);
if (data)
{
GLenum format;
if (nrComponents == 1)
format = GL_RED;
else if (nrComponents == 3)
format = GL_RGB;
else if (nrComponents == 4)
format = GL_RGBA;
glBindTexture(GL_TEXTURE_2D, textureID);
glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, GL_UNSIGNED_BYTE, data);
glGenerateMipmap(GL_TEXTURE_2D);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
stbi_image_free(data);
}
else
{
std::cout << "Texture failed to load at path: " << path << std::endl;
stbi_image_free(data);
}
return textureID;
}
代码解释
- OpenGL的对象在创建时通常需要一个unsigned int类型的变量,将该变量与OpenGL创建出的对象进行绑定,绑定后可以将该变量看作是所创建的OpenGL对象的一个引用
- stbi_load:stb_image库提供的函数,可以读取多种格式的栅格文件数据,并返回图像的宽度、高度和颜色通道维度,这些都是OpenGL绑定纹理所需要的参数
- glBindTexture:将纹理对象绑定到target name上
- glTexImage2D:将读取的图像数据转换为OpenGL的纹理数据
- glGenerateMipmap:MipMap操作,详细见计算机图形学入门
- glTexParameteri:设置纹理的环绕参数;因为纹理坐标的范围通常是从(0, 0)到(1, 1),所以需要开发者处理纹理坐标设置在范围之外的情况;第一个参数指定了纹理目标,第二个参数指定设置的选项和应用的纹理轴,第三个参数传递一个环绕方式,可供选择的环绕方式有4种,分别是:
- GL_REPEAT:对纹理的默认行为。重复纹理图像
- GL_MIRRORED_REPEAT:和GL_REPEAT一样,但每次重复图片是镜像放置的
- GL_CLAMP_TO_EDGE:纹理坐标会被约束在0到1之间,超出的部分会重复纹理坐标的边缘,产生一种边缘被拉伸的效果
- GL_CLAMP_TO_BORDER:超出的坐标为用户指定的边缘颜色
- stbi_image_free:释放data占用的缓存
- 最后返回纹理的ID即可使用