国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語(yǔ)言|JavaScript|易語(yǔ)言|vb.net|

服務(wù)器之家 - 編程語(yǔ)言 - Android - OpenGL ES紋理詳解

OpenGL ES紋理詳解

2022-02-25 15:14weiers Android

這篇文章主要為大家詳細(xì)介紹了OpenGL ES紋理的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

使用前面學(xué)過(guò)的技術(shù)已經(jīng)可以利用OpenGL ES構(gòu)建立體圖形,并通過(guò)頂點(diǎn)著色器和片元著色器對(duì)其進(jìn)行各種變化呢和光照等效果使得三維效果更加真實(shí),實(shí)際上我看看到很多的3D游戲漂亮多了,那是因?yàn)橛懈鞣N各樣的漂亮的圖像帶給人很多視覺盛宴,這篇文章在前面的基礎(chǔ)上,增加物體的表面貼圖,使得物體更加好看。

紋理概念

紋理用來(lái)表示圖像照片或者說(shuō)一系列的數(shù)據(jù),使用紋理可以使物體用用更多的細(xì)節(jié)。OpenGL ES 2.0 中有兩種貼圖:二維紋理和立方體紋理。

每個(gè)二維紋理都由許多小的紋理元素組成,類似與片元和像素,使用紋理最簡(jiǎn)單的方式就是直接從一個(gè)圖像加載數(shù)據(jù)。在OpenGL中規(guī)定紋理圖像的左下角由stst坐標(biāo)(0.0,0.0)指定,右上角由stst坐標(biāo)(1.0,1.0)指定,不過(guò)超過(guò)1.0的坐標(biāo)也是允許的,在該區(qū)間之外的紋理在讀取時(shí)的時(shí)候由紋理拉伸模式?jīng)Q定。

OpenGL ES 2.0不必是正方形,但是每個(gè)維度都應(yīng)該是2的冪

在Android中使用的OpenGL ES的紋理坐標(biāo)系跟官方的紋理坐標(biāo)系統(tǒng)不一樣,在Android中使用官方的紋理坐標(biāo)系統(tǒng),得到的結(jié)果是相反的,而是左上角是stst坐標(biāo)(0.0,0.0)點(diǎn),右下角是stst坐標(biāo)(1.0,1.0)點(diǎn)。

二維紋理映射的原理

OpenGL ES紋理詳解

使用紋理就是在紋理圖中進(jìn)行采樣,因此需要將選定的紋理坐標(biāo)穿進(jìn)頂點(diǎn)著色器,經(jīng)過(guò)插值在片元著色器中從紋理圖中的指定位置采樣即可,紋理圖的數(shù)據(jù)通過(guò)往片元插值器傳遞紋理單元指定的。

紋理對(duì)象和紋理加載

創(chuàng)建一個(gè)紋理對(duì)象,保存渲染所需的紋理數(shù)據(jù),例如圖像數(shù)據(jù)、過(guò)濾模式、包裝模式。創(chuàng)建生成紋理對(duì)象的函數(shù)

?
1
2
3
4
5
public static native void glGenTextures(
    int n, // 指定要生成的紋理對(duì)象的數(shù)量
    int[] textures, // 保存紋理對(duì)象ID的數(shù)組
    int offset
  );

紋理對(duì)象在應(yīng)用程序中不再使用時(shí),需要?jiǎng)h除。

?
1
2
3
4
5
public static native void glDeleteTextures(
    int n, // 指定要?jiǎng)h除的紋理數(shù)量
    int[] textures, // 保存待刪除的紋理ID的數(shù)組
    int offset
  );

紋理對(duì)象的 ID 必須是 glGenTextures 產(chǎn)生的,一旦生成紋理ID,就必須綁定紋理對(duì)象才能繼續(xù)進(jìn)行后續(xù)的操作。后續(xù)的操作將影響綁定的紋理對(duì)象。一旦紋理被綁定到一個(gè)特定的紋理目標(biāo),再刪除之前就一直保持著綁定狀態(tài)。

?
1
2
3
4
public static native void glBindTexture(
    int target, // 綁定紋理對(duì)象到目標(biāo) GL_TEXTURE_2D 或 GL_TEXTURE_CUBE_MAP
    int texture // 要綁定的紋理對(duì)象ID
  );

激活某個(gè)紋理單元

