资源下载地址:https://download.csdn.net/download/sheziqiong/85628707
资源下载地址:https://download.csdn.net/download/sheziqiong/85628707
在OpenGL消隐和光照实验的基础上,通过实现实验内容,掌握OpenGL中纹理的使用,并验证课程中关于纹理的内容。
实验内容和原理使用Visual Studio C++编译已有项目工程。
模型尺寸不做具体要求。要求修改代码达到以下要求:
1.通过设置纹理,使得茶壶纹理为:
2.使得桌子纹理为:
3.对茶壶实现纹理和光照效果的混合
4.自己用代码产生一张纹理,并贴在茶壶表面,效果类似:
5.在桌面上实现两张纹理的叠合效果(附加项,完成可加分):
提示:glSolidCube()并不会为多边形指定纹理坐标,因此需要自己重写一个有纹理坐标的方块函数。另外,此实验需要用到 #include
Visual Studio C++
glut.zip
模板工程
操作方法和实验步骤具体步骤按照参考资料的提示,对茶壶和桌子的纹理进行设置和更新。
读入纹理贴图部分的代码很像上学期DIP(图像信息处理)课上对于bmp文件的读写操作,所以就不再赘述。
加载纹理函数部分:
重点函数:
voidglBindTexture(GLenum target,GLuint texture); 将一个命名的纹理绑定到一个纹理目标上,参数target指定绑定目标,参数texture指定纹理的名字。
glBindTexture允许我们向GL_TEXTURE_1D, GL_TEXTURE_2D, GL_TEXTURE_3D, GL_TEXTURE_1D_ARRAY, GL_TEXTURE_2D_ARRAY, GL_TEXTURE_RECTANGLE, GL_TEXTURE_CUBE_MAP, GL_TEXTURE_CUBE_MAP_ARRAY, GL_TEXTURE_BUFFER, GL_TEXTURE_2D_MULTISAMPLE or GL_TEXTURE_2D_MULTISAMPLE_ARRAY 绑定一张纹理。当把一张纹理绑定到一个目标上时,之前对这个目标的绑定就会失效。纹理名字是一个无符号整数。值0是被保留的,它代表了每一个纹理目标的默认纹理。对于当前的GL渲染上下文中的共享对象空间,纹理名称以及它们对应的纹理内容是局部的;只有在显式开启上下文之间的共享,两个渲染上下文才可以共享纹理名称。
Mipmap——可以提高渲染性能与提升场景视觉质量的一个较为优秀的纹理技术,可以解决常见的闪烁和性能等问题。用glTexParameteri()函数就可以通过纹理参数来控制要加载的层级范围。
实验中用到的过滤方式:GL_TEXTURE_MAG_FILTER: 放大过滤, GL_TEXTURE_MIN_FILTER: 缩小过滤;GL_NEAREST:在mip基层上使用最近邻过滤。实际上,Mipmap的纹理过滤的方式还有如下:
常量 | 描述 |
---|---|
GL_NEAREST | 在mip基层上使用最邻近过滤 |
GL_LINEAR | 在mip基层上使用线性过滤 |
GL_NEAREST_MIPMAP_NEAREST | 选择最邻近的mip层,并使用最邻近过滤 |
GL_NEAREST_MIPMAP_LINEAR | 在mip层之间使用线性插值和最邻近过滤 |
GL_LINEAR_MIPMAP_NEAREST | 选择最邻近的mip层,使用线性过滤 |
GL_LINEAR_MIPMAP_LINEAR | 在mip层之间使用线性插值和使用线性过滤,又称三线性mipmap |
其中GL_NEAREST_MIPMAP_NEAAREST具有很好的性能,也能够解决闪烁的问题,但在视觉效果上会比较差。其中GL_LINEAR_MIPMAP_NEAREST常用于游戏加速,使用了质量较高的线性过滤,和快速的选择的方式(最邻近方式)。
GL_APICALL void GL_APIENTRY glTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void* pixels);
参数说明:
target 指定目标纹理,这个值必须是GL_TEXTURE_2D。
level 执行细节级别。0是最基本的图像级别,n表示第N级贴图细化级别。
internalformat 指定纹理中的颜色组件。可选的值有GL_ALPHA,GL_RGB,GL_RGBA,GL_LUMINANCE, GL_LUMINANCE_ALPHA 等几种。
width 指定纹理图像的宽度,必须是2的n次方。纹理图片至少要支持64个材质元素的宽度
height 指定纹理图像的高度,必须是2的m次方。纹理图片至少要支持64个材质元素的高度
border 指定边框的宽度。必须为0。
format 像素数据的颜色格式, 不需要和internalformatt取值必须相同。可选的值参考internalformat。
type 指定像素数据的数据类型。可以使用的值有GL_UNSIGNED_BYTE,GL_UNSIGNED_SHORT_5_6_5,GL_UNSIGNED_SHORT_4_4_4_4,GL_UNSIGNED_SHORT_5_5_5_1。
pixels 指定内存中指向图像数据的指针
定义纹理函数:
贴纹理并注意和光照效果混合(以茶壶为例),注意到增加了操作控制切换纹理与灯光的布尔量:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8ZN4tKYR-1655101678346)(https://www.writebug.com/myres/static/uploads/2022/6/12/7a07d863f0fec69ab619788371ec7fb7.writebug)]
重点函数:纹理映射voidglTexEnvf(GLenumtarget,GLenumpname,GLfloatparam); 对于贴了纹理的模型,可以使用glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE,XX)来指定纹理贴图和材质混合的方式,从而产生特定的绘制效果。(XX为混合方式参数,OpenGL默认为GL_REPLACE,即只使用纹理)我们使用GL_MODULATE参数模式是把纹理元素的颜色乘以几何图元(进行光照计算之后)的颜色。通过这种模式,我们可以用彩色的几何图形与纹理结合来产生不同的效果。
至此,本次实验重头戏都已经完成,下面是加分项——纹理叠合的实现。
多纹理混合的实现原理:在OpenGL中通过ARB_multitexture和ARB_texture_env_combine扩展来实现多纹理混合。分为以下几个步骤:
计算3个纹理各自的贡献,并将它们编码进顶点的颜色中,这样颜色的RGB部分控制纹理阶段0和1间的插值,颜色的ALPHA控制纹理阶段1和2间的插值。
使用GL_ARB_multitexture将3个纹理同时应用到物体表面。
将第一个纹理设为纹理阶段0。
在纹理阶段1,使用GL_INTERPOLATE_ARB在纹理阶段0的输出(第一个纹理)和阶段1的纹理之间用GL_SRC_COLOR(颜色的RGB部分)进行线性插值。
在纹理阶段2,使用GL_INTERPOLATE_ARB在纹理阶段1的输出(第一个纹理和第二个纹理的混合体)和阶段2的纹理之间用GL_SRC_COLOR(颜色的ALPHA部分)进行线性插值。
当然现在在新版本的OpenGL中用shader来实现会方便很多……鉴于OpenGL版本问题,我们还是用这几个扩展方法来实现。
混合纹理的设置:
绘制多纹理物体也是采用单独绘制的方法,其中调用了如下函数:
void glActiveTexture(GLenum texUnit); 选择可以由纹理函数进行修改的当前纹理单位,texUnit是一个符号常量,其形式为GL_TEXTUREi,其中i的范围是从0到k-1,k是纹理单位的大数量。
void glMultiTexCoord2f(GLenum texUnit, const TYPE* coords); 将参数coords中的纹理坐标数据(s,t,r,q)用于纹理单位texUnit。texUnit参数所使用的枚举值与glActiveTexture()函数相同。
(略)
实验结果与分析
资源下载地址:https://download.csdn.net/download/sheziqiong/85628707
资源下载地址:https://download.csdn.net/download/sheziqiong/85628707
你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧
名称栏目:基于C++OpenGL实现的小桌茶壶纹理图形绘制-创新互联
文章转载:http://scpingwu.com/article/dgdpep.html