如果使用一般的纹理过滤,当观察方向跟模型表面不是相互垂直的的情况下,会出现纹理信息的丢失,表现为图像看上去比较模糊,如下图所示,远处场景的细节信息很差:

针对这种情况,可以采用同向异性过滤的方式处理纹理,在过滤纹理的时候,考虑到观察角度不同,使纹理本身沿着模型表面倾斜的方向进行延伸。

使用如下语句查询当前系统支持的最大同向异性过滤的数值,数值越大,表示沿着最大变化方向所采样的纹理单元越多,显示效果就越好:

GLfloat max_TexAni;    //查询允许的各向异性数量glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &max_TexAni);

以“ GL_TEXTURE_MAX_ANISOTROPY_EXT ”为参数调用“ glTexParameterf ”函数,并设置同向异性过滤的数值,就可以使设置生效。以下是经过同向异性过滤设置的显示效果:

远处纹理的细节增强了很多。以下是工程代码:

#define WindowWidth  400
#define WindowHeight 400
#define WindowTitle  "OpenGL Mip纹理贴图&&同向异性过滤"#include <Windows.h>
#include "GL/glew.h"
#include <GL/freeglut.h>
#include <stdio.h>
#include <stdlib.h>//定义纹理对象编号
GLuint texGround;
GLuint texWall;
GLuint texSky;#define BMP_Header_Length 54  //图像数据在内存块中的偏移量
static GLfloat angle = 0.0f;   //旋转角度
static GLfloat zPosition = 10;// 函数power_of_two用于判断一个整数是不是2的整数次幂
int power_of_two(int n)
{if (n <= 0)return 0;return (n & (n - 1)) == 0;
}/* 函数load_texture28.* 读取一个BMP文件作为纹理29.* 如果失败,返回0,如果成功,返回纹理编号30.*/
GLuint load_texture(const char* file_name)
{GLint width, height, total_bytes;GLubyte* pixels = 0;GLuint last_texture_ID = 0, texture_ID = 0;// 打开文件,如果失败,返回    FILE* pFile = fopen(file_name, "rb");if (pFile == 0)return 0;// 读取文件中图象的宽度和高度    fseek(pFile, 0x0012, SEEK_SET);fread(&width, 4, 1, pFile);fread(&height, 4, 1, pFile);fseek(pFile, BMP_Header_Length, SEEK_SET);// 计算每行像素所占字节数,并根据此数据计算总像素字节数    {GLint line_bytes = width * 3;while (line_bytes % 4 != 0)++line_bytes;total_bytes = line_bytes * height;}// 根据总像素字节数分配内存    pixels = (GLubyte*)malloc(total_bytes);if (pixels == 0){fclose(pFile);return 0;}// 读取像素数据    if (fread(pixels, total_bytes, 1, pFile) <= 0){free(pixels);fclose(pFile);return 0;}// 对就旧版本的兼容,如果图象的宽度和高度不是的整数次方,则需要进行缩放    // 若图像宽高超过了OpenGL规定的最大值,也缩放    {GLint max;glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max);if (!power_of_two(width)|| !power_of_two(height)|| width > max|| height > max){const GLint new_width = 256;const GLint new_height = 256; // 规定缩放后新的大小为边长的正方形    GLint new_line_bytes, new_total_bytes;GLubyte* new_pixels = 0;// 计算每行需要的字节数和总字节数    new_line_bytes = new_width * 3;while (new_line_bytes % 4 != 0)++new_line_bytes;new_total_bytes = new_line_bytes * new_height;// 分配内存    new_pixels = (GLubyte*)malloc(new_total_bytes);if (new_pixels == 0){free(pixels);fclose(pFile);return 0;}// 进行像素缩放    gluScaleImage(GL_RGB,width, height, GL_UNSIGNED_BYTE, pixels,new_width, new_height, GL_UNSIGNED_BYTE, new_pixels);// 释放原来的像素数据,把pixels指向新的像素数据,并重新设置width和height    free(pixels);pixels = new_pixels;width = new_width;height = new_height;}}// 分配一个新的纹理编号    glGenTextures(1, &texture_ID);if (texture_ID == 0){free(pixels);fclose(pFile);return 0;}// 绑定新的纹理,载入纹理并设置纹理参数    // 在绑定前,先获得原来绑定的纹理编号,以便在最后进行恢复    GLint lastTextureID = last_texture_ID;glGetIntegerv(GL_TEXTURE_BINDING_2D, &lastTextureID);glBindTexture(GL_TEXTURE_2D, texture_ID);/*glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);130.    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); */GLfloat max_TexAni;    //查询允许的各向异性数量glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &max_TexAni);glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, max_TexAni);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_LINEAR);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);/* glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0,140.    GL_BGR_EXT, GL_UNSIGNED_BYTE, pixels); */gluBuild2DMipmaps(GL_TEXTURE_2D, 3, width, height, GL_BGR_EXT, GL_UNSIGNED_BYTE, pixels);glBindTexture(GL_TEXTURE_2D, lastTextureID);  //恢复之前的纹理绑定    free(pixels);return texture_ID;
}void Display(void)
{// 清除屏幕    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);// 设置视角    glMatrixMode(GL_PROJECTION);glLoadIdentity();gluPerspective(65, 1, 1, 100);glMatrixMode(GL_MODELVIEW);glLoadIdentity();gluLookAt(0, 0, zPosition, 0, 0, 0, 0, 1, 0);glRotatef(angle, 0.0f, 1.0f, 0.0f); //旋转    // 绘制左侧墙壁以及纹理    glBindTexture(GL_TEXTURE_2D, texWall);glBegin(GL_QUADS);glTexCoord2f(0.0f, 0.0f); glVertex3f(-5.0f, -5.0f, 100.0f);glTexCoord2f(30.0f, 0.0f); glVertex3f(-5.0f, -5.0f, -100.0f);glTexCoord2f(30.0f, 2.0f); glVertex3f(-5.0f, 5.0f, -100.0f);glTexCoord2f(0.0f, 2.0f); glVertex3f(-5.0f, 5.0f, 100.0f);glEnd();//绘制右侧墙  glBegin(GL_QUADS);glTexCoord2f(0.0f, 0.0f); glVertex3f(5.0f, -5.0f, 100.0f);glTexCoord2f(30.0f, 0.0f); glVertex3f(5.0f, -5.0f, -100.0f);glTexCoord2f(30.0f, 2.0f); glVertex3f(5.0f, 5.0f, -100.0f);glTexCoord2f(0.0f, 2.0f); glVertex3f(5.0f, 5.0f, 100.0f);glEnd();//绘制地板  glBindTexture(GL_TEXTURE_2D, texGround);glBegin(GL_QUADS);glTexCoord2f(0.0f, 0.0f); glVertex3f(-5.0f, -5.0f, 100.0f);glTexCoord2f(0.0f, 1.0f); glVertex3f(5.0f, -5.0f, 100.0f);glTexCoord2f(25.0f, 1.0f); glVertex3f(5.0f, -5.0f, -100.0f);glTexCoord2f(25.0f, 0.0f); glVertex3f(-5.0f, -5.0f, -100.0f);glEnd();//绘制顶层  glBindTexture(GL_TEXTURE_2D, texSky);glBegin(GL_QUADS);glTexCoord2f(0.0f, 0.0f); glVertex3f(-5.0f, 5.0f, 100.0f);glTexCoord2f(0.0f, 3.0f); glVertex3f(5.0f, 5.0f, 100.0f);glTexCoord2f(35.0f, 3.0f); glVertex3f(5.0f, 5.0f, -100.0f);glTexCoord2f(35.0f, 0.0f); glVertex3f(-5.0f, 5.0f, -100.0f);glEnd();glutSwapBuffers();
}void SpecialKey(GLint key, GLint x, GLint y)
{if (key == GLUT_KEY_UP){zPosition += 1.0f;}if (key == GLUT_KEY_DOWN){zPosition -= 1.0f;}if (key == GLUT_KEY_LEFT){angle += 0.5f;}if (key == GLUT_KEY_RIGHT){angle -= 0.5f;}glutPostRedisplay();
}int main(int argc, char* argv[])
{// GLUT初始化    glutInit(&argc, argv);glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);glutInitWindowPosition(100, 100);glutInitWindowSize(WindowWidth, WindowHeight);glutCreateWindow(WindowTitle);glEnable(GL_DEPTH_TEST);glEnable(GL_TEXTURE_2D);    // 启用纹理    texGround = load_texture("ground.bmp");  //加载纹理    texWall = load_texture("wall.bmp");texSky = load_texture("sky.bmp");glutDisplayFunc(&Display);   //回调函数    glutSpecialFunc(&SpecialKey);glutMainLoop(); //循环调用    return 0;
}

