導航:首頁 > 操作系統 > androidopengl繪圖

androidopengl繪圖

發布時間:2024-03-27 05:34:25

① 如何使用android中的OpenGL ES媒體效果

Android的媒體效果框架允許開發者可以很容易的應用多種令人印象深刻的視覺效果到照片或視頻之上。作為這個媒體效果的框架,它使用GPU來處理圖片處理的過程,它僅僅接收OpenGL的紋理(texture)作為輸入。在本次教程中,你將會學習到如何使用OpenGL ES2.0將圖片資源轉化為紋理,以及如何使用框架為圖片應用不同的處理效果。
准備
為了開始本次的教程,你必須具備:
1.一款支持Android開發的IDE,如果你沒有的話,可以在Android Developer website下載最新版本的Android studio。
2.一款運行Android4.0之上Android手機,並且GPU支持OpenGL ES2.0
3.對OpenGL的基本知識了解
設置OpenGL ES環境
創建GLSurfaceView
為了顯示OpenGL的圖形,你需要使用GLSurfaceView類,就像其他任何的View子類意義,你可以將它添加到你的Activity或Fragment之上,通過在布局xml文件中定義或者在代碼中創建實例。
在本次的教程中,我們使用GLSurfaceView作為唯一的View在我們的Activity中,因此,為了簡便,我們在代碼中創建GLSurfaceView的實例並將其傳入setContentView中,這樣它將會填充你的整個手機屏幕。Activity中的onCreate方法如下:
<code class="hljs" java="">protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

GLSurfaceView view = new GLSurfaceView(this);
setContentView(view);
}</code>

因為媒體效果的框架僅僅支持OpenGL ES2.0及以上的版本,所以在setEGLContextClientVersion 方法中傳入2;
<code avrasm="" class="hljs">view.setEGLContextClientVersion(2);</code>

為了確保GLSurfaceView僅僅在必要的時候進行渲染,我們在setRenderMode 方法中進行設置:
<code avrasm="" class="hljs">view.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);</code>

創建Renderer
Renderer負責渲染GLSurfaceView中的內容。
創建類實現介面GLSurfaceView.Renderer,在這里我們打算將這個類命名為EffectsRenderer,添加構造函數並覆寫介面中的抽象方法,如下:
<code class="hljs" java="">public class EffectsRenderer implements GLSurfaceView.Renderer {

public EffectsRenderer(Context context){
super();
}

@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
}

@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
}

@Override
public void onDrawFrame(GL10 gl) {
}
}</code>

回到Activity中調用setRenderer方法,讓GLSurfaceView使用我們創建的Renderer:
<code class="hljs" cs="">view.setRenderer(new EffectsRenderer(this));</code>

編寫Manifest文件
如果你想要發布你的App到谷歌商店,在AndroidManifest.xml文件中添加如下語句:
<code class="hljs" xml=""><uses-feature android:glesversion="0x00020000" android:required="true"></uses-feature></code>

這會確保你的app只能被安裝在支持OpenGL ES2.0的設備之上。現在OpenGL環境准備完畢。
創建一個OpenGL平面
定義頂點
GLSurfaceView是不能直接顯示一張照片的,照片首先應該被轉化為紋理,應用在OpenGL square之上。在本次教程中,我將創建一個2D平面,並且具有4個頂點。為了簡單,我將使用一個長方形,現在,創建一個新的類Square,用它來代表形狀。
<code class="hljs" cs="">public class Square {

}</code>

