尝试通过 OpenGL 渲染位图,但位图不可见
Trying to render a bitmap through OpenGL but the bitmap is not visible
这是 MyGLSurfaceView:
public class MyGLSurfaceView extends GLSurfaceView {
public final MyGLRenderer mRenderer;
public MyGLRenderer getmRenderer() {
return mRenderer;
}
public MyGLSurfaceView(Context context){
super(context);
// Create an OpenGL ES 2.0 context
setEGLContextClientVersion(2);
mRenderer = new MyGLRenderer(context);
// Set the Renderer for drawing on the GLSurfaceView
setRenderer(mRenderer);
setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
}
}
这是我的渲染器:
public class MyGLRenderer implements GLSurfaceView.Renderer {
private Triangle mTriangle;
private int[] textures;
Context context;
private static final float[] VERTEX_COORDINATES = new float[] {
-1.0f, +1.0f, 0.0f,
+1.0f, +1.0f, 0.0f,
-1.0f, -1.0f, 0.0f,
+1.0f, -1.0f, 0.0f
};
private static final float[] TEXTURE_COORDINATES = new float[] {
0.0f, 0.0f,
1.0f, 0.0f,
0.0f, 1.0f,
1.0f, 1.0f
};
public MyGLRenderer(Context context) {
this.context = context;
}
private static final Buffer TEXCOORD_BUFFER = ByteBuffer.allocateDirect(TEXTURE_COORDINATES.length * 4)
.order(ByteOrder.nativeOrder()).asFloatBuffer().put(TEXTURE_COORDINATES).rewind();
private static final Buffer VERTEX_BUFFER = ByteBuffer.allocateDirect(VERTEX_COORDINATES.length * 4)
.order(ByteOrder.nativeOrder()).asFloatBuffer().put(VERTEX_COORDINATES).rewind();
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
// Set the background frame color
Log.i("","MyGLRenderer onSurfaceCreated");
GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
mTriangle = new Triangle();
textures = new int[1];
gl.glEnable(GL10.GL_TEXTURE_2D);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
gl.glGenTextures(1, textures, 0);
gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_CLAMP_TO_EDGE);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_CLAMP_TO_EDGE);
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, BitmapFactory.decodeResource(context.getResources(), R.drawable.ic_launcher), 0);
}
public void onDrawFrame(GL10 gl) {
Log.i("","MyGLRenderer onDrawFrame");
// Redraw background color
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
mTriangle.draw();
gl.glActiveTexture(GL10.GL_TEXTURE0);
gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, VERTEX_BUFFER);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, TEXCOORD_BUFFER);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
}
public void onSurfaceChanged(GL10 unused, int width, int height) {
Log.i("","MyGLRenderer onSurfaceChanged");
GLES20.glViewport(0, 0, width, height);
}
public static int loadShader(int type, String shaderCode){
Log.i("","MyGLRenderer loadShader");
// create a vertex shader type (GLES20.GL_VERTEX_SHADER)
// or a fragment shader type (GLES20.GL_FRAGMENT_SHADER)
int shader = GLES20.glCreateShader(type);
// add the source code to the shader and compile it
GLES20.glShaderSource(shader, shaderCode);
GLES20.glCompileShader(shader);
return shader;
}
}
现在我检查并调用了 onSurfaceCreated。在那之后,onDrawFrame 被调用,所以我认为这应该已经为我绘制了位图,但为什么它不可见?
我确实使用本教程设法解决了这个问题,并从一开始就创建了渲染器:
https://blog.jayway.com/2010/12/30/opengl-es-tutorial-for-android-part-vi-textures/
我为我的位图创建了一个网格,然后我像这样绘制它们:
public void onDrawFrame(GL10 gl) {
Log.i("", "RENDERER onDrawFrame");
// Clears the screen and depth buffer.
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
// Replace the current matrix with the identity matrix
gl.glLoadIdentity();
// Translates 4 units into the screen.
gl.glTranslatef(0, 0, -1);
// Draw our scene.
try {
if (root != null)
root.draw(gl);
if (rootSelf != null) {
rootSelf.x = 0.35f;
rootSelf.y = -0.1f;
rootSelf.draw(gl);
}
}catch (Exception e){
Log.e("","error is: " + e.getMessage());
}
}
其中 root 和 rootSelf 是我的 Mesh 的实例 class
在 MainActivity 的 OnCreate() 方法中将 GlSurfaceView 对象设置为 contentView
GLSurfaceView glSurfaceView = new GLSurfaceView(this);
glSurfaceView.setEGLContextClientVersion(1);
glSurfaceView.setRenderer(new BitmapRenderer(getResources()));
glSurfaceView.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
setContentView(glSurfaceView);
这是 MyGLSurfaceView:
public class MyGLSurfaceView extends GLSurfaceView {
public final MyGLRenderer mRenderer;
public MyGLRenderer getmRenderer() {
return mRenderer;
}
public MyGLSurfaceView(Context context){
super(context);
// Create an OpenGL ES 2.0 context
setEGLContextClientVersion(2);
mRenderer = new MyGLRenderer(context);
// Set the Renderer for drawing on the GLSurfaceView
setRenderer(mRenderer);
setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
}
}
这是我的渲染器:
public class MyGLRenderer implements GLSurfaceView.Renderer {
private Triangle mTriangle;
private int[] textures;
Context context;
private static final float[] VERTEX_COORDINATES = new float[] {
-1.0f, +1.0f, 0.0f,
+1.0f, +1.0f, 0.0f,
-1.0f, -1.0f, 0.0f,
+1.0f, -1.0f, 0.0f
};
private static final float[] TEXTURE_COORDINATES = new float[] {
0.0f, 0.0f,
1.0f, 0.0f,
0.0f, 1.0f,
1.0f, 1.0f
};
public MyGLRenderer(Context context) {
this.context = context;
}
private static final Buffer TEXCOORD_BUFFER = ByteBuffer.allocateDirect(TEXTURE_COORDINATES.length * 4)
.order(ByteOrder.nativeOrder()).asFloatBuffer().put(TEXTURE_COORDINATES).rewind();
private static final Buffer VERTEX_BUFFER = ByteBuffer.allocateDirect(VERTEX_COORDINATES.length * 4)
.order(ByteOrder.nativeOrder()).asFloatBuffer().put(VERTEX_COORDINATES).rewind();
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
// Set the background frame color
Log.i("","MyGLRenderer onSurfaceCreated");
GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
mTriangle = new Triangle();
textures = new int[1];
gl.glEnable(GL10.GL_TEXTURE_2D);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
gl.glGenTextures(1, textures, 0);
gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_CLAMP_TO_EDGE);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_CLAMP_TO_EDGE);
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, BitmapFactory.decodeResource(context.getResources(), R.drawable.ic_launcher), 0);
}
public void onDrawFrame(GL10 gl) {
Log.i("","MyGLRenderer onDrawFrame");
// Redraw background color
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
mTriangle.draw();
gl.glActiveTexture(GL10.GL_TEXTURE0);
gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, VERTEX_BUFFER);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, TEXCOORD_BUFFER);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
}
public void onSurfaceChanged(GL10 unused, int width, int height) {
Log.i("","MyGLRenderer onSurfaceChanged");
GLES20.glViewport(0, 0, width, height);
}
public static int loadShader(int type, String shaderCode){
Log.i("","MyGLRenderer loadShader");
// create a vertex shader type (GLES20.GL_VERTEX_SHADER)
// or a fragment shader type (GLES20.GL_FRAGMENT_SHADER)
int shader = GLES20.glCreateShader(type);
// add the source code to the shader and compile it
GLES20.glShaderSource(shader, shaderCode);
GLES20.glCompileShader(shader);
return shader;
}
}
现在我检查并调用了 onSurfaceCreated。在那之后,onDrawFrame 被调用,所以我认为这应该已经为我绘制了位图,但为什么它不可见?
我确实使用本教程设法解决了这个问题,并从一开始就创建了渲染器:
https://blog.jayway.com/2010/12/30/opengl-es-tutorial-for-android-part-vi-textures/
我为我的位图创建了一个网格,然后我像这样绘制它们:
public void onDrawFrame(GL10 gl) {
Log.i("", "RENDERER onDrawFrame");
// Clears the screen and depth buffer.
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
// Replace the current matrix with the identity matrix
gl.glLoadIdentity();
// Translates 4 units into the screen.
gl.glTranslatef(0, 0, -1);
// Draw our scene.
try {
if (root != null)
root.draw(gl);
if (rootSelf != null) {
rootSelf.x = 0.35f;
rootSelf.y = -0.1f;
rootSelf.draw(gl);
}
}catch (Exception e){
Log.e("","error is: " + e.getMessage());
}
}
其中 root 和 rootSelf 是我的 Mesh 的实例 class
在 MainActivity 的 OnCreate() 方法中将 GlSurfaceView 对象设置为 contentView
GLSurfaceView glSurfaceView = new GLSurfaceView(this);
glSurfaceView.setEGLContextClientVersion(1);
glSurfaceView.setRenderer(new BitmapRenderer(getResources()));
glSurfaceView.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
setContentView(glSurfaceView);