OpenGL-ES 學習(15) ----紋理

目錄

      • 紋理簡介
      • 紋理映射
      • 紋理映射流程
      • 示例代碼:
      • 紋理的環繞和過濾方式
      • 紋理的過濾方式

紋理簡介

現實生活中,紋理(Texture) 類似于游戲中皮膚的概念,最通常的作用是裝飾 3D 物體,它像貼紙一樣貼在物體的表面,豐富物體的表面和細節
OpenGL-ES 開發中,紋理除了用于裝飾物體表面,還可以用來作為存儲數據的容器
所以在 OpenGL-ES 中,紋理實際上是一個可以被采樣的復雜數據集合,是 GPU 的圖像數據結構,紋理分為 2D紋理、立方圖紋理和 3D紋理

  • 2D 紋理是 OpenGL-ES 中最常見和最常用的紋理形式,是一個表示圖像數據的二維數組,紋理中一個單獨的數據單元被稱為紋素或者紋理像素
  • 立方圖紋理(CubeMap)是一個由6個單獨的 2D 紋理面組成的紋理,立方圖紋理像素的讀取是使用三維坐標(s, t, r)作為紋理坐標
  • 3D 紋理 可以看做 2D 紋理的集合,2D 紋理是 3D 紋理的一個切面,使用三維坐標對齊進行訪問

紋理映射

OpenGL-ES 中,紋理映射就是通過為圖元的頂點坐標指定恰當的紋理坐標,通過紋理坐標在紋理圖中選定特定范圍的紋理區域,最后通過紋理坐標和頂點的映射關系,將選定的紋理區域映射到指定的圖元上
紋理映射也稱為紋理貼圖,簡單說就是將紋理坐標所指定的紋理區域,映射到頂點坐標對應的渲染區域
紋理坐標是使用紋理坐標系
頂點坐標是使用渲染坐標系或者 OpenGL-ES 坐標系
紋理坐標映射.jpg
4個紋理坐標T0(0,0), T1(0,1), T2(1,1), T3(1,0) 對應的頂點坐標為V0(-1,0.5),V1(-1,-0.5),V2(1,-0.5),V3(1,0.5)
OpenGL-ES 的基本圖元是以三角形為單位的,設置繪制兩個三角形V0V1V2V0V2V3
當我們調整紋理坐標的順序保持頂點坐標的順序不變,T0T1T2T3 ==》T1T2T3T0 繪制后將會得到一個順時針旋轉 90 度為紋理貼圖,所以調整紋理坐標和頂點坐標的對應關系可以實現紋理貼圖的簡單旋轉
紋理坐標和紋理像素的映射關系如下:
紋理坐標和紋理像素.png

紋理坐標(0,0)對應紋理像素的第一個元素
紋理坐標(1,0)對應紋理像素的index = width - 1的元素
紋理坐標(0,1)對應紋理像素的index = width* (height - 1) 的元素
紋理坐標(1,1)對應紋理像素的index = width* height - 1 的元素
對應紋理像素區域內的元素都會被采樣

紋理映射流程

紋理映射的一般步驟:

  • 生成紋理,編譯鏈接著色器程序
  • 確定紋理坐標和對應的頂點坐標
  • 加載圖形數據到紋理,加載頂點坐標和紋理坐標到著色器程序
  • 開始繪制

軟件流程如下:
texture_rendering.jpg

對紋理采樣的 FragmentShader

"#version 300 es                                     \n"
"precision mediump float;                            \n"
"in vec2 v_texCoord;                                 \n"
"layout(location = 0) out vec4 outColor;             \n"
"uniform sampler2D s_texture;                        \n"
"void main()                                         \n"
"{                                                   \n"
"  outColor = texture( s_texture, v_texCoord );      \n"
"}      

其中 texture 是內置的采樣函數,v_texCoord 是頂點著色器傳入的紋理坐標,根據紋理坐標進行采樣,輸出為4向量的 RGBA 值
uniform sampler2D s_texture 是加載后的紋理內容

示例代碼:

typedef struct
{// Handle to a program objectGLuint programObject;// Sampler locationGLint samplerLoc;// Texture handleGLuint textureId;
} UserData;// load texture form tga file 
static GLuint CreateSimpleTexture2D()
{// Texture object handleGLuint textureId;// load texture from tga fileconst char* files = "./Huskey.tga";int width;int height;GLubyte* pixels = esLoadTGA(NULL, files, &width, &height);// Use tightly packed dataglPixelStorei(GL_UNPACK_ALIGNMENT, 1);// Generate a texture objectglGenTextures(1, &textureId);// Bind the texture objectglBindTexture(GL_TEXTURE_2D, textureId);// Load the texture notice width height  format must align with real sizeglTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, pixels);// Set the filtering modeglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);return textureId;
}///
// Initialize the shader and program object
//
static int Init(ESContext *esContext) {UserData *userData = esContext->userData;char vShaderStr[] ="#version 300 es                            \n""layout(location = 0) in vec4 a_position;   \n""layout(location = 1) in vec2 a_texCoord;   \n""out vec2 v_texCoord;                       \n""void main()                                \n""{                                          \n""   gl_Position = a_position;               \n""   v_texCoord = a_texCoord;                \n""}                                          \n";char fShaderStr[] ="#version 300 es                                     \n""precision mediump float;                            \n""in vec2 v_texCoord;                                 \n""layout(location = 0) out vec4 outColor;             \n""uniform sampler2D s_texture;                        \n""void main()                                         \n""{                                                   \n"
//使用內建函數在Fragmanet Shader 中進行紋理采樣"  outColor = texture( s_texture, v_texCoord );      \n""}                                                   \n";// Load the shaders and get a linked program objectuserData->programObject = esLoadProgram(vShaderStr, fShaderStr);// Get the sampler locationuserData->samplerLoc = glGetUniformLocation(userData->programObject, "s_texture");// Load the textureuserData->textureId = CreateSimpleTexture2D();glClearColor(1.0f, 1.0f, 1.0f, 0.0f);return TRUE;
}///
// Draw a triangle using the shader pair created in Init()
//
static void Draw(ESContext *esContext)
{UserData *userData = esContext->userData;GLfloat vVertices[] = { -0.5f,  0.5f, 0.0f,  // Position 00.0f,  0.0f,        // TexCoord 0 -0.5f, -0.5f, 0.0f,  // Position 10.0f,  1.0f,        // TexCoord 10.5f, -0.5f, 0.0f,  // Position 21.0f,  1.0f,        // TexCoord 20.5f,  0.5f, 0.0f,  // Position 31.0f,  0.0f         // TexCoord 3};GLushort indices[] = { 0, 1, 2, 0, 2, 3 };// Set the viewportglViewport(0, 0, esContext->width, esContext->height);// Clear the color bufferglClear(GL_COLOR_BUFFER_BIT);// Use the program objectglUseProgram(userData->programObject);// Load the vertex positionglVertexAttribPointer(0, 3, GL_FLOAT,GL_FALSE, 5 * sizeof(GLfloat), vVertices);// Load the texture coordinateglVertexAttribPointer(1, 2, GL_FLOAT,GL_FALSE, 5 * sizeof(GLfloat), &vVertices[3]);glEnableVertexAttribArray(0);glEnableVertexAttribArray(1);// Bind the textureglActiveTexture(GL_TEXTURE0);glBindTexture(GL_TEXTURE_2D, userData->textureId);// Set the sampler texture unit to 0glUniform1i(userData->samplerLoc, 0);glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);
}

注意其中的glTexImage2D是用于加載紋理的函數:
void glTexImage2D( GLenum target,GLint level,GLint internalFormat,GLsizei width,GLsizei height,GLint border,
GLenum format,GLenum type,const void * data);

  • GLenum target : 指定texture 類型,一般為 GL_TEXTURE_2D
  • GLint level : 一般設置為0
  • GLint internalFormat : 設置紋理的存儲格式 GL_RGB
  • GLsizei width : texture 的寬度
  • GLsizei height : texture 的高度
  • GLint border : 一般設置為0
  • GLenum format : 設置紋理輸入圖片的存儲格式 GL_RGB
  • GLenum type : 設置紋理輸入圖片的存儲格式 GL_RGB
  • const void * data : 指向加載為紋理內容的圖片的指針

實際顯示效果:
texture_result.jpg

紋理的環繞和過濾方式

紋理坐標的范圍通常是從(0, 0) 到 (1, 1),如果設置的坐標超出這個范圍,就會有重復的效果,比如 紋理的 S 坐標設置到 2,就表示 S 軸上要重復兩次采樣紋理,如果 將T 坐標設置為 2,表示 T 軸上重復兩次采樣紋理,通過設置不同的紋理坐標,就可以產生不同的重復的效果,紋理的環繞方式也可以設置,可以設置的類型如下:
紋理環繞方式.jpg

GL_REPEAT.jpg

GL_MIRRORED_REPEAT.jpg
GL_CLAMP_TO_EDGE.jpg

設置的代碼如下:

// GL_REPEAT  GL_CLAMP_TO_EDGE  GL_MIRRORED_REPEAT
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

紋理的過濾方式

紋理映射的原理是:光柵化之后,圖元轉換為一個個光柵,每個光柵化之后的 pixel 都會經過 PixelShaderPixelShader 中從紋理采樣得到每個 pixel 的顏色,這里就會涉及采樣方式的問題,如果圖元的分辨率很大,但是關聯到圖元的紋理很小,就需要進行插值,紋理的過濾方式實際就是紋理到光柵的插值算法
現在只討論最重要的兩種:GL_NEARESTGL_LINEAR

  • GL_NEAREST(也叫鄰近過濾,Nearest Neighbor Filtering)是 OpenGL 默認的紋理過濾方式。當設置為 GL_NEAREST 的時候,OpenGL 會選擇中心點最接近紋理坐標的那個像素,原理是最近鄰插值算法

  • GL_LINEAR(也叫線性過濾,(Bilinear Filtering)它會基于紋理坐標附近的四個紋理像素的值,計算出一個插值,原理是雙線性插值算法

鄰近過濾算法簡單,但是在放大圖像的時候,會有嚴重的馬賽克,線性過濾計算過程復雜,但是效果比鄰近過濾算法好
GL_NEAREST.jpg

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/79211.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/79211.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/79211.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

OpenCV計算機視覺實戰(2)——環境搭建與OpenCV簡介

OpenCV計算機視覺實戰(2)——環境搭建與OpenCV簡介 0. 前言1. OpenCV 安裝與配置1.1 安裝 Python-OpenCV1.2 配置開發環境 2. OpenCV 基礎2.1 圖像讀取與顯示2.2 圖像保存 3. 攝像頭實時捕獲小結系列鏈接 0. 前言 OpenCV (Open Source Computer Vision …

ubuntu22.04安裝顯卡驅動與cuda+cuDNN

背景: 緊接前文:Proxmox VE 8.4 顯卡直通完整指南:NVIDIA 2080 Ti 實戰。在R740服務器完成了proxmox的安裝,并且安裝了一張2080ti 魔改22g顯存的的顯卡。配置完了proxmox顯卡直通,并將顯卡掛載到了vm 301(…

A2A Python 教程 - 綜合指南

目錄 ? 介紹? 設置環境? 創建項目? 代理技能? 代理卡片? A2A服務器? 與A2A服務器交互? 添加代理功能? 使用本地Ollama模型? 后續步驟 介紹 在本教程中,您將使用Python構建一個簡單的echo A2A服務器。這個基礎實現將向您展示A2A提供的所有功能。完成本教…

MySQL基礎關鍵_005_DQL(四)

目 錄 一、分組函數 1.說明 2.max/min 3.sum/avg/count 二、分組查詢 1.說明 2.實例 (1)查詢崗位和平均薪資 (2)查詢每個部門編號的不同崗位的最低薪資 3.having (1)說明 (2&#xff…

GAMES202-高質量實時渲染(Assignment 2)

目錄 作業介紹環境光貼圖預計算傳輸項的預計算Diffuse unshadowedDiffuse shadowedDiffuse Inter-reflection(bonus) 實時球諧光照計算 GitHub主頁:https://github.com/sdpyy1 作業實現:https://github.com/sdpyy1/CppLearn/tree/main/games202 作業介紹 物體在不同…

2025年- H21-Lc129-160. 相交鏈表(鏈表)---java版

1.題目描述 2.思路 當pa!pb的時候,執行pa不為空,遍歷pa鏈表。執行pb不為空,遍歷pb鏈表。 3.代碼實現 // 單鏈表節點定義 class ListNode {int val;ListNode next;ListNode(int x){valx;nextnull;}}public class H160 {// 主方法…

win10系統安卓開發環境搭建

一 安裝jdk 下載jdk17 ,下載路徑:https://download.oracle.com/java/17/archive/jdk-17.0.12_windows-x64_bin.exe 下載完畢后,按照提示一步步完成,然后接著創建環境變量, 在cmd控制臺輸入java -version 驗證: 有上面的輸出代表jdk安裝并配置成功。 二 安裝Android stu…

【算法基礎】選擇排序算法 - JAVA

一、算法基礎 1.1 什么是選擇排序 選擇排序是一種簡單直觀的排序算法,它的工作原理是:首先在未排序序列中找到最小(或最大)元素,存放到排序序列的起始位置,然后再從剩余未排序元素中繼續尋找最小&#xf…

LabVIEW異步調用VI介紹

在 LabVIEW 編程環境里,借助結合異步 VI 調用,并使用 “Open VI Reference” 函數上的 “Enable simultaneous calls on reentrant VIs” 選項(0x40),達成了對多個 VI 調用執行效率的優化。以下將從多方面詳細介紹該 V…

Leetcode刷題 | Day50_圖論02_島嶼問題01_dfs兩種方法+bfs一種方法

一、學習任務 99. 島嶼數量_深搜dfs代碼隨想錄99. 島嶼數量_廣搜bfs100. 島嶼的最大面積101. 孤島的總面積 第一類DFS(主函數中處理第一個節點,DFS處理相連節點): 主函數中先將起始節點標記為已訪問DFS函數中不處理起始節點&…

深入理解網絡安全中的加密技術

1 引言 在當今數字化的世界中,網絡安全已經成為個人隱私保護、企業數據安全乃至國家安全的重要組成部分。隨著網絡攻擊的復雜性和頻率不斷增加,保護敏感信息不被未授權訪問變得尤為關鍵。加密技術作為保障信息安全的核心手段,通過將信息轉換為…

舊版本NotionNext圖片失效最小改動解決思路

舊版本NotionNext圖片失效最小改動解決思路 契機 好久沒寫博客了,最近在notion寫博客的時候發現用notionNext同步到個人網站時,圖片無法預覽。猜測是notion加了防盜鏈措施,去notionNext官方github上尋找解決方案,需要升級到4.8.…

深度學習筆記40_中文文本分類-Pytorch實現

🍨 本文為🔗365天深度學習訓練營 中的學習記錄博客🍖 原作者:K同學啊 | 接輔導、項目定制 一、我的環境 1.語言環境:Python 3.8 2.編譯器:Pycharm 3.深度學習環境: torch1.12.1cu113torchvision…

010302-oss_反向代理_負載均衡-web擴展2-基礎入門-網絡安全

文章目錄 1 OSS1.1 什么是 OSS 存儲?1.2 OSS 核心功能1.3 OSS 的優勢1.4 典型使用場景1.5 如何接入 OSS?1.6 注意事項1.7 cloudreve實戰演示1.7.1 配置cloudreve連接阿里云oss1.7.2 常見錯誤1.7.3 安全測試影響 2 反向代理2.1 正向代理和反向代理2.2 演示…

【 Node.js】 Node.js安裝

下載 下載 | Node.js 中文網https://nodejs.cn/download/ 安裝 雙擊安裝包 點擊Next 勾選使用許可協議,點擊Next 選擇安裝位置 點擊Next 點擊Next 點擊Install 點擊Finish 完成安裝 添加環境變量 編輯【系統變量】下的變量【Path】添加Node.js的安裝路徑--如果…

Python基本語法(自定義函數)

自定義函數 Python語言沒有子程序,只有自定義函數,目的是方便我們重復使用相同的一 段程序。將常用的代碼塊定義為一個函數,以后想實現相同的操作時,只要調用函數名就可以了,而不需要重復輸入所有的語句。 函數的定義…

OpenGL-ES 學習(11) ---- EGL

目錄 EGL 介紹EGL 類型和初始化EGL初始化方法獲取 eglDisplay初始化 EGL選擇 Config構造 Surface構造 Context開始繪制 EGL Demo EGL 介紹 OpenGL-ES 是一個操作GPU的圖像API標準,它通過驅動向 GPU 發送相關圖形指令,控制圖形渲染管線狀態機的運行狀態&…

極簡5G專網解決方案

極簡5G專網解決方案 利用便攜式即插即用私有 5G 網絡提升您的智能創新。為您的企業提供無縫、安全且可擴展的 5G 解決方案。 提供極簡5G專網解決方案 Mantiswave Network Private Limited 提供全面的 5G 專用網絡解決方案,以滿足您企業的獨特需求。我們創新的“…

html:table表格

表格代碼示例&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title> </head> <body><!-- 標準表格。 --><table border"5"cellspacing&qu…