默認的OpenGL系統的坐標系中的原點是在中心,因此4個角的坐標可以表示為:
左下角: (-1, -1) 右下角:(1, -1) 右上角:(1, 1) 左上角:(-1, 1)
我們使用OpenGL繪制的所有的物體都應該是由三角形決定的,為了畫一個方形,我們需要兩個具有一條公共邊的三角形,那意味著這些三角形的坐標應該是:
triangle 1: (-1, -1), (1, -1), 和 (-1, 1) triangle 2: (1, -1), (-1, 1), 和 (1, 1)
創建一個float數組來代表這些頂點:
<code class="hljs" cpp="">private float vertices[] = {
-1f, -1f,
1f, -1f,
-1f, 1f,
1f, 1f,
};</code>
為了在square上定位紋理,需要確定紋理的頂點坐標,創建另一個數組來表示紋理頂點的坐標:
<code class="hljs" cpp="">private float textureVertices[] = {
0f,1f,
1f,1f,
0f,0f,
1f,0f
};</code>
創建緩沖區
這些坐標數組應該被轉變為緩沖字元(byte buffer)在OpenGL可以使用之前,接下來進行定義:
<code class="hljs" cs="">private FloatBuffer verticesBuffer;
private FloatBuffer textureBuffer;</code>
在initializeBuffers方法中去初始化這些緩沖區:使用ByteBuffer.allocateDirect來創建緩沖區,因為float是4個位元組,那麼我們需要的byte數組的長度應該為float的4倍。
下面使用ByteBuffer.nativeOrder方法來定義在底層的本地平台上的byte的順序。使用asFloatBuffer方法將ByteBuffer轉化為FloatBuffer,在FloatBuffer被創建後,我們調用put方法來將float數組放入緩沖區,最後,調用position方法來保證我們是由緩沖區的開頭進行讀取。
<code avrasm="" class="hljs">private void initializeBuffers(){
ByteBuffer buff = ByteBuffer.allocateDirect(vertices.length * 4);
buff.order(ByteOrder.nativeOrder());
verticesBuffer = buff.asFloatBuffer();
verticesBuffer.put(vertices);
verticesBuffer.position(0);

buff = ByteBuffer.allocateDirect(textureVertices.length * 4);
buff.order(ByteOrder.nativeOrder());
textureBuffer = buff.asFloatBuffer();
textureBuffer.put(textureVertices);
textureBuffer.position(0);
}</code>
創建著色器
著色器只不過是簡單的運行在GPU中的每個單獨的頂點的C程序,在本次教程中,我們使用兩種著色器:頂點著色器和片段著色器。
頂點著色器的代碼:
<code class="hljs" glsl="">attribute vec4 aPosition;
attribute vec2 aTexPosition;
varying vec2 vTexPosition;
void main() {
gl_Position = aPosition;
vTexPosition = aTexPosition;
};</code>
片段著色器的代碼
class="hljs" glsl="">precision mediump float;

uniform sampler2D uTexture;
varying vec2 vTexPosition;
void main() {
gl_FragColor = texture2D(uTexture, vTexPosition);
};</code>
如果你了解OpenGL,那麼這段代碼對你來說是熟悉的,如果你不能理解這段代碼,你可以參考OpenGL documentation。這里有一個簡明扼要的解釋:
頂點著色器負責繪制單個頂點。aPosition是一個變數被綁定到FloatBuffer上,包含著這些頂點的坐標。相似的,aTexPosition 是一個變數被綁定到FloatBuffer上,包含著紋理的坐標。gl_Position 是一個在OpenGL中創建的變數,代表每一個頂點的位置,vTexPosition是一個數組變數,它的值被傳遞到片段著色器中。
在本教程中,片段著色器負責square的著色。它使用texture2D方法從紋理中拾取顏色,並且使用一個在OpenGL中被創建的變數gl_FragColor將顏色分配到片段。
在該類中,著色器的代碼應該被轉化為String。
<code class="hljs" java="">private final String vertexShaderCode =
attribute vec4 aPosition; +
attribute vec2 aTexPosition; +
varying vec2 vTexPosition; +
void main() { +
gl_Position = aPosition; +
vTexPosition = aTexPosition; +
};