?
1
2
3
public static native void glActiveTexture(
    int texture // 要激活的紋理單元
  );

對(duì)這兩個(gè)函數(shù)的理解:顯卡中有N個(gè)紋理單元(GL_TEXTURE0,GL_TEXTURE1,GL_TEXTURE2…),每個(gè)紋理單元中保存著很多紋理目標(biāo)(targetTexture1D,targetTexture2D,targetTexture3D,targetTextureCube…),OpenGL ES 2.0貌似只支持了targetTexture2D和targetTextureCube。

紋理單元TextureUnit的定義如下

?
1
2
3
4
5
6
7
8
struct TextureUnit
{
  GLuint targetTexture1D;
  GLuint targetTexture2D;
  GLuint targetTexture3D;
  GLuint targetTextureCube;
  ...
};

glActiveTexture函數(shù)就是設(shè)置當(dāng)前活動(dòng)的紋理單元

?
1
2
3
4
5
6
7
TextureUnit textureUnits[GL_MAX_TEXTURE_IMAGE_UNITS]
GLuint currentTextureUnit = 0;
// ...
void glActiveTexture(GLenum textureUnit)
{
  currentTextureUnit = textureUnit - GL_TEXTURE0 ;
}

glBindTexture函數(shù)就是將紋理對(duì)象ID賦值給當(dāng)前活動(dòng)的紋理單元的對(duì)應(yīng)的目標(biāo)紋理。

?
1
2
3
4
5
6
7
8
9
10
11
void glBindTexture(GLenum textureTarget, GLuint textureObject)
{
  TextureUnit *texUnit = &textureUnits[currentTextureUnit];
  switch(textureTarget)
  {
  case GL_TEXTURE_1D: texUnit->targetTexture1D = textureObject; break;
  case GL_TEXTURE_2D: texUnit->targetTexture2D = textureObject; break;
  case GL_TEXTURE_3D: texUnit->targetTexture3D = textureObject; break;
  case GL_TEXTURE_CUBEMAP: texUnit->targetTextureCube = textureObject; break;
  }
}

獲取一副圖片的紋理數(shù)據(jù)

?
1
2
3
4
5
public static void texImage2D(int target, // 常數(shù)GL_TEXTURE_2D
               int level, // 表示多級(jí)分辨率的紋理圖像的級(jí)數(shù),若只有一種分辨率,則level設(shè)為0。
               Bitmap bitmap,
               int border // 邊框,一般設(shè)為0
               )

其他紋理選項(xiàng)的設(shè)置使用glTexParameterf系列函數(shù)

?
1
2
3
4
5
public static native void glTexParameterf(
    int target,
    int pname, // 設(shè)定的參數(shù),可以是GL_TEXTURE_MAG_FILTER,GL_TEXTURE_MIN_FILTER,GL_TEXTURE_WRAP_S,GL_TEXTURE_WRAP_T
    float param // 參數(shù)對(duì)應(yīng)的值
  );

應(yīng)用紋理的例子

對(duì)前面的立方體的每個(gè)面應(yīng)用一張圖片作為紋理貼圖,效果圖(這個(gè)紋理圖是哪個(gè)老師來(lái)著?)

OpenGL ES紋理詳解

Rectangle.java

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
public class Rectangle {
  private FloatBuffer mVertexBuffer;
  private int mProgram;
  private int mPositionHandle;
  private int muMVPMatrixHandle;
  private int mColorHandle;
  private int muMMatrixHandle;
  private int muLightLocationHandle;
  private int mTextureCoordHandle;
  private int textureId;
  private int muTextureHandle;
 
  private Context mContext;
  public Rectangle(Context context) {
    this.mContext = context;
    initVetexData();
  }
 
