专注于 JetBrains IDEA 全家桶,永久激活,教程
持续更新 PyCharm,IDEA,WebStorm,PhpStorm,DataGrip,RubyMine,CLion,AppCode 永久激活教程

OpenGL纹理及常用API

纹理

之前我们已经通过渲染三角形,通过深度计算、颜色混合等方式,模拟出了3D效果,但是为了达到更加真实的效果,还有一种方式:纹理贴图(texture mappint).纹理是一种应用到场景中三角形上的图像数据,通过过滤的纹理单元(相当于基于纹理的像素)填充到实心区域.

纹理贴图可以理解为,新房装修的墙纸,依据一面墙各个角的点,对应墙纸的点,然后贴上去.

51_1.png

1.读取像素

OpenGL一般读取的是tga文件,OpenGL ES可以直接使用png、jpg压缩格式的图片.targa图像格式(.tga)是一种方便而且容易使用的图像格式,它即支持简单颜色图像,也支持带有Alpha值的图像.

gltReadTGABits(const char *szFileName, GLint *iWidth, GLint *iHeight, GLint *iComponents, GLenum *eFormat)
1.szFileName:纹理文件名称
2.iWidth:文件宽度地址 nWidth用来接受宽度值
3.iHeight:文件高度地址
4.iComponents:文件组件地址
5.eFormat:文件格式地址
返回值pBits:指向图像数据的指针

gltReadTGABits函数用来打开文件,然后读入文件头并进行语法分析,以确定文件的宽度、高度和数据格式等,返回的结果指向了图像数据.

2.载入纹理

在几何图形中应用纹理贴图时,第一个必要步骤就是将纹理载入内存.一旦被载入,这些纹理就会称为当前纹理状态的一部分.有3个OpenGL函数经常用来从存储器缓冲区中载入:

  • glTexImage1D
  • glTexImage2D
  • glTexImage3D

它们是由glTexImage派生出来,OpenGL支持一维、二维、三维纹理贴图,使用相应的函数来载入这些纹理,并将它们设置为当前纹理.

glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
 1.target:纹理维度 1、2、3D
 2.level:mip贴图层次,对于非mip贴图的纹理,可以设置为0
 3.internalformat:纹理单元存储的颜色成分
 4.width:纹理宽度
 5.height:纹理高度
 6.border:加载纹理的边界宽度
 8.format:OpenGL的像素格式,一般由读取时的eFormat决定
 7.type:像素数据的数据类型,告诉OpenGL使用缓存区中的什么数据类型来存储颜色分量,像素数据的数据类型
 8.pixels:指向纹理图像数据的指针

  • width,height和depth参数一般都是2的整数次方,在较老的OpenGL实现中,如果使用了非2的整数次幂的值,将会导致纹理贴图被隐式的禁用.
  • border参数允许为纹理贴图指定一个边界宽度,纹理边界允许通过对边界处的纹理单元进行额外的设置,来对它的宽度、高度或深度进行扩展.

format:像素格式

像素格式一般常用GL_RGBA,GL_RGB

常量 说明
GL_RGB 描述红、绿、蓝顺序排列的颜⾊
GL_RGBA 按照红、绿、蓝、Alpha顺序排列的颜⾊
GL_BGR 按照蓝、绿、红顺序排列颜⾊
GL_BGRA 按照蓝、绿、红、Alpha顺序排列颜⾊
GL_RED 每个像素只包含了⼀个红⾊分量
GL_GREEN 每个像素只包含了⼀个绿⾊分量
GL_BLUE 每个像素只包含了⼀个蓝⾊分量
GL_RG 每个像素依次包含了一个红色和绿色的分量
GL_RED_INTEGER 每个像素包含了一个整数形式的红⾊分量
GL_GREEN_INTEGER 每个像素包含了一个整数形式的绿色分量
GL_BLUE_INTEGER 每个像素包含了一个整数形式的蓝色分量
GL_RG_INTEGER 每个像素依次包含了一个整数形式的红⾊、绿⾊分量
GL_RGB_INTEGER 每个像素包含了一个整数形式的红⾊、蓝⾊、绿色分量
GL_RGBA_INTEGER 每个像素包含了一个整数形式的红⾊、蓝⾊、绿⾊、Alpah分量
GL_BGR_INTEGER 每个像素包含了一个整数形式的蓝⾊、绿⾊、红色分量
GL_BGRA_INTEGER 每个像素包含了一个整数形式的蓝⾊、绿⾊、红色、Alpah分量
GL_STENCIL_INDEX 每个像素只包含了一个模板值
GL_DEPTH_COMPONENT 每个像素只包含一个深度值
GL_DEPTH_STENCIL 每个像素包含一个深度值和一个模板值

type:像素数据的类型

常用的是GL_UNSIGNED_BYTE