private final String fragmentShaderCode =
precision mediump float; +
uniform sampler2D uTexture; +
varying vec2 vTexPosition; +
void main() { +
gl_FragColor = texture2D(uTexture, vTexPosition); +
};</code>
創建程序
創建新的方法initializeProgram來創建一個編譯和鏈接著色器的OpenGL程序。
使用glCreateShader創建一個著色器對象,並且返回以int為表示形式的指針。為了創建頂點著色器,傳遞GL_VERTEX_SHADER給它。相似的,為了創建一個片段著色器,傳遞GL_FRAGMENT_SHADER給它。下面使用glShaderSource方法關聯相對應的著色器代碼到著色器上。使用glCompileShader編譯著色器代碼。
在編譯了著色器的代碼後,創建一段新的的程序glCreateProgram,與glCreateShader相似,它也返回一個以int為表示形式的指針。調用glAttachShader方法附著著色器到程序中,最後,調用glLinkProgram進行鏈接。
代碼:
<code class="hljs" cs="">private int vertexShader;
private int fragmentShader;
private int program;
private void initializeProgram(){
vertexShader = GLES20.glCreateShader(GLES20.GL_VERTEX_SHADER);
GLES20.glShaderSource(vertexShader, vertexShaderCode);
GLES20.glCompileShader(vertexShader);
fragmentShader = GLES20.glCreateShader(GLES20.GL_FRAGMENT_SHADER);
GLES20.glShaderSource(fragmentShader, fragmentShaderCode);
GLES20.glCompileShader(fragmentShader);
program = GLES20.glCreateProgram();
GLES20.glAttachShader(program, vertexShader);
GLES20.glAttachShader(program, fragmentShader);

GLES20.glLinkProgram(program);
}</code>
你可能會發現,OpenGL的方法(以gl開頭的)都是在GLES20類中,這是因為我們使用的是OpenGL ES2.0,如果我們使用更高的版本,就會用到這些類:GLES30,GLES31。
畫出形狀
現在定義draw方法來利用我們之前定義的點和著色器進行繪制。
下面是你需要做的:
1.使用glBindFramebuffer方法創建一個幀緩沖對象(FBO)
2.調用glUseProgram創建程序,就像之前所提
3.傳遞GL_BLEND給glDisable方法,在渲染過程中禁用顏色的混合。
4.調用glGetAttribLocation得到變數aPosition和aTexPosition的句柄
5.使用glVertexAttribPointer連接aPosition和aTexPosition的句柄到各自的verticesBuffer和textureBuffer
6.使用glBindTexture方法綁定紋理(作為draw方法的參數傳入)到片段著色器上
7.調用glClear方法清空GLSurfaceView的內容
8.最後,使用glDrawArrays方法畫出兩個三角形(也就是方形)
代碼:
<code avrasm="" class="hljs">public void draw(int texture){
GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0);
GLES20.glUseProgram(program);
GLES20.glDisable(GLES20.GL_BLEND);

int positionHandle = GLES20.glGetAttribLocation(program, aPosition);
int textureHandle = GLES20.glGetUniformLocation(program, uTexture);
int texturePositionHandle = GLES20.glGetAttribLocation(program, aTexPosition);

GLES20.glVertexAttribPointer(texturePositionHandle, 2, GLES20.GL_FLOAT, false, 0, textureBuffer);
GLES20.glEnableVertexAttribArray(texturePositionHandle);

GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, texture);
GLES20.glUniform1i(textureHandle, 0);

GLES20.glVertexAttribPointer(positionHandle, 2, GLES20.GL_FLOAT, false, 0, verticesBuffer);
GLES20.glEnableVertexAttribArray(positionHandle);

GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
}</code>

在構造函數中添加初始化方法:
<code class="hljs" cs="">public Square(){
initializeBuffers();
initializeProgram();
}</code>

渲染OpenGL平面和紋理
現在我們的渲染器什麼也沒做,我們需要改變它來渲染我們在前面創造的平面。
首先,讓我們創建一個Bitmap,添加一張照片到res/drawable文件夾之下,我把它命名為forest.jpg,使用BitmapFactory將照片轉化為Bitmap。另外將照片的尺寸存儲下來。
改變EffectsRenderer的構造函數如下,

<code class="hljs" java="">private Bitmap photo;
private int photoWidth, photoHeight;
public EffectsRenderer(Context context){
super();
photo = BitmapFactory.decodeResource(context.getResources(), R.drawable.forest);
photoWidth = photo.getWidth();
photoHeight = photo.getHeight();
}</code>

