OpenGL ES 3.0之Texturing纹理详解(二)
Texture Filtering and Mipmapping 纹理过滤与多级纹理
前面我们已经讲了单个2D图像的2D纹理的介绍,这篇文章主要讲解多级纹理。纹理坐标是用于生成一个2D索引,当放大和缩小设置为GL_NEAREST时,将发生一个单一纹理将匹配到纹理坐标位置中,这是一个最近点的采样。
当使用一个多级纹理时,我们可以设置过滤模式,,为了达到屏幕像素和纹理图片像素更合适的比例,减少锯齿。因为多级纹理贴图的成功过滤,当在更远处观察时,我们向贴图链后移动,锯齿减少,实现高质量的图像。
// Load mipmap level 0
glTexImage2D(GL_TEXTURE_2D, , GL_RGB, width, height,
, GL_RGB, GL_UNSIGNED_BYTE, pixels);
level = ;
prevImage = &pixels[];
while(width > && height > )
{
int newWidth,
newHeight;
// Generate the next mipmap level
GenMipMap2D( prevImage, &newImage, width, height, &newWidth,
&newHeight);
// Load the mipmap level
glTexImage2D(GL_TEXTURE_2D, level, GL_RGB,
newWidth, newHeight, , GL_RGB,
GL_UNSIGNED_BYTE, newImage);
// Free the previous image
free(prevImage);
// Set the previous image for the next iteration
prevImage = newImage;
level++;
// Half the width and height
width = newWidth;
height = newHeight;
}
free(newlmage);
GenMipMap2D用于用于实现多级纹理。纹理过滤有2种:放大和缩小。当屏幕上设计的多边形的大小小于纹理图像时,我们使用缩小纹理。反之使用放大。使用过滤类型由具体硬件自动选择,但是API也提供了过滤控制,放大处理是不相关的,因为我们总是使用最大
可用的级别。对于缩小,有各种的采样模式可以使用。哪种模式的使用选择基于你需要实现的可视质量和你想要实现多大性能的纹理过滤来决定的。过滤模式使用glTexParameter[i|f][v]来指定。


放大过滤可以是GL_NEAREST 或 GL_LINEAR。在GL_NEAREST 放大过滤模式,纹理最近的单点将做纹理坐标。在GL_LINEAR 模式,双线性(四个点平均)作为纹理坐标。
缩小过滤可以是下列值:
•• GL_NEAREST—Takes a single point sample from the texture nearest to the texture coordinate.
•• GL_LINEAR—Takes a bilinear sample from the texture nearest to the texture coordinate.
•• GL_NEAREST_MIPMAP_NEAREST—Takes a single point sample from the closest mip level chosen.
•• GL_NEAREST_MIPMAP_LINEAR—Takes a sample from the two closest mip levels and interpolates between those samples.
•• GL_LINEAR_MIPMAP_NEAREST—Takes a bilinear fetch from the closest mip level chosen.
•• GL_LINEAR_MIPMAP_LINEAR—Takes a bilinear fetch from each of the two closest mip levels and then interpolates between them. This last mode, which is typically referred to as trilinear filtering, produces the best quality of all modes.
GL_NEAREST 和 GL_LINEAR 是唯一不需要完整多级纹理的缩小过滤模式,其他都需要完整的多级处理。

GL_NEAREST 和GL_LINEAR_MIPMAP_LINEAR的过滤设置。
值得一提的是一些性能将影响你选择的纹理过滤模式。对于大多数硬件来说,使用多级纹理是最好的选择。
Seamless Cubemap Filtering
它是3.0新特性。当一个线性过滤核心在一个立方体纹理的边框时,这个过滤只发生在线所在立方体的一面中。你不需要设置Seamless Cubemap Filtering,线性过滤会自动使用它。
自动多级纹理生成
前面我们已经创建了一个level为0的多级纹理,这是一种方法。另外也提供了自动多级纹理生成函数 glGenerateMipmap。