  public void initVetexData() {
    float vertices[] = new float[] {
        // 頂點(diǎn)  顏色   紋理坐標(biāo)
        //前面
        0, 0, 1, 1,1,1,0, 0.5f, 0.5f,
        1, 1, 1, 1,0,0,0, 1.0f, 0.0f,
        -1, 1, 1, 1,0,0,0, 0.0f, 0.0f,
        0, 0, 1, 1,1,1,0, 0.5f, 0.5f,
        -1, 1, 1, 1,0,0,0, 0.0f, 0.0f,
        -1,-1, 1, 1,0,0,0, 0.0f, 1.0f,
        0, 0, 1, 1,1,1,0, 0.5f, 0.5f,
        -1,-1, 1, 1,0,0,0, 0.0f, 1.0f,
        1,-1, 1, 1,0,0,0, 1.0f, 1.0f,
        0, 0, 1, 1,1,1,0, 0.5f, 0.5f,
        1,-1, 1, 1,0,0,0, 1.0f, 1.0f,
        1, 1, 1, 1,0,0,0, 1.0f, 0.0f,
        //后面
        0, 0,-1, 1,1,1,0, 0.5f, 0.5f,
        1, 1,-1, 1,0,0,0, 1.0f, 0.0f,
        1,-1,-1, 1,0,0,00.0f, 0.0f,
        0, 0,-1, 1,1,1,0, 0.5f, 0.5f,
        1,-1,-1, 1,0,0,00.0f, 0.0f,
        -1,-1,-1, 1,0,0,0, 0.0f, 1.0f,
        0, 0,-1, 1,1,1,0, 0.5f, 0.5f,
        -1,-1,-1, 1,0,0,0, 0.0f, 1.0f,
        -1, 1,-1, 1,0,0,0, 1.0f, 1.0f,
        0, 0,-1, 1,1,1,0, 0.5f, 0.5f,
        -1, 1,-1, 1,0,0,0, 1.0f, 1.0f,
        1, 1,-1, 1,0,0,0, 1.0f, 0.0f,
        //左面
        -1, 0, 0, 1,1,1,0, 0.5f, 0.5f,
        -1, 1, 1, 1,0,0,0, 1.0f, 0.0f,
        -1, 1,-1, 1,0,0,0, 0.0f, 0.0f,
        -1, 0, 0, 1,1,1,0, 0.5f, 0.5f,
        -1, 1,-1, 1,0,0,0, 0.0f, 0.0f,
        -1,-1,-1, 1,0,0,0, 0.0f, 1.0f,
        -1, 0, 0, 1,1,1,0, 0.5f, 0.5f,
        -1,-1,-1, 1,0,0,0, 0.0f, 1.0f,
        -1,-1, 1, 1,0,0,0, 1.0f, 1.0f,
        -1, 0, 0, 1,1,1,0, 0.5f, 0.5f,
        -1,-1, 1, 1,0,0,0, 1.0f, 1.0f,
        -1, 1, 1, 1,0,0,0, 1.0f, 0.0f,
        //右面
        1, 0, 0, 1,1,1,0, 0.5f, 0.5f,
        1, 1, 1, 1,0,0,0, 1.0f, 0.0f,
        1,-1, 1, 1,0,0,0, 0.0f, 0.0f,
        1, 0, 0, 1,1,1,0, 0.5f, 0.5f,
        1,-1, 1, 1,0,0,0, 0.0f, 0.0f,
        1,-1,-1, 1,0,0,0, 0.0f, 1.0f,
        1, 0, 0, 1,1,1,0, 0.5f, 0.5f,
        1,-1,-1, 1,0,0,0, 0.0f, 1.0f,
        1, 1,-1, 1,0,0,0, 1.0f, 1.0f,
        1, 0, 0, 1,1,1,0, 0.5f, 0.5f,
        1, 1,-1, 1,0,0,0, 1.0f, 1.0f,
        1, 1, 1, 1,0,0,0, 1.0f, 0.0f,
        //上面
        0, 1, 0, 1,1,1,0, 0.5f, 0.5f,
        1, 1, 1, 1,0,0,0, 1.0f, 0.0f,
        1, 1,-1, 1,0,0,00.0f, 0.0f,
        0, 1, 0, 1,1,1,0, 0.5f, 0.5f,
        1, 1,-1, 1,0,0,00.0f, 0.0f,
        -1, 1,-1, 1,0,0,0, 0.0f, 1.0f,
        0, 1, 0, 1,1,1,0, 0.5f, 0.5f,
        -1, 1,-1, 1,0,0,0, 0.0f, 1.0f,
        -1, 1, 1, 1,0,0,0, 1.0f, 1.0f,
        0, 1, 0, 1,1,1,0, 0.5f, 0.5f,
        -1, 1, 1, 1,0,0,0, 1.0f, 1.0f,
        1, 1, 1, 1,0,0,0, 1.0f, 0.0f,
        //下面
        0,-1, 0, 1,1,1,0, 0.5f, 0.5f,
        1,-1, 1, 1,0,0,0, 1.0f, 0.0f,
        -1,-1, 1, 1,0,0,0, 0.0f, 0.0f,
        0,-1, 0, 1,1,1,0, 0.5f, 0.5f,
        -1,-1, 1, 1,0,0,0, 0.0f, 0.0f,
        -1,-1,-1, 1,0,0,0, 0.0f, 1.0f,
        0,-1, 0, 1,1,1,0, 0.5f, 0.5f,
        -1,-1,-1, 1,0,0,0, 0.0f, 1.0f,
        1,-1,-1, 1,0,0,0, 1.0f, 1.0f,
        0,-1, 0, 1,1,1,0, 0.5f, 0.5f,
        1,-1,-1, 1,0,0,0, 1.0f, 1.0f,
        1,-1, 1, 1,0,0,0, 1.0f, 0.0f
      };
    ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4);
    vbb.order(ByteOrder.nativeOrder());
    mVertexBuffer = vbb.asFloatBuffer();
    mVertexBuffer.put(vertices);
    mVertexBuffer.position(0);
 
