OpenGL-ES を使用して Android 用のゲームの作成を開始し、glDrawTexfOES 拡張機能を使用する描画コードを完成させました。エミュレーターでテストしたところ正常に動作しましたが、Samsung Galaxy S2 でテストしたところ、すべてのテクスチャが白く描かれているようです。
間違いを犯していないことを確認するために、チュートリアルからソースをコピーし、同じ結果で実行しました。私が使用しているチュートリアル コードは、ここで見ることができます。
私のテクスチャは .PNG 形式で 2 のべき乗であり、R.drawable フォルダーからロードしていますが、提案されているように drawable-nodpi などの他の場所をいくつか試しました。
私が読んだ glGenTextures の結果も確認しましたが、特定の電話で奇数の値を与える可能性がありますが、正しい値 (1,2,3..) を与えているようです。
なぜこれが起こっているのか、または何がうまくいかないのかを理解するために私ができる他のチェックを提案している人はいますか?
これは、上でリンクしたサンプル コードを簡単にするために少し変更したバージョンです。
public void onSurfaceCreated(GL10 gl10, EGLConfig eglConfig) {
gl10.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);
// Set the background colour to black ( rgba ).
gl10.glClearColor(0.0f, 0.0f, 0.0f, 1);
// Enable Flat Shading.
gl10.glShadeModel(GL10.GL_FLAT);
// We don't need to worry about depth testing!
gl10.glDisable(GL10.GL_DEPTH_TEST);
// Set OpenGL to optimise for 2D Textures
gl10.glEnable(GL10.GL_TEXTURE_2D);
// Disable 3D specific features.
gl10.glDisable(GL10.GL_DITHER);
gl10.glDisable(GL10.GL_LIGHTING);
gl10.glTexEnvx(GL10.GL_TEXTURE_ENV, GL10.GL_TEXTURE_ENV_MODE, GL10.GL_MODULATE);
// Initial clear of the screen.
gl10.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
// Test for draw texture
// Test for device specific extensions
String extensions = gl10.glGetString(GL10.GL_EXTENSIONS);
boolean drawTexture = extensions.contains("draw_texture");
Log.i("OpenGL Support - ver.:",
gl10.glGetString(GL10.GL_VERSION) + " renderer:" +
gl10.glGetString(GL10.GL_RENDERER) + " : " +
(drawTexture ? "good to go!" : "forget it!!"));
// LOAD TEXTURE
mTextureName = new int[1];
// Generate Texture ID
gl10.glGenTextures(1, mTextureName, 0);
assert gl10.glGetError() == GL10.GL_NO_ERROR;
// Bind texture id / target (we want 2D of course)
gl10.glBindTexture(GL10.GL_TEXTURE_2D, mTextureName[0]);
// Open and input stream and read the image
InputStream is = mContext.getResources().openRawResource(R.drawable.asteroid);
Bitmap bitmap;
try {
bitmap = BitmapFactory.decodeStream(is);
} finally {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
// Build our crop region to be the size of the bitmap (ie full image)
mCrop = new int[4];
mCrop[0] = 0;
mCrop[1] = imageHeight = bitmap.getHeight();
mCrop[2] = imageWidth = bitmap.getWidth();
mCrop[3] = -bitmap.getHeight();
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
assert gl10.glGetError() == GL10.GL_NO_ERROR;
bitmap.recycle();
}
public void onSurfaceChanged(GL10 gl10, int i, int i1) {
gl10.glViewport(0, 0, i, i1);
/*
* Set our projection matrix. This doesn't have to be done each time we
* draw, but usually a new projection needs to be set when the viewport
* is resized.
*/
float ratio = (float) i / i1;
gl10.glMatrixMode(GL10.GL_PROJECTION);
gl10.glLoadIdentity();
gl10.glFrustumf(-ratio, ratio, -1, 1, 1, 10);
}
public void onDrawFrame(GL10 gl) {
// Just clear the screen and depth buffer.
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
// Begin drawing
//--------------
// These function calls can be experimented with for various effects such as transparency
// although certain functionality maybe device specific.
gl.glShadeModel(GL10.GL_FLAT);
gl.glEnable(GL10.GL_BLEND);
gl.glBlendFunc(GL10.GL_ONE, GL10.GL_ONE_MINUS_SRC_ALPHA);
gl.glColor4x(0x10000, 0x10000, 0x10000, 0x10000);
// Setup correct projection matrix
gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glPushMatrix();
gl.glLoadIdentity();
gl.glOrthof(0.0f, mWidth, 0.0f, mHeight, 0.0f, 1.0f);
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glPushMatrix();
gl.glLoadIdentity();
gl.glEnable(GL10.GL_TEXTURE_2D);
// Draw all Textures
gl.glBindTexture(GL10.GL_TEXTURE_2D, mTextureName[0]);
((GL11)gl).glTexParameteriv(GL10.GL_TEXTURE_2D, GL11Ext.GL_TEXTURE_CROP_RECT_OES, mCrop, 0);
((GL11Ext)gl).glDrawTexfOES(0, 0, 0, imageWidth, imageHeight);
// Finish drawing
gl.glDisable(GL10.GL_BLEND);
gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glPopMatrix();
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glPopMatrix();
}