從零開始OpenGL ES(四) 繪製紋理 圖片
理論
首先是兩個座標系
假如現在有一張圖片,是通過紋理座標系繪製出來的,圖片的左上角(0,0),左下角(0,1),
那麼我需要把紋理座標系和頂點座標系對齊, 那麼要把紋理座標系中(0,0)這個點,放到頂點座標系中的(-1,0)這個點.
相應的要把紋理座標系的(0,1)這個點,放到頂點座標系中(-1,-1)這個點. 後面以此類推
具體做法: 先把OpenGL 需要展示的區域畫出來(就是整個螢幕),再按照上面的做法 把紋理座標系貼到頂點座標系中.
頂點Shader
vertex_shader.glsl
attribute vec4 av_Position; attribute vec2 af_Position; varying vec2 v_texPo; void main() { v_texPo = af_Position; gl_Position = av_Position; }
注: attribute 只能在vertex中使用
varying 用於vertex和fragment之間傳遞值
- attribute vec4 av_Position; 這個是之前寫過的 頂點座標系
- attribute vec2 af_Position; 這個是紋理座標系 vec2 圖片是2d的 就用兩個向量x,y
- varying vec2 v_texPo; 在頂點座標和片元座標之間傳遞資料 v_texPo 這個值需要在頂點座標和片源座標的檔案中定義一直.
片元Shader
fragment_shader.glsl
precision mediump float; varying vec2 v_texPo; uniform sampler2D sTexture; void main() { gl_FragColor=texture2D(sTexture, v_texPo); }
注: uniform 用於在application中向vertex和fragment中傳遞值。
- precision mediump float; 精度
- varying vec2 v_texPo; 從頂點Shader 獲取到的值
- uniform sampler2D sTexture; 紋理的屬性 因為是在片元裡面 所以用uniform修飾 傳值
- texture2D 把顏色取出來的方法 這裡實際上就是做的兩個座標的轉換
繪製紋理過程
1、載入shader和生成program過程不變
2、建立和繫結紋理:
GLES20.glGenTextures(1, textureId, 0); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureid);
glGenTextures 就是建立紋理 引數.1 是建立多少個紋理 texturId 是個整形的陣列. 0 是從0開始
glBindTexture 繫結紋理 把生成的textrueId 生成的紋理繫結到GL_TEXTURE_2D 上
3、設定環繞和過濾方式
環繞(超出紋理座標範圍):
(s == x t == y GL_REPEAT 重複)
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_REPEAT);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_REPEAT);
過濾(紋理畫素對映到座標點):(縮小、放大:GL_LINEAR線性)
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
4、設定圖片
(bitmap)
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);
5、繫結頂點座標和紋理座標
6、繪製圖形
程式碼
按照前面文章
繪製四邊形 實際上的點 按照 v1 v2 v3 v4 繪製
在頂點座標系中就是
//頂點座標
private final float[] vertexData={
-1f,-1f,
1f,-1f,
-1f,1f,
1f,1f
};
但是紋理座標系和頂點座標系不一樣 需要對應起來所以紋理座標系是
//紋理座標
private final float[] textureData={
0f,1f,
1f,1f,
0f,0f,
0f,1f
};
其他程式碼:
package com.xyyy.www.opengldemo;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLES20;
import android.opengl.GLSurfaceView;
import android.opengl.GLUtils;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
/**
* @author liuml
* @explain 渲染圖片
* @time 2018/11/15 11:19
*/
public class XYRenderImage implements GLSurfaceView.Renderer {
private Context context;
//頂點座標
private final float[] vertexData={
-1f,-1f,
1f,-1f,
-1f,1f,
1f,1f
};
//紋理座標 正常
// private final float[] textureData={
// 0f,1f,
// 1f,1f,
// 0f,0f,
// 1f,0f
// };
//紋理座標 倒立
private final float[] textureData={
1f,0f,
0f,0f,
1f, 1f,
0f, 1f
};
private FloatBuffer vertexBuffer;//頂點buffer
private FloatBuffer textureBuffer;//紋理buffer
private int program;
private int avPosition;//頂點座標
private int afPosition;//紋理座標
private int textureId;//紋理id儲存
// private int afColor;
public XYRenderImage(Context context){
this.context = context;
vertexBuffer = ByteBuffer.allocateDirect(vertexData.length * 4)
.order(ByteOrder.nativeOrder())
.asFloatBuffer()
.put(vertexData);
vertexBuffer.position(0);
textureBuffer = ByteBuffer.allocateDirect(textureData.length * 4)
.order(ByteOrder.nativeOrder())
.asFloatBuffer()
.put(textureData);
textureBuffer.position(0);
}
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
String vertexSource = XYShaderUtil.readRawText(context, R.raw.img_vertex_shader);
String fragmentSource = XYShaderUtil.readRawText(context, R.raw.img_fragment_shader);
program = XYShaderUtil.createProgram(vertexSource, fragmentSource);
if (program > 0) {
avPosition = GLES20.glGetAttribLocation(program, "av_Position");
afPosition = GLES20.glGetAttribLocation(program, "af_Position");
//建立紋理
int[] textureIds = new int[1];
GLES20.glGenTextures(1, textureIds, 0);
if (textureIds[0] == 0) {
return;
}
textureId = textureIds[0];
//繫結
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureId);
//設定引數 環繞(超出紋理座標範圍):
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_REPEAT);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_REPEAT);
//過濾(紋理畫素對映到座標點
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
// BitmapFactory.Options options = new BitmapFactory.Options();
// options.inScaled = false;
Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), R.mipmap.test);
if (bitmap == null) {
return;
}
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);
bitmap.recycle();
bitmap = null;
}
}
@Override
public void onSurfaceChanged(GL10 gl, int width,int height) {
//繪製區域
GLES20.glViewport(0,0,width,height);
}
@Override
public void onDrawFrame(GL10 gl) {
//清屏緩衝區
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
//利用顏色清屏
GLES20.glClearColor(1.0f,1.0f,1.0f,1.0f);
//讓program可用
GLES20.glUseProgram(program);
//頂點座標
GLES20.glEnableVertexAttribArray(avPosition);
GLES20.glVertexAttribPointer(avPosition, 2, GLES20.GL_FLOAT, false, 8, vertexBuffer);
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
//紋理座標
GLES20.glEnableVertexAttribArray(afPosition);
GLES20.glVertexAttribPointer(afPosition, 2, GLES20.GL_FLOAT, false, 8, textureBuffer);
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
}
}
效果:
相關推薦
從零開始OpenGL ES(四) 繪製紋理 圖片
理論 首先是兩個座標系 假如現在有一張圖片,是通過紋理座標系繪製出來的,圖片的左上角(0,0),左下角(0,1), 那麼我需要把紋理座標系和頂點座標系對齊, 那麼要把紋理座標系中(0,0)這個點,放到頂點座標系中的(-1,0)這個點. 相應的要把紋理座標系的
從零開始OpenGL ES(三) 繪製四邊形
原理 現在要實現用OpenGLES 實現四邊形. 一個四邊形是可以由兩個三角形構成 那麼我畫兩個相連的三角形來實現一個四邊形. 如圖 有個規定.:圖形環繞方向必須一致,要麼全是順時針 要麼全是逆時針 1、GL_TRIANGLES: v1, v2, v3, v3, v
從零開始openGL—— 二、 基本圖形繪製
前言 這是從零開始openGL系列文章的第二篇,在上篇文章中介紹了基本的環境配置,這篇文章將介紹如何繪製基本圖形(圓、三角形、立方體、圓柱、圓錐)。 基本框架 下面這裡我先給出opengl的3D繪圖的基本框架 #include <windows.h> #include <string.h&
PowerShell學習小結——PowerShell從零開始系列之四
PowerShell能堅持看到這裏的同學,相信對PowerShell的命令使用應該不陌生,由於後面的內容較為繁雜,所以必須要熟悉PowerShell命令這裏準備了一些基礎的題目,有興趣的一定要動手操作一下:如何查看wuauserv服務運行狀態如何停止wuauserv服務如何查看explorer進程有服務器條件
從零開始學習jQuery (四) 使用jQuery操作元素的屬性與樣式
本系列文章導航 一.摘要 本篇文章講解如何使用jQuery獲取和操作元素的屬性和CSS樣式. 其中DOM屬性和元素屬性的區分值得大家學習. 二.前言 通過前面幾章我們已經能夠完全控制jQuery包裝集了, 無論是通過選擇器選取物件,
【Kettle從零開始】第四彈之Kettle轉換資料抽取使用
Kettle版本:3.2GA JDK版本:1.6.0_41 OS:NT 需求:需要把業務系統庫、TXT檔案、EXCEL檔案中的資料抽取到資料倉庫中。 1、 建立轉換(Ctrl+N),轉換名稱為:R
從零開始學習jQuery (四)
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.
從零開始學Python(四):變數與基本資料型別
上一章我們簡單的瞭解了一下python的程式碼縮排,基礎的輸出語句,多行語句和單行多行註釋,今天我們來了解下python的變數與基本資料型別,讓我們在以後的程式設計中,對各種型別瞭如指掌! 變數的賦值 為了方便給下面各種資料型別做詳解,我們首先學習一下變
【工作筆記】從零開始學ExtJs6( 四)—— 首頁樹狀選單和Tab頁的實現
題外話 做一個專案要向完成對應的模組,肯定是先要有樹形選單結構,點選對應才dna跳轉到相應介面,在extjs中如何實現。是上週遇到的一個小問題,現在做做記錄 app目錄下建立data/me
從零開始openGL——三、模型載入及滑鼠互動實現
前言 在上篇文章中,介紹了基本圖形的繪製。這篇部落格中將介紹模型的載入、繪製以及滑鼠互動的實現。 模型載入 模型儲存 要實現模型的讀取、繪製,我們首先需要知道模型是如何儲存在檔案中的。 通常模型是由網格組成的,且一般為三角網格。原因為: 其它多邊形網格可以容易地剖分為三角形 三點共面:保證平面性
從零開始openGL——五、光線追蹤
前言 前面介紹了基本圖形、模型、曲線的繪製,但是,在好像還沒有感受到那種3D遊戲裡一些能驚豔到自己的效果,即真實感還不是很足。這篇文章中介紹的光線追蹤,是實現真實感必不可少的。拿下面的兩張圖片來對比 對比一下是不是被下面這張圖片的效果驚豔到了?可以很明顯感覺到,下面的這個圖片效果要好的多。這篇部落格將
從零開始的openGL——四、紋理貼圖與n次B樣條曲線
前言 在上篇文章中,介紹瞭如何載入繪製模型以及滑鼠互動的實現,並且遺留了個問題,就是沒有模型表面沒有紋理,看起來很醜。這篇文章將介紹如何貼紋理,以及曲線的繪製。 紋理貼圖 紋理載入 既然是貼圖,那首先我們得要有合適的紋理圖片,openGL中支援的圖片為bmp格式。在這裡我還用到了個額外的庫glaux,但當時在
android平臺下OpenGL ES 3.0從零開始
OpenGL ES 3.0學習實踐 android平臺下OpenGL ES 3.0從零開始 android平臺下OpenGL ES 3.0繪製純色背景 android平臺下OpenGL ES 3.0繪製圓點、直線和三角形 android平臺下OpenGL E
從零開始之OpenGL ES 2.0【1】
這一節主要內容是矩陣的使用,投影和相機相關知識。一、矩陣相關 由於OpenGL ES使用的是列向量,所以向量與矩陣計算方式為 矩陣乘向量;在DirectX中使用的是行向量計算方式為 向量乘矩陣。二、投影相關 在OpenGL ES中投影方式有兩種,分
OpenGL ES 從零開始系列9:動畫基礎和關鍵幀動畫
Creating a Rotation Matrix from a Quaternion 從一個四元數中建立旋轉矩陣 這另外的一個方法相對簡單些。並且這個基本演算法來自於Matrix FAQ,雖然我需要把它轉換成行優先的順序。 static inline void Matrix3DSetUsingQuater
從零開始學android<Bitmap圖形組件.四十七.>
alt getheight drawtext layout pla cin mas 簡單 制圖 android.graphics.Bitmap(位圖)是Android手機中專門提供的用於操作圖片資源的操作類,使用此類能夠直接從資源文件之中進行圖片資源的讀取。而且對這些圖
從零開始學習html(十四)單位和值
type 當我 總結 學生 專註 bfc span blog 設置顏色 一、顏色值 1 <!DOCTYPE HTML> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5
從零開始的linux 第四章
cd命令詳解 linux文件類型 pwd命令從零開始的linux 第四章哈嘍~~小編又回來啦~~(被同學們接住後扔進了水裏....)QAQ...你們怎麽能這麽對待小編...(啪..崩..咚..劈..咚..啪..)(鼻青臉腫的小編)額...同學們看起來精神不錯,早起活動活動筋骨對身體有好處....好啦,
從零開始學習前端JAVASCRIPT — 11、JavaScript基礎this指向的四種情況
事件 箭頭 註意 idt 轉移 如果 箭頭函數 javascrip function JavaScript中this的四種情況(非嚴格模式) 1、當this所在函數是事件處理函數時,this指向事件源。2、當this所在函數是構造函數時,this指向new出來的
從零開始學 Web 之 DOM(四)節點
def clas scrip while p標簽 設置 ner 操作 text 大家好,這裏是「 Daotin的夢囈 」從零開始學 Web 系列教程。此文首發於「 Daotin的夢囈 」公眾號,歡迎大家訂閱關註。在這裏我會從 Web 前端零基礎開始,一步步學習 Web 相