創建一個新的方法generateSquare,將Bitmap轉化為紋理,並且出初始化Square對象,你也需要一個數組來保存對紋理的引用,使用glGenTextures來初始化這個數組,glBindTexture方法來在位置0激活紋理。
現在,調用glTexParameteri設置不同的級別,決定紋理被怎樣渲染。
設置GL_TEXTURE_MIN_FILTER(修正功能),GL_TEXTURE_MAG_FILTER(放大功能)給GL_LINEAR,確保圖片是平滑的在它被拉伸的時候。
設置GL_TEXTURE_WRAP_S和GL_TEXTURE_WRAP_T給GL_CLAMP_TO_EDGE,保證紋理不會重復。
最後調用texImage2D方法將Bitmap放置到紋理中,實現方法如下:
<code avrasm="" class="hljs">private int textures[] = new int[2];
private Square square;

private void generateSquare(){
GLES20.glGenTextures(2, textures, 0);
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textures[0]);

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);
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);

GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, photo, 0);
square = new Square();
}</code>

當GLSurfaceView的尺寸發生改變時,onSurfaceChanged方法被調用,這時我們需要調用glViewPort確認新的尺寸。調用glClearColor使其變為黑色,接著調用generateSquare重新初始化紋理和平面。
<code class="hljs" java="">@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
GLES20.glViewport(0,0,width, height);
GLES20.glClearColor(0,0,0,1);
generateSquare();
}</code>

最後在onDrawFrame調用draw方法:
<code class="hljs" java="">@Override
public void onDrawFrame(GL10 gl) {
square.draw(textures[0]);
}</code>

② 如何在Android上使用OpenGL ES 2.0繪制點

FrameBuffer對象的概念可以參見前面文章AndroidOpenGLES開發教程(23):FrameBuffer。簡單的和2D圖像類比,FrameBuffer如果對應到二維圖形環境中,就是一個2D的內存數組空間,預設情況為屏幕的顯存,也可以創建Offscreen內存空間,此時FrameBuffer可以是一個二維數組,數組每個元素代表一個像素顏色。對於三維圖形來說,除了需要代表顏色的二維數組(ColorBuffer),還需要深度二維數組(DepthBuffer)或遮罩數組(StencilBuffer),因此在OpenGL中的FrameBuffer為上述ColorBuffer,DepthBuffer,StencilBuffer的集合。如果手機具有GPU,其預設的FrameBuffer也是3D屏幕顯示區域。通過OpenglES擴展支持,應用程序也可以創建內存中的FrameBuffer對象(不用於屏幕顯示)。通過這種應用程序創建的FrameBuffer對象,OpenGL應用可以將圖像顯示輸出重新定向到這個非屏幕顯示用FrameBuffer對象中,類似於二維圖形繪制中常用的Offscreen技術。和預設的屏幕顯示FrameBuffer一樣,由應用程序創建的FrameBuffer對象也是由ColorBuffer,DepthBuffer和StencilBuffer(可選)的集合組成。這些Buffer在FrameBuffer對象中可以稱為FrameBuffer-attachable圖像,FrameBuffer定義了一些接入點(AttachmentPoint)可以用於連接(Attach)這些Buffer數組。OpenGLES定義了兩種FrameBuffer-attachable圖像,Texture和renderbuffer,簡單的可以將Texture理解為Colorbuffer或是2D圖像,renderbuffer對應於depthbuffer。

③ Android OpenGL 的基本使用

由於本人現在在公司做Android上的OpenGL圖像處理相關功能,以前沒有搞過這方面的知識,所以一切只能從頭開始搞起,接下來將會慢慢分享其他方面的內容,先用這篇比較基礎的文章來開頭。

剛才我們談到圖像處理,在做圖像處理我們不是可以用Canvas來繪制嗎,怎麼還要用OpenGL那麼陌生的東西來搞?為什麼要用OpenGL,肯定有它的好處。