常量 说明
GL_UNSIGNED_BYTE 每种颜色分量都是一个8位无符号整数
GL_BYTE 8位有符号整数
GL_UNSIGNED_SHORT 16位无符号整数
GL_SHORT 16位有符号整数
CL_UNSIGNED_INT 32位无符号整数
GL_INT 32位有符号整数
GL_FLOAT 单精度浮点数
GL_HALF_FLOAT 半精度浮点数
GL_UNSIGNED_BYTE_3_2_3 包装的RGB值
GL_UNSIGNED_BYTE_2_3_3_REV 包装的RGB值
GL_UNSIGNED_SHORT_5_6_5 包装的RGB值
GL_UNSIGNED_SHORT_5_6_5_REV 包装的RGB值
GL_UNSIGNED_SHORT_4_4_4_4 包装的RGB值
GL_UNSIGNED_SHORT_4_4_4_4_REV 包装的RGB值
GL_UNSIGNED_SHORT_5_5_5_1 包装的RGB值
GL_UNSIGNED_SHORT_1_5_5_5_REV 包装的RGB值
GL_UNSIGNED_INT_8_8_8_8 包装的RGB值
GL_UNSIGNED_INT_8_8_8_8_REV 包装的RGB值
GL_UNSIGNED_INT_10_10_10_2 包装的RGB值
GL_UNSIGNED_INT_2_10_10_10_REV 包装的RGB值
GL_UNSIGNED_INT_24_8 包装的RGB值
GL_UNSIGNED_INT_10F_11F_REV 包装的RGB值
GL_FLOAT_24_UNSIGNED_INT_24_8_REV 包装的RGB值

3.生成纹理

  • 分配纹理对象

在纹理之间进行切换或重新加载不同的纹理对象可能会是开销很大的操作.纹理对象允许我们一次加载一个以上的纹理状态,包括纹理图像,以及在它们之间进行快速切换.纹理状态是由当前绑定的纹理对象维护的,而纹理对象是由一个无符号整数标识的.首先是分配纹理对象

glGenTextures(GLsizei n, GLuint *textures)
n:纹理对象个数
textures;纹理对象指针

函数指定纹理对象的数量和一个指针,这个指针指向一个无符号整形数组(由纹理对象标识符填充).

  • 绑定纹理状态
glBindTexture(GLenum target, GLuint texture)
target:纹理维度:GL_TEXTURE_1D 、2D、3D
texture:纹理对象

texture是需要绑定的特定纹理对象,此后,所有的纹理加载和纹理参数设置只影响当前绑定的纹理对象.

  • 删除纹理对象
void glDeleteTextures(GLsizei n, GLuint *textures)

在销毁大量的纹理内存时,多次调用可能会造成延迟

4.纹理参数

//参数1:target,指定这些参数将要应⽤用在那个纹理理模式上,⽐比如GL_TEXTURE_1D、GL_TEXTURE_2D、GL_TEXTURE_3D。 
//参数2:pname,指定需要设置那个纹理理参数
//参数3:param,设定特定的纹理理参数的值
glTexParameterf(GLenum target,GLenum pname,GLFloat param);
glTexParameteri(GLenum target,GLenum pname,GLint param);
glTexParameterfv(GLenum target,GLenum pname,GLFloat *param);
glTexParameteriv(GLenum target,GLenum pname,GLint *param);

  • 设置过滤方式

设置放大/缩小时的过滤方式

放大:GL_TEXTURE_MAG_FILTER
缩小:GL_TEXTURE_MIN_FILTER
临近过滤:GL_NEAREST
线性过滤:GL_LINEAR

51_2.png我们可以看下面例子,在放大时的临近过滤和线性过滤的区分.

51_3.png左侧临近过滤:临近过滤最显著的特征就是,当纹理被拉伸到特别大的时候,会出现斑驳状像素.是因为不管纹理坐标位于哪个纹理单元,这个纹理单元的颜色就作为这个片段的纹理颜色.

右侧线性过滤:线性过滤是把这个纹理坐标周围的纹理单元的加权平均值应用到这个纹理坐标上(线性插值).所以当拉伸放大时会出现“失真”的效果.线性过滤往往比临近过滤付出更多的额外开销,但是当今硬件设备,几乎可以忽略不计.

  • 设置环绕方式

环绕方式指当纹理坐标超出默认范围时,边缘的显示形式.

x轴:GL_TEXTURE_WRAP_S
y轴:GL_TEXTURE_WRAP_T
z轴:GL_TEXTURE_WRAP_R

环绕方式 描述
GL_REPEAT 对纹理的默认行为,重复纹理图像
GL_CLAMP 类似Repeat,但是重复的图片都是镜像放置的
GL_CLAMP_TO_EDGE 纹理坐标约束在0-1之间,超出则重复纹理坐标的边缘
GL_CLAMP_TO_BORDER 超出的部分显示用户指定的颜色

51_4.png

推荐:

OpenGL 纹理相关API OpenGL纹理

文章永久链接:https://tech.souyunku.com/31378

未经允许不得转载:搜云库技术团队 » OpenGL纹理及常用API

JetBrains 全家桶,激活、破解、教程

提供 JetBrains 全家桶激活码、注册码、破解补丁下载及详细激活教程,支持 IntelliJ IDEA、PyCharm、WebStorm 等工具的永久激活。无论是破解教程,还是最新激活码,均可免费获得,帮助开发者解决常见激活问题,确保轻松破解并快速使用 JetBrains 软件。获取免费的破解补丁和激活码,快速解决激活难题,全面覆盖 2024/2025 版本!

联系我们联系我们