    int vertexShader = loaderShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode);
    int fragmentShader = loaderShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode);
 
    mProgram = GLES20.glCreateProgram();
    GLES20.glAttachShader(mProgram, vertexShader);
    GLES20.glAttachShader(mProgram, fragmentShader);
    GLES20.glLinkProgram(mProgram);
 
    mPositionHandle = GLES20.glGetAttribLocation(mProgram, "aPosition");
    mColorHandle = GLES20.glGetAttribLocation(mProgram, "aColor");
    mTextureCoordHandle = GLES20.glGetAttribLocation(mProgram, "aTextureCoord");
 
    muMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
    muMMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMMatrix");
    muLightLocationHandle = GLES20.glGetUniformLocation(mProgram, "uLightLocation");
    muTextureHandle = GLES20.glGetUniformLocation(mProgram, "uTexture");
    initTexture();
  }
 
  // 初始化紋理
  public void initTexture() {
    int [] textures = new int[1];
    GLES20.glGenTextures(1, textures, 0);
    textureId = textures[0];
    // 激活紋理單元,默認(rèn)激活的就是0號(hào)紋理單元
    //GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
    // 將紋理對(duì)象ID綁定到當(dāng)前活動(dòng)的紋理單元0上的GL_TEXTURE_2D目標(biāo)
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureId);
    // 后面對(duì)紋理的設(shè)置都是對(duì)綁定了的紋理所生效的
    //縮小采樣使用最近點(diǎn)采樣
    GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER,GLES20.GL_NEAREST);
    //縮小采樣使用最近點(diǎn)采樣
    GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D,GLES20.GL_TEXTURE_MAG_FILTER,GLES20.GL_LINEAR);
    //紋理包裹拉伸方式在st軸采用截取拉伸方式,這些設(shè)置指的是對(duì)坐標(biāo)范圍超過(guò)1的部分的限制
    GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S,GLES20.GL_CLAMP_TO_EDGE);
    GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T,GLES20.GL_CLAMP_TO_EDGE);
 
    Bitmap bitmap = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.texture);
    GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, bitmap, 0);
    // 圖片已經(jīng)加載到了顯存,可以回收
    bitmap.recycle();
  }
 
  public void draw() {
    GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 12*6);
  }
 
  public void setValue(float[] mvpMatrix, float[] mMatrix) {
    GLES20.glUseProgram(mProgram);
    mVertexBuffer.position(0);
    GLES20.glVertexAttribPointer(mPositionHandle, 3, GLES20.GL_FLOAT, false, (4+3+2) * 4, mVertexBuffer);
    mVertexBuffer.position(3);
    GLES20.glVertexAttribPointer(mColorHandle, 4, GLES20.GL_FLOAT, false, (4+3+2) * 4, mVertexBuffer);
    mVertexBuffer.position(7);
    GLES20.glVertexAttribPointer(mTextureCoordHandle, 2, GLES20.GL_FLOAT, false, (4+3+2) * 4, mVertexBuffer);
    GLES20.glEnableVertexAttribArray(mPositionHandle);
    GLES20.glEnableVertexAttribArray(mColorHandle);
    GLES20.glEnableVertexAttribArray(mTextureCoordHandle);
 
    GLES20.glUniform3f(muLightLocationHandle, 0, 0, 20);
    GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, mvpMatrix, 0);
    GLES20.glUniformMatrix4fv(muMMatrixHandle, 1, false, mMatrix, 0);
    // 將使用的紋理單元0傳遞給片元著色器
    GLES20.glUniform1i(muTextureHandle, 0);
  }
 
  private int loaderShader(int type, String shaderCode) {
    int shader = GLES20.glCreateShader(type);
    GLES20.glShaderSource(shader, shaderCode);
    GLES20.glCompileShader(shader);
    return shader;
  }
 
  private String vertexShaderCode = "uniform mat4 uMVPMatrix;"
      + "attribute vec2 aTextureCoord;"
      + "varying vec2 vTextureCoord;"
      + "uniform mat4 uMMatrix;"
      + "uniform vec3 uLightLocation;"
      + "attribute vec4 aColor;"
      + "varying vec4 vColor;"
      + "varying vec4 vDiffuse;"
      + "attribute vec3 aPosition;"
      + "void main(){"
      + "vec3 normalVectorOrigin = aPosition;"
      + "vec3 normalVector = normalize((uMMatrix*vec4(normalVectorOrigin,1)).xyz);"
      + "vec3 vectorLight = normalize(uLightLocation - (uMMatrix * vec4(aPosition,1)).xyz);"
      + "float factor = max(0.0, dot(normalVector, vectorLight));"
      + "vDiffuse = factor*vec4(1,1,1,1.0);"
      + "gl_Position = uMVPMatrix * vec4(aPosition,1);"
      + "vColor = aColor;"
      + "vTextureCoord = aTextureCoord;" // 將紋理坐標(biāo)傳到片元著色器,得到更多的插值紋理坐標(biāo)
      + "}";
 
  private String fragmentShaderCode = "precision mediump float;"
      + "uniform sampler2D uTexture;" // 這個(gè)uniform變量表示了紋理數(shù)據(jù),從java中傳過(guò)來(lái)的是所在的紋理單元編號(hào)
      + "varying vec2 vTextureCoord;"
      + "varying vec4 vColor;"
      + "varying vec4 vDiffuse;"
      + "void main(){"
      + "gl_FragColor = (vColor*vDiffuse + vColor*vec4(0.6,0.6,0.6,1))*texture2D(uTexture, vTextureCoord);" // 在紋理的基礎(chǔ)上還考慮到光照,texture2D函數(shù)用于紋理采樣
      + "}";
}