接下來我們會來講解如何在Android項目開發過程中加入OpenGL,在開始前我們先了解同OpenGL ES密切相關的載體:GLSurfaceView:

要用OpenGL繪制,首先要有GLSurfaceVie的實例

現在OpenGL ES版本已經到3.0了,Android平台上目前有1.0和2.0,我們使用的是2.0,在使用前在onCreate()方法中檢查是否支持2.0的版本並且確定使用2.0

一般我們只需要使用「configurationInfo.reqGlEsVersion >= 0x20000」,至於加後面主要是用於模擬器檢查,假定模擬器支持2.0。

前面說到GLSurfaceView挖了一個洞,就是為了看見下面的渲染表面,同樣實在onCreate()方法中

通過setEGLContextClientVersion()方法配置surface視圖,設定好使用的OpenGL版本,然後調用setRenderer()傳進有自定義Renderer類的新實例。當Surface創建或者發生變化的時候,以及繪制一幅新幀時,渲染器都會被GLSurfaceView調用。

GLSurfaceView的生命周期要協同好Activity的生命周期,避免造成內存泄漏。

Renderer類也就是我們的渲染類了,它是通過實現Renderer介面來實現功能的。

渲染器介面定義的方法:

實現Renderer的介面方法

首選在onSurfaceCreated()中調用glClearColor設置清空屏幕用的顏色,這里使用紅色。

設置視口的大小

在onDrawFrame()中調用glClear(GL_COLOR_BUFFER_BIT)清空屏幕,會調用glClearColor中定義的顏色來填充整個屏幕。通過這幾個步驟,基本上就可以在GLSurfaceView繪制出東西了,在這里我只是簡單的用紅色繪制整個屏幕。

OpenGL在Android上的使用基本上是這樣,但是,當然沒那麼簡單,在使用OpenGL進行繪制算是比較繁瑣的過程,後面也會慢慢去揭曉其他使用方法,來構造一幅一幅精美的特效靜/動圖。

④ android 中opengl畫正方體,其頂底坐標還有索引是怎麼計算和定義的

opengl es畫圖形都是通過三角形來畫的,當然還可以畫直線和點
畫圖形的時候有兩種方法:glDrawArrays( ) 和glDrawElements( )

比如畫一個由2個三角形組成的正方形,左上角坐標是l,t,右下角坐標是r,b
使用glDrawArrays繪制時,畫2個三角形,需要這樣傳:
(l,t),(r,t),(l,b)
(r,t),(r,b),(l,b)
也就是說傳的頂點數據就是按照順時針或者逆時針排好順序的,兩個三角形的6個頂點

而用glDrawElements畫的話可以這樣
float coord[4][2]={{l,t},{r,t},{r,b},{l,b}};
繪制時用索引指定頂點順序:
0,1,3
1,2,3

也就是說glDrawArrays傳輸或指定的數據是最終的真實數據,在繪制時效能更好
而glDrawElements指定的是真實數據的調用索引,在內存/顯存佔用上更節省

⑤ android skia與opengl es 都可以畫2d圖嗎

