Android 如何将 OpenGL ES 1.0 代码转换为 OpenGL Es 2.0?
How to Convert OpenGL ES 1.0 code to OpenGL Es 2.0 on Android?
我有一个用 OpenGL ES 1.0 编写的代码,使用 GL_LINE_STRIP
绘制一条 20 点的线。我想将代码升级到 OpenGL ES 2.0。代码在3 类:
mainActivity
MyGLRenderer
Shape
我该怎么办?如何设置fragShader
和vertShader
等?
请帮助
代码如下:
mainActivity=
public class mainActivuty extends Activity {
private GLSurfaceView surface;
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
surface = new GLSurfaceView(this);
surface.setEGLContextClientVersion(1);
surface.setRenderer(new MyGLRenderer());
setContentView(surface);
}
public void onPause(){
super.onPause();
surface.onPause();
}
public void onResume() {
super.onResume();
surface.onResume();
}
}
MyGLRenderer=
public class MyGLRenderer implements Renderer {
Shape s;
public MyGLRenderer() {
s = new Shape();
}
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
gl.glClearColor(0.0f, 0.0f, 0.5f, 0.5f);
}
public void onDrawFrame(GL10 gl) {
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
gl.glLoadIdentity();
gl.glTranslatef(0, 0, -8);
s.draw(gl);
}
public void onSurfaceChanged(GL10 gl, int width, int height) {
gl.glViewport(0, 0, width, height);
gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glLoadIdentity();
GLU.gluPerspective(gl, 45.0f, (float) width / (float) height, 0.1f,
100.0f);
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
}
@Override
public void onSurfaceCreated(GL10 arg0, javax.microedition.khronos.egl.EGLConfig arg1) {
// TODO Auto-generated method stub
}
}
和形状=
public class Shape {
float vertices[] = {
-3.14f, -0.00159265f, 0f,
-2.826f, -0.31038f, 0f,
-2.512f, -0.588816f, 0f,
-2.198f, -0.809672f, 0f,
-1.884f, -0.951351f, 0f,
-1.57f, -1f, 0f,
-1.256f, -0.950859f, 0f,
-0.942f, -0.808736f, 0f,
-0.628f, -0.587528f, 0f,
-0.314f, -0.308866f, 0f,
0f, 0f, 0f,
0.314f, 0.308866f, 0f,
0.628f, 0.587528f, 0f,
0.942f, 0.808736f, 0f,
1.256f, 0.950859f, 0f,
1.57f, 1f, 0f,
1.884f, 0.951351f, 0f,
2.198f, 0.809672f, 0f,
2.512f, 0.588816f, 0f,
2.826f, 0.31038f, 0f,
3.14f, 0.00159265f, 0f
};
private short[] indices = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20};
FloatBuffer vertexBuffer;
ShortBuffer indexBuffer;
public Shape() {
ByteBuffer bb = ByteBuffer.allocateDirect(vertices.length * 4);
bb.order(ByteOrder.nativeOrder());
vertexBuffer = bb.asFloatBuffer();
vertexBuffer.put(vertices);
vertexBuffer.position(0);
ByteBuffer bb2=ByteBuffer.allocateDirect(indices.length*2);
bb2.order(ByteOrder.nativeOrder());
indexBuffer=bb2.asShortBuffer();
indexBuffer.put(indices);
indexBuffer.position(0);
}
public void draw(GL10 gl) {
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
gl.glDrawElements(GL10.GL_LINE_STRIP,indices.length,GL10.GL_UNSIGNED_SHORT,indexBuffer);
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
}
}
坦克斯
ES1.x和ES2.x是截然不同的。如果您正在画一条线并且 ES1 对您来说已经足够,那么我的建议是 "don't convert it".
如果这不可能,那么我建议您在 ES2 中开始一个新的 project/module 并使用一些教程来帮助您完成整个过程。从您发布的内容来看,这应该足够快了。
然后只需修改教程项目来执行您需要的操作,或者开始将逻辑从教程复制到您的案例以进行转换。
根据您的代码,一些方法可能已更改,但通常您需要做的是:
- 添加着色器(代码、编译和使用)
- 将矩阵方法移动到着色器中(矩阵不在 GL 中,因此您需要使用其他方法)
- 将指针和客户端状态转换为对应于着色器属性
- 在着色器中添加其他参数,例如颜色
有很多方法可以记下这段代码。这是我以前遇到这个问题时的建议。
您的 mainActivity
不需要太多更改。只是您必须通过更改此行将您的 OpenGL ES 版本更改为 2.0 版: surface.setEGLContextClientVersion(2);
正如您提到的,您还需要两个 classes。 MyGLRenderer
和 Shape
我会在这里 Renderer
和 Shader
clasees。您的 Shader
class 应该有 vertcode
字符串和 fragcode
字符串。你的 Shader
class 应该是这样的:
public class Shader {
private final static String vertcode = "attribute vec4 a_pos;"+
"void main(){"+
"gl_Position = a_pos;" +
"}";
private final static String fragcode = "precision mediump float;" +
"uniform vec4 u_color;"+
"void main(){"+
"gl_FragColor = u_color;"+
"}";
private static int program;
public static int positionhandle;
public static int colorhandle;
public static void makeprogram()
{
int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertcode);
int fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragcode);
program = GLES20.glCreateProgram();
GLES20.glAttachShader(program, vertexShader);
GLES20.glAttachShader(program, fragmentShader);
GLES20.glLinkProgram(program);
positionhandle = GLES20.glGetAttribLocation(program,"a_pos");
colorhandle = GLES20.glGetUniformLocation(program, "u_color");
GLES20.glUseProgram(program);
}
private static int loadShader(int type, String shadertext)
{
int shader = GLES20.glCreateShader(type);
GLES20.glShaderSource(shader, shadertext);
GLES20.glCompileShader(shader);
return shader;
}
}
现在您必须设置您的 Renderer
class,包括您的积分。 public
class Renderer implements GLSurfaceView.Renderer {
private FloatBuffer vertbuffer;
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
tut1.Shader.makeprogram();
GLES20.glEnableVertexAttribArray(tut1.Shader.positionhandle);
float[] verts = {-3.14f, -0.00159265f, 0f,
-2.826f, -0.31038f, 0f,
-2.512f, -0.588816f, 0f,
-2.198f, -0.809672f, 0f,
-1.884f, -0.951351f, 0f,
-1.57f, -1f, 0f,
-1.256f, -0.950859f, 0f,
-0.942f, -0.808736f, 0f,
-0.628f, -0.587528f, 0f,
-0.314f, -0.308866f, 0f,
0f, 0f, 0f,
0.314f, 0.308866f, 0f,
0.628f, 0.587528f, 0f,
0.942f, 0.808736f, 0f,
1.256f, 0.950859f, 0f,
1.57f, 1f, 0f,
1.884f, 0.951351f, 0f,
2.198f, 0.809672f, 0f,
2.512f, 0.588816f, 0f,
2.826f, 0.31038f, 0f,
3.14f, 0.00159265f, 0f
};
vertbuffer = makefloatbuffer(verts);
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
GLES20.glViewport(0, 0, width, height);
}
@Override
public void onDrawFrame(GL10 gl) {
GLES20.glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
GLES20.glUniform4f(tut1.Shader.colorhandle, 1.0f, 0.0f, 0.0f, 1.0f);
GLES20.glVertexAttribPointer(tut1.Shader.positionhandle, 3, GLES20.GL_FLOAT, false, 0, vertbuffer);
GLES20.glDrawArrays(GLES20.GL_LINE_STRIP, 0, 3);
}
public FloatBuffer makefloatbuffer(float[] array) {
FloatBuffer floatbuff = ByteBuffer.allocateDirect(array.length*4).order(ByteOrder.nativeOrder()).asFloatBuffer();
floatbuff.put(array).position(0);
return floatbuff;
}
}
我有一个用 OpenGL ES 1.0 编写的代码,使用 GL_LINE_STRIP
绘制一条 20 点的线。我想将代码升级到 OpenGL ES 2.0。代码在3 类:
mainActivity
MyGLRenderer
Shape
我该怎么办?如何设置fragShader
和vertShader
等?
请帮助
代码如下:
mainActivity=
public class mainActivuty extends Activity {
private GLSurfaceView surface;
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
surface = new GLSurfaceView(this);
surface.setEGLContextClientVersion(1);
surface.setRenderer(new MyGLRenderer());
setContentView(surface);
}
public void onPause(){
super.onPause();
surface.onPause();
}
public void onResume() {
super.onResume();
surface.onResume();
}
}
MyGLRenderer=
public class MyGLRenderer implements Renderer {
Shape s;
public MyGLRenderer() {
s = new Shape();
}
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
gl.glClearColor(0.0f, 0.0f, 0.5f, 0.5f);
}
public void onDrawFrame(GL10 gl) {
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
gl.glLoadIdentity();
gl.glTranslatef(0, 0, -8);
s.draw(gl);
}
public void onSurfaceChanged(GL10 gl, int width, int height) {
gl.glViewport(0, 0, width, height);
gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glLoadIdentity();
GLU.gluPerspective(gl, 45.0f, (float) width / (float) height, 0.1f,
100.0f);
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
}
@Override
public void onSurfaceCreated(GL10 arg0, javax.microedition.khronos.egl.EGLConfig arg1) {
// TODO Auto-generated method stub
}
}
和形状=
public class Shape {
float vertices[] = {
-3.14f, -0.00159265f, 0f,
-2.826f, -0.31038f, 0f,
-2.512f, -0.588816f, 0f,
-2.198f, -0.809672f, 0f,
-1.884f, -0.951351f, 0f,
-1.57f, -1f, 0f,
-1.256f, -0.950859f, 0f,
-0.942f, -0.808736f, 0f,
-0.628f, -0.587528f, 0f,
-0.314f, -0.308866f, 0f,
0f, 0f, 0f,
0.314f, 0.308866f, 0f,
0.628f, 0.587528f, 0f,
0.942f, 0.808736f, 0f,
1.256f, 0.950859f, 0f,
1.57f, 1f, 0f,
1.884f, 0.951351f, 0f,
2.198f, 0.809672f, 0f,
2.512f, 0.588816f, 0f,
2.826f, 0.31038f, 0f,
3.14f, 0.00159265f, 0f
};
private short[] indices = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20};
FloatBuffer vertexBuffer;
ShortBuffer indexBuffer;
public Shape() {
ByteBuffer bb = ByteBuffer.allocateDirect(vertices.length * 4);
bb.order(ByteOrder.nativeOrder());
vertexBuffer = bb.asFloatBuffer();
vertexBuffer.put(vertices);
vertexBuffer.position(0);
ByteBuffer bb2=ByteBuffer.allocateDirect(indices.length*2);
bb2.order(ByteOrder.nativeOrder());
indexBuffer=bb2.asShortBuffer();
indexBuffer.put(indices);
indexBuffer.position(0);
}
public void draw(GL10 gl) {
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
gl.glDrawElements(GL10.GL_LINE_STRIP,indices.length,GL10.GL_UNSIGNED_SHORT,indexBuffer);
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
}
}
坦克斯
ES1.x和ES2.x是截然不同的。如果您正在画一条线并且 ES1 对您来说已经足够,那么我的建议是 "don't convert it".
如果这不可能,那么我建议您在 ES2 中开始一个新的 project/module 并使用一些教程来帮助您完成整个过程。从您发布的内容来看,这应该足够快了。
然后只需修改教程项目来执行您需要的操作,或者开始将逻辑从教程复制到您的案例以进行转换。
根据您的代码,一些方法可能已更改,但通常您需要做的是:
- 添加着色器(代码、编译和使用)
- 将矩阵方法移动到着色器中(矩阵不在 GL 中,因此您需要使用其他方法)
- 将指针和客户端状态转换为对应于着色器属性
- 在着色器中添加其他参数,例如颜色
有很多方法可以记下这段代码。这是我以前遇到这个问题时的建议。
您的 mainActivity
不需要太多更改。只是您必须通过更改此行将您的 OpenGL ES 版本更改为 2.0 版: surface.setEGLContextClientVersion(2);
正如您提到的,您还需要两个 classes。 MyGLRenderer
和 Shape
我会在这里 Renderer
和 Shader
clasees。您的 Shader
class 应该有 vertcode
字符串和 fragcode
字符串。你的 Shader
class 应该是这样的:
public class Shader {
private final static String vertcode = "attribute vec4 a_pos;"+
"void main(){"+
"gl_Position = a_pos;" +
"}";
private final static String fragcode = "precision mediump float;" +
"uniform vec4 u_color;"+
"void main(){"+
"gl_FragColor = u_color;"+
"}";
private static int program;
public static int positionhandle;
public static int colorhandle;
public static void makeprogram()
{
int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertcode);
int fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragcode);
program = GLES20.glCreateProgram();
GLES20.glAttachShader(program, vertexShader);
GLES20.glAttachShader(program, fragmentShader);
GLES20.glLinkProgram(program);
positionhandle = GLES20.glGetAttribLocation(program,"a_pos");
colorhandle = GLES20.glGetUniformLocation(program, "u_color");
GLES20.glUseProgram(program);
}
private static int loadShader(int type, String shadertext)
{
int shader = GLES20.glCreateShader(type);
GLES20.glShaderSource(shader, shadertext);
GLES20.glCompileShader(shader);
return shader;
}
}
现在您必须设置您的 Renderer
class,包括您的积分。 public
class Renderer implements GLSurfaceView.Renderer {
private FloatBuffer vertbuffer;
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
tut1.Shader.makeprogram();
GLES20.glEnableVertexAttribArray(tut1.Shader.positionhandle);
float[] verts = {-3.14f, -0.00159265f, 0f,
-2.826f, -0.31038f, 0f,
-2.512f, -0.588816f, 0f,
-2.198f, -0.809672f, 0f,
-1.884f, -0.951351f, 0f,
-1.57f, -1f, 0f,
-1.256f, -0.950859f, 0f,
-0.942f, -0.808736f, 0f,
-0.628f, -0.587528f, 0f,
-0.314f, -0.308866f, 0f,
0f, 0f, 0f,
0.314f, 0.308866f, 0f,
0.628f, 0.587528f, 0f,
0.942f, 0.808736f, 0f,
1.256f, 0.950859f, 0f,
1.57f, 1f, 0f,
1.884f, 0.951351f, 0f,
2.198f, 0.809672f, 0f,
2.512f, 0.588816f, 0f,
2.826f, 0.31038f, 0f,
3.14f, 0.00159265f, 0f
};
vertbuffer = makefloatbuffer(verts);
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
GLES20.glViewport(0, 0, width, height);
}
@Override
public void onDrawFrame(GL10 gl) {
GLES20.glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
GLES20.glUniform4f(tut1.Shader.colorhandle, 1.0f, 0.0f, 0.0f, 1.0f);
GLES20.glVertexAttribPointer(tut1.Shader.positionhandle, 3, GLES20.GL_FLOAT, false, 0, vertbuffer);
GLES20.glDrawArrays(GLES20.GL_LINE_STRIP, 0, 3);
}
public FloatBuffer makefloatbuffer(float[] array) {
FloatBuffer floatbuff = ByteBuffer.allocateDirect(array.length*4).order(ByteOrder.nativeOrder()).asFloatBuffer();
floatbuff.put(array).position(0);
return floatbuff;
}
}