OpenGL(二十三) 各向异性纹理过滤相关推荐

  1. 读书笔记——各向异性纹理过滤

    启用 if (gltIsExtSupported("GL_EXT_texture_filter_anisotropic")){GLfloat fLargest;glGetFloat ...

  2. 现代opengl 设计入门,纹理贴图

    上节 现代opengl 设计入门,着色器  介绍了着色器语言GLSL, 可以绘制多彩的三角形.这节介绍更高级的着色,纹理贴图. 先做纹理贴图的基本介绍,然后介绍其中几个重要设置:纹理环绕方式,纹理过滤 ...

  3. OpenGL蓝宝书源码学习(二十三)第七章——MultiTexture多重纹理

    在上一节CubeMap的基础上新增了一个纹理贴图实现多重纹理. // MultiTexture.cpp // OpenGL SuperBible // Demonstrates applying a ...

  4. OpenGL之纹理过滤(Texture Filtering)、MipMap方法、纹理坐标

    1.1 纹理过滤 像素.片元都是具有面积的,一个像素可能对应物体上的一小块区域,而物体上这个小区域对应于纹理图像上的一个小区域,因此一个像素的颜色可能来自于纹理中的一小个不规则区域,如果纹理的分辨率比 ...

  5. OpenGL之纹理过滤的四种方式

    I.纹理过滤: 当三维空间里面的多边形经过坐标变换.投影.光栅化等过程,变成二维屏幕上的一组象素的时候,对每个象素需要到相应纹理图像中进行采样,这个过程就称为纹理过滤. II.纹理过滤通常分为2种情况 ...

  6. OpenGL 纹理过滤和 mip 贴图

    一.概念 1. 纹理过滤 当纹理贴到具体像素上时,像素需要到纹理图像中进行采样,这个过程称为纹理过滤. 纹理过滤通常有两种情况:放大(GL_TEXTURE_MAG_FILTER)和缩小(GL_TEXT ...

  7. 手把手教会OpenGL之纹理贴图、包含纹理载入、纹理过滤、边界处理、纹理参数设置(入门级别案例,棋盘)

    一.OpenGL中纹理的加载(对glTexImage2D函数的使用) 二.纹理过滤(glTexParameteri参数中的GL_TEXTURE_MAG_FILTER与 GL_TEXTURE_MIN_F ...

  8. C++ Opengl纹理过滤和光照实例源码

    C++ Opengl纹理过滤和光照实例源码 项目开发环境 项目功能 项目演示 项目源码传送门 项目开发环境 开发语言:C++和IDE:VS2017,操作系统Windows版本windows SDK8. ...

  9. 初识OpenGL (-)纹理过滤(Texture Filtering)

    1. OpenGL需要知道怎样将纹理像素(Texture Pixel,也叫Texel)映射到纹理坐标. 纹理坐标 不依赖于分辨率(Resolution),它可以是任意浮点值, 给模型顶点设置的那个数组 ...

最新文章

  1. ML Pipelines管道
  2. A Strange Bitcoin Transaction
  3. 用平方映射理解tanh
  4. python监控程序编写_05-python进阶-简单监控程序开发
  5. mysql随机显示记录_MySQL随机读取表中记录
  6. vue饼图组件_vue2.0 自定义 饼状图 (Echarts)组件
  7. 用memoization优化递归算法[JS/PHP实现]
  8. DeepFace人脸检测(python实现)
  9. 以太网网络变压器EMI电流及以太网网络变压器对EMI阻断原理
  10. 1074: 百钱买百鸡
  11. RK3288 开发板 排插物理引脚对应图以及如何进入android6.0.1内核终端、uboot终端
  12. 如何打开VoLTE,ViLTE,VoWifi Feature
  13. 现代微服务拆分与设计
  14. Antv X6 画布平移
  15. CSUOJ-1986: 玄学
  16. 涂鸦模组开发光照传感器
  17. 《精通Tableau商业数据分析与可视化》之序言
  18. 埃塞俄比亚 - 阿姆哈拉语
  19. 做好开源客服系统,春松客服入驻 Rainbond 开源应用商店 | Chatopera
  20. 2021 各式免費 sorce code final

热门文章

  1. docker中mysql执行脚本文件
  2. GDI与DirectDraw之间的区别
  3. 抖音app安卓抓包不能连接网络问题解决、高版本安卓抓包证书校验问题
  4. 荣耀笔记本linux重装win10,荣耀MagicBook笔记本一键快速重装win10教程
  5. python post方法登录微信公众号_python实现简单的微信公众号后台编写
  6. 独家首发DJ舞曲音乐在线播放微信小程序源码下载支持多分类歌曲
  7. 如何优雅使用百度网盘(Mac 版本)
  8. 中富金石:智能卫浴行业高速发展,智能马桶将迎来高光时刻
  9. Vue 获取 当前日期
  10. STAAD.Pro CONNECT Edition V22 Update 6