一、基礎知識: OpenGL ES目前只支持三角形,但任何多邊形都可拆分成多個三角形,所以無所謂這個限制的存在。 1.OpenGL中的坐標點: 每一個坐標點由(X, Y, Z)組成。 定義一個三角形的頂點數組: [java] int one = 0x10000; //三角形三個頂點 private IntBuffer triggerBuffer = IntBuffer.wrap(new int[]{ 0,one,0, //上頂點 -one,-one,0, //左下點 one,-one,0,}); //右下點 int one = 0x10000; //三角形三個頂點 private IntBuffer triggerBuffer = IntBuffer.wrap(new int[]{ 0,one,0, //上頂點 -one,-one,0, //左下點 one,-one,0,}); //右下點定義一個正方形的頂點數組: [java] //正方形的4個頂點 private IntBuffer quaterBuffer = IntBuffer.wrap(new int[]{ one,one,0, -one,one,0, one,-one,0, -one,-one,0}); //正方形的4個頂點 private IntBuffer quaterBuffer = IntBuffer.wrap(new int[]{ one,one,0, -one,one,0, one,-one,0, -one,-one,0}); 2.OpenGL中的坐標系: 當調用gl.glLoadIdentity()函數之後,實際上是將當前點移動到了屏幕中心, X坐標軸從左至右,Y坐標軸從下至上,Z坐標軸從里至外。 OpenGL屏幕中心的坐標值是X軸和Y軸的0.0f點。 中心左邊的坐標值是負值,右邊是正值; 移向屏幕頂端是正值,移向屏幕底端是負值; 移入屏幕深處是負值,移出屏幕則是正值。 在繪制時,我們可以使用glTranslatef函數來移動畫筆的位置,從而使圖形顯示在我們 想要的位置。 [java] gl.glTranslatef(-1.5f, 0.0f, -6.0f); gl.glTranslatef(-1.5f, 0.0f, -6.0f);此函數,就是將畫筆沿X軸左移1.5f個單位,Y軸保持不變,Z軸向屏幕裡面移動6.0f個單位。 將視圖推入屏幕背後足夠的距離以便可以看見全部的場景,這里需要注意的是屏幕內移動的單位 必須小於我們前面通過glFrustumf方法設置的最遠距離,否則超出視角范圍,將顯示不出來。 3.OpenGL中的頂點數組: 在實際畫圖時,我們往往需要定位幾個點,然後讓OpenGL以此為基準來畫圖。在設置頂點位置前, 我們需要按照以下步驟來啟用我們的頂點數組: ①開啟頂點設置動能: [java] gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);②設置頂點數組: [java] view plainprint?gl.glVertexPointer(3, GL10.GL_FIXED, 0, triggerBuffer); gl.glVertexPointer(3, GL10.GL_FIXED, 0, triggerBuffer);glVertexPointer(int size, int type, int stride, Buffer pointer) size用於描述頂點的尺寸(本例使用XYZ,所以是3),type描述頂點的類型,固定的使用 GL_FIXED,stride描述步長,pointer指向頂點緩存,即我們創建的頂點數組。 ③繪制頂點: [java] gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3); //繪制三角形 gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4); //繪制四邊形 gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3); //繪制三角形 gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4); //繪制四邊形glDrawArrays(int mode, int first, int count) mode指明繪制的模式,first和count分別是開始的位置和要繪制的頂點計數。 4、實例: 畫一個三角形和正方形。 根據我們上一節的框架分析,目前,我們只需將精力集中在onDrawFrame方法裡面的繪圖操作部分了。 1. 界面編輯(reslayoutmain.xml): [java] android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/hello" /> 2.代碼編輯 (srcwyfzclMyActivity.java): [java] package wyf.zcl; import android.app.Activity; import android.opengl.GLSurfaceView; import android.opengl.GLSurfaceView.Renderer; import android.os.Bundle; public class Activity01 extends Activity { Renderer render = new GLRender(); /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); GLSurfaceView glView = new GLSurfaceView(this); glView.setRenderer(render); setContentView(glView); } } package wyf.zcl; import android.app.Activity; import android.opengl.GLSurfaceView; import android.opengl.GLSurfaceView.Renderer; import android.os.Bundle; public class Activity01 extends Activity { Renderer render = new GLRender(); /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); GLSurfaceView glView = new GLSurfaceView(this); glView.setRenderer(render); setContentView(glView); } } (srcwyfzclGLRender.java): [java] package wyf.zcl; import java.nio.IntBuffer; import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.opengles.GL10; import android.opengl.GLSurfaceView.Renderer; public class GLRender implements Renderer { int one = 0x10000; //三角形三個頂點 private IntBuffer triggerBuffer = IntBuffer.wrap(new int[]{ 0,one,0, //上頂點 -one,-one,0, //左下點 one,-one,0,}); //右下點 //正方形的4個頂點 private IntBuffer quaterBuffer = IntBuffer.wrap(new int[]{ one,one,0, -one,one,0, one,-one,0, -one,-one,0}); @Override public void onDrawFrame(GL10 gl) { // 清除屏幕和深度緩存 gl.glClear(GL10.GL_COLOR_BUFFER_BIT GL10.GL_DEPTH_BUFFER_BIT); // 重置當前的模型觀察矩陣 gl.glLoadIdentity(); // 左移 1.5 單位,並移入屏幕 6.0 gl.glTranslatef(-1.5f, 0.0f, -6.0f); // 允許設置頂點 gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); // 設置三角形 gl.glVertexPointer(3, GL10.GL_FIXED, 0, triggerBuffer); //繪制三角形 gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3); // 重置當前的模型觀察矩陣 gl.glLoadIdentity(); // 左移 1.5 單位,並移入屏幕 6.0 gl.glTranslatef(1.5f, 0.0f, -6.0f); //設置和繪制正方形 gl.glVertexPointer(3, GL10.GL_FIXED, 0, quaterBuffer); gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4); // 取消頂點設置 gl.glDisableClientState(GL10.GL_VERTEX_ARRAY); } @Override public void onSurfaceChanged(GL10 gl, int width, int height) { float ratio = (float) width / height; //設置OpenGL場景的大小 gl.glViewport(0, 0, width, height); //設置投影矩陣 gl.glMatrixMode(GL10.GL_PROJECTION); //重置投影矩陣 gl.glLoadIdentity(); // 設置視口的大小 gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10); // 選擇模型觀察矩陣 gl.glMatrixMode(GL10.GL_MODELVIEW); // 重置模型觀察矩陣 gl.glLoadIdentity(); } @Override public void onSurfaceCreated(GL10 gl, EGLConfig config) { // 啟用陰影平滑 gl.glShadeModel(GL10.GL_SMOOTH); // 黑色背景 gl.glClearColor(0, 0, 0, 0); // 設置深度緩存 gl.glClearDepthf(1.0f); // 啟用深度測試 gl.glEnable(GL10.GL_DEPTH_TEST); // 所作深度測試的類型 gl.glDepthFunc(GL10.GL_LEQUAL); // 告訴系統對透視進行修正 gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST); } } package wyf.zcl; import java.nio.IntBuffer; import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.opengles.GL10; import android.opengl.GLSurfaceView.Renderer; public class GLRender implements Renderer { int one = 0x10000; //三角形三個頂點 private IntBuffer triggerBuffer = IntBuffer.wrap(new int[]{ 0,one,0, //上頂點 -one,-one,0, //左下點 one,-one,0,}); //右下點 //正方形的4個頂點 private IntBuffer quaterBuffer = IntBuffer.wrap(new int[]{ one,one,0, -one,one,0, one,-one,0, -one,-one,0}); @Override public void onDrawFrame(GL10 gl) { // 清除屏幕和深度緩存 gl.glClear(GL10.GL_COLOR_BUFFER_BIT GL10.GL_DEPTH_BUFFER_BIT); // 重置當前的模型觀察矩陣 gl.glLoadIdentity(); // 左移 1.5 單位,並移入屏幕 6.0 gl.glTranslatef(-1.5f, 0.0f, -6.0f); // 允許設置頂點 gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); // 設置三角形 gl.glVertexPointer(3, GL10.GL_FIXED, 0, triggerBuffer); //繪制三角形 gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3); // 重置當前的模型觀察矩陣 gl.glLoadIdentity(); // 左移 1.5 單位,並移入屏幕 6.0 gl.glTranslatef(1.5f, 0.0f, -6.0f); //設置和繪制正方形 gl.glVertexPointer(3, GL10.GL_FIXED, 0, quaterBuffer); gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4); // 取消頂點設置 gl.glDisableClientState(GL10.GL_VERTEX_ARRAY); } @Override public void onSurfaceChanged(GL10 gl, int width, int height) { float ratio = (float) width / height; //設置OpenGL場景的大小 gl.glViewport(0, 0, width, height); //設置投影矩陣 gl.glMatrixMode(GL10.GL_PROJECTION); //重置投影矩陣 gl.glLoadIdentity(); // 設置視口的大小 gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10); // 選擇模型觀察矩陣 gl.glMatrixMode(GL10.GL_MODELVIEW); // 重置模型觀察矩陣 gl.glLoadIdentity(); } @Override public void onSurfaceCreated(GL10 gl, EGLConfig config) { // 啟用陰影平滑 gl.glShadeModel(GL10.GL_SMOOTH); // 黑色背景 gl.glClearColor(0, 0, 0, 0); // 設置深度緩存 gl.glClearDepthf(1.0f); // 啟用深度測試 gl.glEnable(GL10.GL_DEPTH_TEST); // 所作深度測試的類型 gl.glDepthFunc(GL10.GL_LEQUAL); // 告訴系統對透視進行修正 gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST); } } 3.運行效果:

⑥ 如何動態地畫一條虛線在Android中使用OpenGL ES 2.0編程

動態繪制虛線,可以參考如下內容:
、被稱為點畫的影響。不幸的是,點畫已經從OpenGL的刪除,但幸運的是,有幾種方法仍然得到的效果。我們必須充分利用的OpenGL的著色語言的這項任務。 頂點著色器:uniform mat4 u_modelViewProjectionMatrix;
uniform mat4 mv;
attribute vec4 a_position;
attribute vec4 a_color;
varying vec4 v_color;
varying vec4 position;
void main() {
gl_Position = u_modelViewProjectionMatrix * a_position;
position = mv * a_position;
v_color = a_color;
}

著色器:precision mediump float;
uniform vec2 sourcePoint;
varying vec4 v_color;
varying vec4 position;
void main() {
if (cos(0.1*abs(distance(sourcePoint.xy, position.xy))) + 0.5 > 0.0) {
gl_FragColor = vec4(0,0,0,0);
} else {
gl_FragColor = v_color;
}
}

我沒有在這里找到本教程中,我測試了,這里是我的結果:

正如羅斯托夫在這個線程解釋,這里最大的部分是sourcePoint。

的關鍵 CodeGo.net,整個事情是sourcePoint被傳遞的
該行的起源。