需要注意的還是傳入的頂點(diǎn)的時(shí)候數(shù)組里面包含了頂點(diǎn)、顏色和紋理坐標(biāo),因此要用ByteBuffer的position方法定位。

代碼下載

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持服務(wù)器之家。

原文鏈接:https://blog.csdn.net/cauchyweierstrass/article/details/52947279

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 精品久久久久久久久久 | 亚洲精品日韩激情在线电影 | 日韩成人在线免费视频 | 91免费网站 | 亚洲成av人片一区二区梦乃 | 午夜寂寞少妇aaa片毛片 | 粉色在线观看 | 99免费观看 | 搡女人真爽免费午夜网站 | 91精品久久久久久 | 中文av字幕 | 成人一区二区在线 | 美女视频一区 | 粉色在线观看 | 中文字幕一区二区三区在线观看 | 嫩草在线视频 | 欧美在线亚洲 | 互换娇妻呻吟hd中文字幕 | 成人免费一区二区三区视频网站 | 久久国产精品久久久久久电车 | 九九九久久国产免费 | 欧美第一专区 | 自拍偷拍五月天 | 6080亚洲精品一区二区 | 国产91精品在线 | 精品成人佐山爱一区二区 | jizzz中国| 91网页版| 国产一级一级国产 | 欧美日韩一区二区三 | 亚洲精品一区二区网址 | 亚洲欧美另类久久久精品2019 | 亚洲国产精品成人 | 91精品国产91久久综合桃花 | 欧美日韩精品综合 | 在线视频亚洲 | 欧美日韩视频在线观看免费 | 在线观看免费成人av | 中文字幕亚洲精品 | 中文字幕在线免费视频 | 欧美不卡视频 |