我需要在同一个Square上放置2个纹理,但是当我运行应用程序时它会不断崩溃。我该怎么办?我必须使用2个不同的“上下文”变量吗?我是否必须制作Square类的2个实例(每个纹理一个)? 我的渲染器:
public class HelloOpenGLES10Renderer implements Renderer {
private Square square; // the square
private Context context;
private Context context2;
/** Constructor to set the handed over context */
public HelloOpenGLES10Renderer(Context context) {
this.square = new Square();
this.context=context;
this.context2=context2;
}
public void onDrawFrame(GL10 gl) {
// clear Screen and Depth Buffer
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
// Reset the Modelview Matrix
gl.glLoadIdentity();
// Drawing
gl.glTranslatef(0.0f, 0.0f, -5.0f); // move 5 units INTO the screen
square.loadGLTexture(gl, this.context,Square.getSex());
square.loadGLTexture(gl, this.context2,Square.getHair()); // is the same as moving the camera 5 units away
square.draw(gl); // Draw the triangle
}
我没有发布我的onsurfacechanged和onsurfacecreated。
My Square课程: 公共阶层广场{
private FloatBuffer vertexBuffer; // buffer holding the vertices
private static int sex=2130837504;
private static int hair=2130837511;
private FloatBuffer textureBuffer;
private FloatBuffer textureBuffer2;// buffer holding the texture coordinates
private float texture[] = {
// Mapping coordinates for the vertices
0.0f, 1.0f, // top left (V2)
0.0f, 0.0f, // bottom left (V1)
1.0f, 1.0f, // top right (V4)
1.0f, 0.0f // bottom right (V3)
};
private float texture2[] = {
// Mapping coordinates for the vertices
0.0f, 0.5f, // top left (V2)
0.0f, 0.0f, // bottom left (V1)
0.5f, 0.5f, // top right (V4)
0.5f, 0.0f // bottom right (V3)
};
private float vertices[] = {
-1.0f, -2.0f, 0.0f, // V1 - bottom left
-1.0f, 2.0f, 0.0f, // V2 - top left
0.8f, -2.0f, 0.0f, // V3 - bottom right
0.8f, 2.0f, 0.0f // V4 - top right
};
public Square() {
ByteBuffer byteBuffer = ByteBuffer.allocateDirect(vertices.length * 4);
byteBuffer.order(ByteOrder.nativeOrder());
vertexBuffer = byteBuffer.asFloatBuffer();
vertexBuffer.put(vertices);
vertexBuffer.position(0);
byteBuffer = ByteBuffer.allocateDirect(texture.length * 4);
byteBuffer.order(ByteOrder.nativeOrder());
textureBuffer = byteBuffer.asFloatBuffer();
textureBuffer.put(texture);
textureBuffer.position(0);
byteBuffer = ByteBuffer.allocateDirect(texture2.length * 4);
byteBuffer.order(ByteOrder.nativeOrder());
textureBuffer2 = byteBuffer.asFloatBuffer();
textureBuffer2.put(texture2);
textureBuffer2.position(0);
}
/** The draw method for the square with the GL context */
public void draw(GL10 gl) {
// bind the previously generated texture
gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);
// Point to our buffers
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
// Set the face rotation
gl.glFrontFace(GL10.GL_CW);
// Point to our vertex buffer
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);
// Draw the vertices as triangle strip
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, vertices.length / 3);
//Disable the client state before leaving
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
}
/** The texture pointer */
private int[] textures = new int[1];
public void loadGLTexture(GL10 gl, Context context,int sex ) {
// loading texture
Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(),
sex);
// generate one texture pointer
gl.glGenTextures(1, textures, 0);
// ...and bind it to our array
gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);
// create nearest filtered texture
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
// Use Android GLUtils to specify a two-dimensional texture image from our bitmap
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
// Clean up
bitmap.recycle();
}
public void loadGLTextureHair(GL10 gl, Context context,int hair ) {
// loading texture
Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(),
sex);
// generate one texture pointer
gl.glGenTextures(1, textures, 0);
// ...and bind it to our array
gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);
// create nearest filtered texture
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
// Use Android GLUtils to specify a two-dimensional texture image from our bitmap
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
// Clean up
bitmap.recycle();
}
public static int getSex() {
return sex;
}
public static void setSex(int sex) {
Square.sex = sex;
}
public static int getHair() {
return hair;
}
public static void setHair(int hair) {
Square.hair = hair;
}
}
logcat的:
06-26 10:15:10.320: D/dalvikvm(280): GC_EXTERNAL_ALLOC freed 923 objects / 64552 bytes in 83ms
06-26 10:15:10.921: D/libEGL(280): egl.cfg not found, using default config
06-26 10:15:10.921: D/libEGL(280): loaded /system/lib/egl/libGLES_android.so
06-26 10:15:11.260: I/ARMAssembler(280): generated scanline__000001B7:030101C1_00009501_00000000 [142 ipp] (234 ins) at [0x23a918:0x23acc0] in 5769170 ns
06-26 10:15:13.170: W/KeyCharacterMap(280): No keyboard for id 0
06-26 10:15:13.170: W/KeyCharacterMap(280): Using default keymap: /system/usr/keychars/qwerty.kcm.bin
06-26 10:15:29.020: D/dalvikvm(312): GC_EXTERNAL_ALLOC freed 945 objects / 65408 bytes in 72ms
06-26 10:15:29.560: D/libEGL(312): egl.cfg not found, using default config
06-26 10:15:29.570: D/libEGL(312): loaded /system/lib/egl/libGLES_android.so
06-26 10:15:29.860: I/ARMAssembler(312): generated scanline__000001B7:030101C1_00009501_00000000 [142 ipp] (234 ins) at [0x23a830:0x23abd8] in 2951633 ns
06-26 10:15:54.629: W/KeyCharacterMap(312): No keyboard for id 0
06-26 10:15:54.639: W/KeyCharacterMap(312): Using default keymap: /system/usr/keychars/qwerty.kcm.bin
06-26 11:21:50.350: D/dalvikvm(344): GC_EXTERNAL_ALLOC freed 967 objects / 66264 bytes in 75ms
06-26 11:21:50.950: D/libEGL(344): egl.cfg not found, using default config
06-26 11:21:50.950: D/libEGL(344): loaded /system/lib/egl/libGLES_android.so
06-26 11:21:51.290: I/ARMAssembler(344): generated scanline__000001B7:030101C1_00009501_00000000 [142 ipp] (234 ins) at [0x23a830:0x23abd8] in 12307152 ns
06-26 11:22:01.749: W/KeyCharacterMap(344): No keyboard for id 0
06-26 11:22:01.749: W/KeyCharacterMap(344): Using default keymap: /system/usr/keychars/qwerty.kcm.bin
06-26 11:48:39.200: D/dalvikvm(371): GC_EXTERNAL_ALLOC freed 989 objects / 67120 bytes in 69ms
06-26 11:48:39.750: D/libEGL(371): egl.cfg not found, using default config
06-26 11:48:39.759: D/libEGL(371): loaded /system/lib/egl/libGLES_android.so
06-26 11:48:40.079: W/dalvikvm(371): threadid=7: thread exiting with uncaught exception (group=0x4001d800)
06-26 11:48:40.109: E/AndroidRuntime(371): FATAL EXCEPTION: GLThread 8
06-26 11:48:40.109: E/AndroidRuntime(371): java.lang.NullPointerException
06-26 11:48:40.109: E/AndroidRuntime(371): at hello.project.Square.loadGLTexture(Square.java:96)
06-26 11:48:40.109: E/AndroidRuntime(371): at hello.project.HelloOpenGLES10Renderer.onDrawFrame(HelloOpenGLES10Renderer.java:34)
06-26 11:48:40.109: E/AndroidRuntime(371): at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1332)
06-26 11:48:40.109: E/AndroidRuntime(371): at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1116)
06-26 11:48:42.879: I/Process(371): Sending signal. PID: 371 SIG: 9
答案 0 :(得分:1)
我几乎可以肯定你得到了NullPointerException
因为BitmapFactory
找不到你指定的资源ID,所以Bitmap
变成了null
,从而引发了异常当你尝试recycle()
时。
您应该从生成的private static int sex=2130837504;
类中获取值R
,而不是将id作为静态变量(BitmapFactory.decodeResource(context.getResources(), R.drawable.sex);
)使用。
除此之外,您的代码还有一些初学者问题:
您只需要一个Context
个对象。
你不需要两种不同的方法来加载纹理(loadGLTextureHair
(有另一个错误,它应该使用参数hair,而不是sex)和loadGLTexture
):
public void loadGLTexture(GL10 gl, Context context, int resourceId) {
Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), resourceId);
gl.glGenTextures(1, textures, 0);
gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
gl.gltexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_REPEAT);
gl.gltexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_REPEAT);
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
bitmap.recycle();
}
您应该使用onSurfaceCreated()
方法调用此方法,如果您从onDrawFrame()
调用它,则每帧都会加载一个新纹理,并且内存不足。
要在纹理之间切换,请使用glBindTexture()
方法。
3.由于您没有将纹理[]中的值保存在其他地方,因此下次加载纹理时会覆盖它。
这些是我能看到的最明显的错误,如果你修复它们,你的程序至少应该运行。继续阅读大量的教程和示例,直到你得到它:)