如果你不喜歡這種方式也存在textures圖案的效果。有與α虛線效果textures,並將其應用到您的線路。
2.
我找到了一個更好的解決方案。它的水平和垂直線。
#define DOT_VERTEX_CODE \
"attribute vec4 a_Position;" \
"uniform mat4 projectionMatrix;" \
"varying vec2 v_xy;" \
"void main() {gl_PointSize = 1.0; gl_Position = a_Position*projectionMatrix; v_xy = a_Position.xy;}"
#define DOT_FRAGMENT_CODE \
"precision mediump float;" \
"varying vec2 v_xy;" \
"uniform float isVert;" \
"uniform vec4 color1;" \
"uniform vec4 color2;" \
"void main() {gl_FragColor = mod(isVert > 0.0 ? v_xy.y : v_xy.x, 2.0) >= 1.0 ? color1 : color2;}"

閱讀全文

與androidopengl繪圖相關的資料

熱點內容
安卓如何截屏到手機 瀏覽:994
多空資金指標公式源碼精準買點 瀏覽:226
匿名投票小程序源碼 瀏覽:1000
java運行監控 瀏覽:233
成都做程序員之都 瀏覽:537
光纖輸出的是源碼還是pcm 瀏覽:143
pdf格式列印出來是白紙 瀏覽:313
主人公叫葉天明柳韶的小說 瀏覽:74
愛戀一樣電影 瀏覽:661
叮咚浩哥電影叫什麼 瀏覽:675
新世界電訊伺服器怎麼樣 瀏覽:126
美國科幻片機器人 瀏覽:104
韓國推理劇愛情電影 瀏覽:757
電視機上app自動扣費哪裡關 瀏覽:44
影像學pdf 瀏覽:316
教育網電教伺服器是什麼呢 瀏覽:136
小電影網站誰有 瀏覽:327
女主和兩個雙胞胎兄弟 瀏覽:6
備戰方艙老兵給新兵寬心解壓 瀏覽:646
宣城加密加硬珍珠棉生產廠 瀏覽:756