付費(fèi)下載
下載本文檔
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
【移動(dòng)應(yīng)用開發(fā)技術(shù)】AndroidOpenGLES2.0如何進(jìn)行繪制紋理
這篇文章將為大家詳細(xì)講解有關(guān)AndroidOpenGLES2.0如何進(jìn)行繪制紋理,文章內(nèi)容質(zhì)量較高,因此在下分享給大家做個(gè)參考,希望大家閱讀完這篇文章后對(duì)相關(guān)知識(shí)有一定的了解。紋理,在OpenGL中,可以理解為加載到顯卡顯存中的圖片。Android設(shè)備在2.2開始支持OpenGLES2.0,從前都是ES1.0和ES1.1的版本。簡(jiǎn)單來說,OpenGL
ES是為了嵌入設(shè)備進(jìn)行功能剪裁后的OpenGL版本。ES2.0是和1.x版本不兼容的,區(qū)別和兼容性參見android官方文檔。首先,android使用openGL提供了特殊的view作為基礎(chǔ)叫做GLSurfaceView。我們的view需要繼承GLSurfaceView。java代碼public
class
MyGLSurfaceView
extends
GLSurfaceView
{
public
MyGLSurfaceView(Context
context)
{
super(context);
setFocusableInTouchMode(true);
//
Tell
the
surface
view
we
want
to
create
an
OpenGL
ES
2.0-compatible
//
context,
and
set
an
OpenGL
ES
2.0-compatible
renderer.
this.setEGLContextClientVersion(2);
this.setRenderer(new
MyRenderer());
}
}并沒有什么特別之處,androidview的渲染操作需要實(shí)現(xiàn)一個(gè)render接口,GLSurfaceView的渲染接口為android.opengl.GLSurfaceView.Renderer。我們需要實(shí)現(xiàn)接口的方法。java代碼public
class
MyRenderer
implements
Renderer
{
public
void
onDrawFrame(GL10
gl)
{}
public
void
onSurfaceChanged(GL10
gl,
int
width,
int
height)
{}
public
void
onSurfaceCreated(GL10
gl,
EGLConfig
config)
{}
}接口實(shí)現(xiàn)3個(gè)方法,對(duì)應(yīng)繪制,繪制區(qū)域變化,區(qū)域創(chuàng)建。需要說明的是參數(shù)GL10gl是OpenGLES1.x版本的對(duì)象。這里我們不會(huì)使用到。還有一點(diǎn)就是,onDrawFrame方法的調(diào)用是有系統(tǒng)調(diào)用的,不需要手動(dòng)調(diào)用。系統(tǒng)會(huì)以一定的頻率不斷的回調(diào)。接下來我們進(jìn)入ES2.0的使用,上代碼先:java代碼public
void
onSurfaceCreated(GL10
gl,
EGLConfig
config)
{
GLES20.glEnable(GLES20.GL_TEXTURE_2D);
//
Active
the
texture
unit
0
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
loadVertex();
initShader();
loadTexture();
}1、啟用2D紋理繪制區(qū)域創(chuàng)建的時(shí)候,我們?cè)O(shè)置了啟用2D的紋理,并且激活了紋理單元unit0。什么意思呢,說起來話長(zhǎng),以后慢慢說。簡(jiǎn)單說一下,記住OpenGL是基于狀態(tài)的,就是很多狀態(tài)的設(shè)置和切換,這里啟用GL_TEXTURE_2D就是一個(gè)狀態(tài)的開啟,表明OpenGL可以使用2D紋理。什么是激活紋理單元?這個(gè)和硬件有點(diǎn)關(guān)系,OpenGL要顯卡會(huì)劃分存儲(chǔ)紋理的存儲(chǔ)區(qū)域不止一個(gè)區(qū)域。這里是使用區(qū)域unit0,多重紋理繪制可以開啟多個(gè),這個(gè)以后說。接下來,調(diào)用了三個(gè)函數(shù),載入頂點(diǎn),初始化著色器,載入紋理。2、加載頂點(diǎn)OpenGL繪制圖形是根據(jù)頂點(diǎn)以后鏈接起來的。為什么要這樣,其實(shí)這樣很強(qiáng)大是一種設(shè)計(jì)吧。頂點(diǎn)可以暫時(shí)簡(jiǎn)單理解為含有位置信息的坐標(biāo)點(diǎn)。java代碼private
void
loadVertex()
{
//
float
size
=
4
this.vertex
=
ByteBuffer.allocateDirect(quadVertex.length
*
4)
.order(ByteOrder.nativeOrder())
.asFloatBuffer();
this.vertex.put(quadVertex).position(0);
//
short
size
=
2
this.index
=
ByteBuffer.allocateDirect(quadIndex.length
*
2)
.order(ByteOrder.nativeOrder())
.asShortBuffer();
this.index.put(quadIndex).position(0);
}
private
FloatBuffer
vertex;
private
ShortBuffer
index;
private
float[]
quadVertex
=
new
float[]
{
-0.5f,
0.5f,
0.0f,
//
Position
0
0,
1.0f,
//
TexCoord
0
-0.5f,
-0.5f,
0.0f,
//
Position
1
0,
0,
//
TexCoord
1
0.5f
,
-0.5f,
0.0f,
//
Position
2
1.0f,
0,
//
TexCoord
2
0.5f,
0.5f,
0.0f,
//
Position
3
1.0f,
1.0f,
//
TexCoord
3
};
private
short[]
quadIndex
=
new
short[]
{
(short)(0),
//
Position
0
(short)(1),
//
Position
1
(short)(2),
//
Position
2
(short)(2),
//
Position
2
(short)(3),
//
Position
3
(short)(0),
//
Position
0
};FloatBuffer,ShortBuffer是封裝了本地?cái)?shù)據(jù)結(jié)構(gòu)的封裝對(duì)象。是的,這個(gè)2個(gè)對(duì)象里面的數(shù)據(jù)不被java虛擬機(jī)管理,相當(dāng)于C語言的存儲(chǔ)方式。quadVertex的數(shù)據(jù)就是一個(gè)矩形的坐標(biāo),和紋理坐標(biāo)。一兩句話很難解釋清楚,這里涉及到openGL的幾個(gè)經(jīng)典的坐標(biāo)系,下次說。概括的說,openGL的坐標(biāo)是單位化的,都是0.0-1.0的浮點(diǎn)型,屏幕的中心點(diǎn)是(0,0)。而紋理的坐標(biāo)左下角是(0,0)。這里的quadVertex是在屏幕中大概花了一個(gè)矩形貼了一個(gè)圖片,position0
是左上點(diǎn),以后左下,右下,右上的順序,紋理坐標(biāo)同理。quadIndx是這剛才的這些頂點(diǎn)索引排列。這里一個(gè)矩形也就4個(gè)頂點(diǎn),每個(gè)頂點(diǎn)3個(gè)位置坐標(biāo),2個(gè)紋理坐標(biāo)。也就是說一個(gè)頂點(diǎn)有5個(gè)float數(shù)據(jù)。至于為什么頂點(diǎn)為什么這么排列下次說,是2個(gè)三角形合成了一個(gè)矩形,幾句話很難解釋清楚。所以說,這段代碼就是把矩形的位置和紋理坐標(biāo),存儲(chǔ)到本地?cái)?shù)據(jù),準(zhǔn)備后面使用而已。3、初始化著色器這個(gè)著色器就是ES2.0的特色,又叫可編程著色器,也是區(qū)別于ES1.x的本質(zhì)。這里只做簡(jiǎn)單的介紹??删幊讨魇且环N腳本,語法類似C語言,腳本分為頂點(diǎn)著色器和片段著色器,分別對(duì)應(yīng)了openGL不同的渲染流程。頂點(diǎn)著色器:java代碼uniform
mat4
u_MVPMatrix;
attribute
vec4
a_position;
attribute
vec2
a_texCoord;
varying
vec2
v_texCoord;
void
main()
{
gl_Position
=
a_position;
v_texCoord
=
a_texCoord;
}片段著色器:java代碼precision
lowp
float;
varying
vec2
v_texCoord;
uniform
sampler2D
u_samplerTexture;
void
main()
{
gl_FragColor
=
texture2D(u_samplerTexture,
v_texCoord);
}這里記住一句話,頂點(diǎn)著色器,會(huì)在頂點(diǎn)上執(zhí)行;片段著色器會(huì)在像素點(diǎn)上執(zhí)行。剛才的矩形就有4個(gè)頂點(diǎn),每個(gè)頂點(diǎn)都會(huì)應(yīng)用這個(gè)腳本。也就是說,頂點(diǎn)是位置相關(guān)信息,片段是色彩紋理相關(guān)信息。這個(gè)2段腳本都是文本,需要編譯,鏈接,等等一些操作才能被ES2.0所使用。過程就像C語言的編譯運(yùn)行過程。openGL提供了相關(guān)函數(shù)去做這些事情。java代碼private
void
initShader()
{
String
vertexSource
=
Tools.readFromAssets("VertexShader.glsl");
String
fragmentSource
=
Tools.readFromAssets("FragmentShader.glsl");
//
Load
the
shaders
and
get
a
linked
program
program
=
GLHelper.loadProgram(vertexSource,
fragmentSource);
//
Get
the
attribute
locations
attribPosition
=
GLES20.glGetAttribLocation(program,
"a_position");
attribTexCoord
=
GLES20.glGetAttribLocation(program,
"a_texCoord");
uniformTexture
=
GLES20.glGetUniformLocation(program,
"u_samplerTexture");
GLES20.glUseProgram(program);
GLES20.glEnableVertexAttribArray(attribPosition);
GLES20.glEnableVertexAttribArray(attribTexCoord);
//
Set
the
sampler
to
texture
unit
0
GLES20.glUniform1i(uniformTexture,
0);
}可以看到,頂點(diǎn)和片段一起構(gòu)成一個(gè)program,它可以被openGL所使用,是一個(gè)編譯好的腳本程序,存儲(chǔ)在顯存。GLES20.glGetAttribLocation和GLES20.glGetUniformLocation
這句話是神馬作用呢。簡(jiǎn)單說就是,java程序和著色器腳本數(shù)據(jù)通信的。把就像參數(shù)的傳遞一樣,這樣腳本就能根據(jù)外界的參數(shù)變化,實(shí)時(shí)的改變openGL流水線渲染的處理流程。封裝的加載著色器的輔助方法:java代碼public
static
int
loadProgram(String
vertexSource,
String
fragmentSource)
{
//
Load
the
vertex
shaders
int
vertexShader
=
GLHelper.loadShader(GLES20.GL_VERTEX_SHADER,
vertexSource);
//
Load
the
fragment
shaders
int
fragmentShader
=
GLHelper.loadShader(GLES20.GL_FRAGMENT_SHADER,
fragmentSource);
//
Create
the
program
object
int
program
=
GLES20.glCreateProgram();
if
(program
==
0)
{
throw
new
RuntimeException("Error
create
program.");
}
GLES20.glAttachShader(program,
vertexShader);
GLES20.glAttachShader(program,
fragmentShader);
//
Link
the
program
GLES20.glLinkProgram(program);
int[]
linked
=
new
int[1];
//
Check
the
link
status
GLES20.glGetProgramiv(program,
GLES20.GL_LINK_STATUS,
linked,
0);
if
(linked[0]
==
0)
{
GLES20.glDeleteProgram(program);
throw
new
RuntimeException("Error
linking
program:
"
+
GLES20.glGetProgramInfoLog(program));
}
//
Free
up
no
longer
needed
shader
resources
GLES20.glDeleteShader(vertexShader);
GLES20.glDeleteShader(fragmentShader);
return
program;
}java代碼public
static
int
loadShader(int
shaderType,
String
source)
{
//
Create
the
shader
object
int
shader
=
GLES20.glCreateShader(shaderType);
if
(shader
==
0)
{
throw
new
RuntimeException("Error
create
shader.");
}
int[]
compiled
=
new
int[1];
//
Load
the
shader
source
GLES20.glShaderSource(shader,
source);
//
Compile
the
shader
GLES20.glCompileShader(shader);
//
Check
the
compile
status
GLES20.glGetShaderiv(shader,
GLES20.GL_COMPILE_STATUS,
compiled,
0);
if
(compiled[0]
==
0)
{
GLES20.glDeleteShader(shader);
throw
new
RuntimeException("Error
compile
shader:
"
+
GLES20.glGetShaderInfoLog(shader));
}
return
shader;
}為什么openGL的很多操作目標(biāo)都是int類型的?因?yàn)閛penGL只會(huì)在顯存生成或綁定地址,返回id,以后用id相當(dāng)于句柄去改變它的內(nèi)部狀態(tài)。4、加載紋理就是把圖片的數(shù)據(jù)上傳到顯存,以后再使用它。請(qǐng)注意紋理圖片的長(zhǎng)和寬***是2的N次方,不然不一定能繪制出來。java代碼static
int[]
loadTexture(String
path)
{
int[]
textureId
=
new
int[1];
//
Generate
a
texture
object
GLES20.glGenTextures(1,
textureId,
0);
int[]
result
=
null;
if
(textureId[0]
!=
0)
{
InputStream
is
=
Tools.readFromAsserts(path);
Bitmap
bitmap;
try
{
bitmap
=
BitmapFactory.decodeStream(is);
}
finally
{
try
{
is.close();
}
catch
(IOException
e)
{
throw
new
RuntimeException("Error
loading
Bitmap.");
}
}
result
=
new
int[3];
result[TEXTURE_ID]
=
textureId[0];
//
TEXTURE_ID
result[TEXTURE_WIDTH]
=
bitmap.getWidth();
//
TEXTURE_WIDTH
result[TEXTURE_HEIGHT]
=
bitmap.getHeight();
//
TEXTURE_HEIGHT
//
Bind
to
the
texture
in
OpenGL
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D,
textureId[0]);
//
Set
filtering
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_NEAREST);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D,
GLES20.GL_TEXTURE_WRAP_S,
GLES20.GL_CLAMP_TO_EDGE);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D,
GLES20.GL_TEXTURE_WRAP_T,
GLES20.GL_CLAMP_TO_EDGE);
//
Load
the
bitmap
into
the
bound
texture.
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D,
0,
bitmap,
0);
//
Recycle
the
bitmap,
since
its
data
has
been
loaded
into
OpenGL.
bitmap.recycle();
}
else
{
throw
new
RuntimeException("Error
loading
texture.");
}
return
result;
}這里使用了android的工具類吧bitmap直接轉(zhuǎn)換成openGL紋理需要的格式了。過程是,先生成一個(gè)紋理的id在顯卡上的,以后根據(jù)id上傳紋理數(shù)據(jù),以后保存這個(gè)id就可以操作這個(gè)紋理了。至于紋理的一些過濾特性設(shè)置,將來再說?,F(xiàn)在貌似就剩下繪制了,準(zhǔn)備好了頂點(diǎn)信息,頂點(diǎn)對(duì)應(yīng)的紋理坐標(biāo)。初始化了著色器,上傳了紋理圖片。接下來就已把他們合起來繪制了。java代碼public
void
onDrawFrame(GL10
gl)
{
//
clear
screen
to
black
GLES20.glClearColor(0.0f,
0.0f,
0.0f,
0.0f);
GLES20.glClear(GLES20.
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2026年會(huì)展現(xiàn)場(chǎng)服務(wù)標(biāo)準(zhǔn)化指南
- 2026湖南邵陽市邵陽縣不動(dòng)產(chǎn)登記中心和邵陽縣土地房屋征收服務(wù)中心選調(diào)4人備考題庫完整答案詳解
- 果園安全生產(chǎn)與防護(hù)手冊(cè)
- 2026浙江嘉興海寧市遠(yuǎn)達(dá)教育集團(tuán)招聘?jìng)淇碱}庫(十)及一套完整答案詳解
- 2026甘肅酒泉金塔縣鑫耀人力資源管理有限公司招聘相關(guān)技術(shù)人員的4人備考題庫有答案詳解
- 2026河南省直機(jī)關(guān)遴選公務(wù)員159人備考題庫完整答案詳解
- 2026年漁業(yè)資源增殖放流實(shí)務(wù)指南
- 職業(yè)噪聲暴露的流行病學(xué)特征與防控策略
- 空調(diào)店銷售年終總結(jié)(3篇)
- 職業(yè)共病管理中的學(xué)術(shù)交流平臺(tái)
- 基建人員考核管理辦法
- 2025體育與健康課程標(biāo)準(zhǔn)深度解讀與教學(xué)實(shí)踐
- 礦山救援器材管理制度
- 2025西南民族大學(xué)輔導(dǎo)員考試試題及答案
- T/CSPSTC 17-2018企業(yè)安全生產(chǎn)雙重預(yù)防機(jī)制建設(shè)規(guī)范
- 2025年《三級(jí)物業(yè)管理師》考試復(fù)習(xí)題(含答案)
- 《數(shù)據(jù)與管理》課件
- 2025屆北京市西城區(qū)北京四中高考英語二模試卷含答案
- 面神經(jīng)炎美國(guó)神經(jīng)病學(xué)會(huì)和美國(guó)耳鼻喉-頭頸外科學(xué)會(huì)治療
- 鍋爐煤場(chǎng)安全管理制度
- DB11∕T1135-2024供熱系統(tǒng)有限空間作業(yè)安全技術(shù)規(guī)程
評(píng)論
0/150
提交評(píng)論