我们队绑定的纹理对象调用glGenerateMipmap,它会为我们生成从原始图像到level为0的多级纹理链。当你使用framebuffer对象时,自动多级纹理生成变得尤为重要。当渲染一个纹理时,我们不想将纹理读回CPU中生成多级纹理。glGenerateMipmap可以解决这个问题。
Texture Coordinate Wrapping
当纹理坐标超过了范围[0.0, 1.0] 时,使用纹理包装来实现。纹理包装模式使用glTexParameter[i|f][v]来指定。
纹理包装模式能被独立的设定为s坐标和t坐标。GL_TEXTURE_WRAP_S模式定义s 坐标超出范围[0.0, 1.0]的情况,GL_TEXTURE_WRAP_T 设定t 坐标超出范围[0.0, 1.0]的情况。有三种包装模式供选择

注意,纹理包装模式对过滤行为有影响。例如纹理坐标是边缘时,双线性过滤将扫描纹理的边缘。这时包装模式将决定哪个纹理是纹理边缘的外面而应用于过滤算法。如果你不想要任何形式的重复,应该使用GL_CLAMP_TO_EDGE。
下图是使用纹理绘制正方形在三种包装模式中的效果图

//
void Draw ( ESContext *esContext )
{
UserData *userData = esContext->userData;
GLfloat vVertices[] = { -0.3f, 0.3f, 0.0f, 1.0f, // Position 0
-1.0f, -1.0f, // TexCoord 0
-0.3f, -0.3f, 0.0f, 1.0f, // Position 1
-1.0f, 2.0f, // TexCoord 1
0.3f, -0.3f, 0.0f, 1.0f, // Position 2
2.0f, 2.0f, // TexCoord 2
0.3f, 0.3f, 0.0f, 1.0f, // Position 3
2.0f, -1.0f // TexCoord 3
};
GLushort indices[] = { , , , , , }; // Set the viewport
glViewport ( , , esContext->width, esContext->height ); // Clear the color buffer
glClear ( GL_COLOR_BUFFER_BIT ); // Use the program object
glUseProgram ( userData->programObject ); // Load the vertex position
glVertexAttribPointer ( , , GL_FLOAT,
GL_FALSE, * sizeof ( GLfloat ), vVertices );
// Load the texture coordinate
glVertexAttribPointer ( , , GL_FLOAT,
GL_FALSE, * sizeof ( GLfloat ), &vVertices[] ); glEnableVertexAttribArray ( );
glEnableVertexAttribArray ( ); // Bind the texture
glActiveTexture ( GL_TEXTURE0 );
glBindTexture ( GL_TEXTURE_2D, userData->textureId ); // Set the sampler texture unit to 0
glUniform1i ( userData->samplerLoc, ); // Draw quad with repeat wrap mode
glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
glUniform1f ( userData->offsetLoc, -0.7f );
glDrawElements ( GL_TRIANGLES, , GL_UNSIGNED_SHORT, indices ); // Draw quad with clamp to edge wrap mode
glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
glUniform1f ( userData->offsetLoc, 0.0f );
glDrawElements ( GL_TRIANGLES, , GL_UNSIGNED_SHORT, indices ); // Draw quad with mirrored repeat
glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT );
glTexParameteri ( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT );
glUniform1f ( userData->offsetLoc, 0.7f );
glDrawElements ( GL_TRIANGLES, , GL_UNSIGNED_SHORT, indices );
}
OpenGL ES 3.0之Texturing纹理详解(二)的更多相关文章
- OpenGL ES 3.0之Texturing纹理详解(一)
本文流程 1.Texturing基础 2.装载Texturing和mipmapping 3.纹理过滤和包装 4.Texture level-of-detail, swizzles, and depth ...
- 基于Cocos2d-x学习OpenGL ES 2.0之多纹理
没想到原文出了那么多错别字,实在对不起观众了.介绍opengl es 2.0的不多.相信介绍基于Cocos2d-x学习OpenGL ES 2.0之多纹理的,我是独此一家吧.~~ 子龙山人出了一个系列: ...
- Android OpenGL ES 3.0 纹理应用
本文主要演示OpenGL ES 3.0 纹理演示.接口大部分和2.0没什么区别,脚本稍微有了点变化而已. 扩展GLSurfaceView package com.example.gles300; im ...
- 基于Cocos2d-x学习OpenGL ES 2.0系列——纹理贴图(6)
在上一篇文章中,我们介绍了如何绘制一个立方体,里面涉及的知识点有VBO(Vertex Buffer Object).IBO(Index Buffer Object)和MVP(Modile-View-P ...
- 【Android 应用开发】OpenGL ES 2.0 -- 制作 3D 彩色旋转三角形 - 顶点着色器 片元着色器 使用详解
最近开始关注OpenGL ES 2.0 这是真正意义上的理解的第一个3D程序 , 从零开始学习 . 案例下载地址 : http://download.csdn.net/detail/han120201 ...
- OpenGL ES 3.0之Uniform详解
Uniform是变量类型的一种修饰符,是OpenGL ES 中被着色器中的常量值,使用存储各种着色器需要的数据,例如:转换矩阵.光照参数或者颜色. uniform 的空间被顶点着色器和片段着色器分享 ...
- OpenGL ES 2.0 -- 制作 3D 彩色旋转三角形 - 顶点着色器 片元着色器 使用详解
最近开始关注OpenGL ES 2.0 这是真正意义上的理解的第一个3D程序 , 从零开始学习 . 案例下载地址 : http://download.csdn.net/detail/han120201 ...
- 【AR实验室】OpenGL ES绘制相机(OpenGL ES 1.0版本)
0x00 - 前言 之前做一些移动端的AR应用以及目前看到的一些AR应用,基本上都是这样一个套路:手机背景显示现实场景,然后在该背景上进行图形学绘制.至于图形学绘制时,相机外参的解算使用的是V-SLA ...
- 在 OpenGL ES 2.0 上实现视差贴图(Parallax Mapping)
在 OpenGL ES 2.0 上实现视差贴图(Parallax Mapping) 视差贴图 最近一直在研究如何在我的 iPad 2(只支持 OpenGL ES 2.0, 不支持 3.0) 上实现 视 ...
随机推荐
- Go内置库模块 flag
import "flag" flag包实现了命令行参数的解析.每个参数认为一条记录,根据实际进行定义,到一个set集合.每条都有各自的状态参数. 在使用flag时正常流程: 1. ...
- Go - 反射中 函数 和 方法 的调用 - v.Call()
上一篇文章 说到了 Golang 中的反射的一些基本规则,重点就是文章中最后的三点,但是这篇文章并没有说如何在反射中调用函数和方法,这就是接下来要说的. 反射中调用 函数 众所周知,Golang 中的 ...
- [Winform]只允许运行一个exe,如果已运行则将窗口置前
摘要 接着介绍项目中用到的一些方法,在winform中,打好包,有时并不允许运行多个客户端,要保证只有一个客户端运行.如果已经运行了,则弹出已运行的窗口,使其展示. 方法 判断是否有相同的进程 /// ...
- Creating popup windows in XBAP applications
A colleague at DevelopMentor recently asked me about creating popup windows in XAML browser applicat ...
- WCF X.509证书双向认证小结
最近在学习WCF X.509证书验证,想实现使用证书实现服务端和客户端的双向认证,实现原理是利用了数字证书包含的一对非对称密钥来实现数字签名及加密.所谓非对称密钥是采用两个密钥将加密和解密能力分开:一 ...
- WordPress主题开发实例:根据不同分类使用不同模板
分类实现效果: 点击"产品"相关分类,显示 否则显示 创建文件: category.php cat-news.php cat-product.php 由于点击分类时wordpres ...
- WordPress主题开发:优化标题
页面使用: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF ...
- WordPress主题开发:加载脚本和样式
如果只引入style.css,我把这个放头顶就可以了 <link rel="stylesheet" href="<?php echo get_styleshe ...
- 深入理解Java并发之synchronized实现原理
深入理解Java类型信息(Class对象)与反射机制 深入理解Java枚举类型(enum) 深入理解Java注解类型(@Annotation) 深入理解Java类加载器(ClassLoader) 深入 ...
- 为何要对URL进行编码
为何要对URL进行编码 我们都知道Http协议中参数的传输是"key=value"这种简直对形式的,如果要传多个参数就需要用“&”符号对键值对进行分割.如"?na ...