OpenGL系列(五)纹理贴图

概述

    OpenGL纹理是一种在三维图形中应用纹理映射的技术。纹理是一张图像,可以应用到三维模型的表面上,从而使得模型看起来更加真实和具有细节。通过纹理映射,可以将图像的像素值与三维模型的顶点进行匹配,从而为模型的表面增加细节和图案。

    OpenGL提供了一套用于加载、创建和使用纹理的API,使得纹理映射变得简单和高效。在OpenGL中,纹理被存储在纹理缓冲区中,并通过纹理坐标来进行访问。纹理坐标是一个二维向量,范围在[0,1]之间,用于映射纹理的像素值。

    为了应用纹理映射,需要先加载纹理图像并将其传输到OpenGL的纹理缓冲区中。然后,可以在绘制三维模型之前,将纹理坐标与模型的顶点进行匹配,并通过纹理坐标在纹理缓冲区中获取相应的像素值。最后,将像素值应用到模型的表面上,从而实现纹理映射。

OpenGL还提供了一些纹理过滤和纹理环绕的选项,用于控制纹理在放大和缩小时的插值和边界处理。这些选项可以改善纹理映射的质量和效果,使得纹理在不同大小和角度下都能正确显示。

总的来说,OpenGL纹理是一种强大的技术,可以为三维模型增加细节和图案,并提升图形渲染的质量和真实感。通过合理的纹理映射和纹理处理,可以使得模型在视觉上更加吸引人和逼真。

示例

    接下来通过一个简单的示例来介绍如何使用纹理贴图将一张图片映射到一个矩形中,效果如下图所示。

    在上图中,中间是一个矩形,在该矩形中显示的图片,下面分步介绍如何实现上面的效果。

1、创建纹理对象 

    要使用纹理,首先要创建纹理对象,代码如下。

    mTexture = 0;
    glGenTextures(1, &mTexture);
    glBindTexture(GL_TEXTURE_2D, mTexture);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

 创建纹理过程解析如下。

1)创建纹理对象:glGenTextures用于创建纹理对象,1表示创建一个纹理对象,成功后纹理对象的句柄保存到tex中。

2)绑定纹理对象:glBindTexture用于绑定纹理对象到纹理目标GL_TEXTURE_2D,绑定后对目标的操作会影响到被绑定的纹理对象。

3)设置参数:glTexParameterf用于设置纹理参数。参数GL_TEXTURE_WRAP_S设置为GL_CLAMP_TO_EDGE表示S方向超出范围[0.0,1.0]时使用边界的颜色,同样参数GL_TEXTURE_WRAP_T也设置为GL_CLAMP_TO_EDGE表示T方向超出范围[0.0,1.0]时使用边界的颜色。参数GL_TEXTURE_MIN_FILTER和GL_TEXTURE_MAG_FILTER都设置为GL_LINEAR表示纹理缩小和放大的过滤方式都是线性插值。

2、载入图片数据

    创建纹理对象后,接下来向该对象载入图片数据,流程如下。

    AAsset *pathAsset = AAssetManager_open(assetManager,path.c_str(), AASSET_MODE_BUFFER);
    unsigned char *filedata = (unsigned char *) AAsset_getBuffer(pathAsset);
    off_t assetLength = AAsset_getLength(pathAsset);
    stbi_set_flip_vertically_on_load(true);
    unsigned char *data = stbi_load_from_memory(filedata, assetLength,&w,&h,&n,0);
    if(data != nullptr){
        GLint format = GL_RGB;
        if(n == 4) format = GL_RGBA;

        glTexImage2D(GL_TEXTURE_2D,0, format, w,h,0,format,GL_UNSIGNED_BYTE, data);
        glGenerateMipmap(GL_TEXTURE_2D);
    }

载入图片数据流程解析如下

1)AAssetManager_open打开assets目录的图片文件

2)AAsset_getBuffer获取图片文件的缓冲

3)stbi_load_from_memory将图片缓冲解吗得到图片数据

4)glTexImage2D向纹理对象载入图片数据

5)glGenerateMipmap生成多级渐远纹理

3、绑定纹理单元

    纹理对象要绑定到特定的纹理单元,采样器才能采样,绑定方法如下

    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, mTexture);

    这里把纹理对象绑定到0号纹理单元。

4、编写着色器

    纹理贴图的着色器如下。

    std::string strVs = R"(
#version 300 es
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec2 aTexCoord;

out vec2 vTexCoord;

void main()
{
    gl_Position = vec4(aPos, 1.0);
    vTexCoord = aTexCoord;
}
)";

    std::string strFs = R"(
#version 300 es
precision mediump float;
out vec4 FragColor;
in vec2 vTexCoord;
uniform sampler2D sampler;
void main()
{
    FragColor = texture(sampler, vTexCoord);
}
)";

    在顶点着色器中,有两个顶点属性,0号属性aPos表示顶点位置,1号属性aTexCoord表示纹理坐标。

    在片元着色器中,vTexCoord是纹理坐标,sampler是纹理采样器,在main方法中调用采样函数texture对纹理进行采样,采样结果输出到FragColor。

5、开始绘制

    绘制纹理的流程如下所示。

    mShader->setInt("sampler",0);

    glClear(GL_COLOR_BUFFER_BIT);
    glClearColor(0.5f,0.6f,0.7f,1.0f);
    glBindVertexArray(VAO);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);

绘制流程解析如下:

mShader->setInt("sampler",0); 知会着色器的采样器到几号纹理单元采样,0表示0号纹理单元。

glBindVertexArray(VAO);绑定VAO,有了VAO才知道如何取得顶点数据。

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); 绑定索引数据

glDrawElements开始绘制,由于已经绑定了索引数据,所以最后的参数无须传索引数据的首地址。

6、工程地址

    本示例已经上传到github,地址如下。

示例工程地址

  • 8
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
OpenGL球面纹理贴图是一种在球体上应用纹理的技术。在OpenGL中,为了使用球面纹理贴图,我们需要首先创建一个球体模型。这可以通过绘制一系列的三角形面片来实现,形成一个球体的表面。接下来,我们需要为球体模型创建一个纹理对象,并加载对应的纹理图像。 在加载纹理图像之后,我们需要设置一些纹理参数,例如缩小过滤和放大过滤的方式。然后,我们可以使用OpenGL纹理映射功能来将纹理图像应用到球体上的各个面片上。 在球面纹理贴图的过程中,需要将纹理坐标映射到球体的表面上。一种常用的方法是使用球坐标系来表示纹理坐标。球坐标系包括两个角度参数:纹理纬度和纹理经度。纹理纬度决定了纹理在球体上的垂直位置,而纹理经度则决定了纹理在球体上的水平位置。 在绘制球体的过程中,我们需要为每个顶点指定纹理坐标。可以根据对应的球面坐标来计算纹理坐标,并将其与顶点一起传递给着色器。在着色器中,可以使用纹理坐标来对纹理进行采样,并将采样到的纹素值与球体的法向量进行组合,从而得到最终的颜色值。 通过这种方式,我们可以在球体表面上实现复杂的纹理图案,例如地球表面的地形、云层等效果。同时,球面纹理贴图还可以应用于球体的各个部分,实现不同部分具有不同纹理的效果。 总而言之,OpenGL的球面纹理贴图技术可以使我们在球体上实现各种有趣的纹理效果,扩展了实时渲染的创作可能性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值