导航:首页 > 操作系统 > 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绘图相关的资料

热点内容
老板咨询阿里云还是独立服务器 浏览:812
诺基亚手机app哪里下载 浏览:520
看比赛用哪个app 浏览:976
如何评价如故app 浏览:151
建立表结构的命令 浏览:581
安卓文件为什么苹果手机打不开 浏览:84
东奥轻4可以在哪个app做题 浏览:165
金融科技加密卡 浏览:837
程序员那么开一共有多少集 浏览:982
面试程序员被问数学问题怎么办 浏览:93
背大学英语的app哪个最好 浏览:721
哪个app买的衣服好 浏览:469
天刀以前玩过的服务器忘了怎么办 浏览:213
单片机基础代码解读 浏览:235
广东青少年编程学习 浏览:511
买男士香水去哪个app 浏览:550
androidsleep函数 浏览:153
android内核代码下载 浏览:665
服务器如何添加墨迹 浏览:747
diglinux安装 浏览:279