android - trigonometria - triangulo rectangulo
Tratar de dibujar triángulos con textura en el dispositivo falla, pero el emulador funciona. ¿Por qué? (7)
Tengo una serie de llamadas OpenGL-ES que correctamente renderizan un triángulo y lo texturizan con fusión alfa en el emulador (2.0.1). Cuando enciendo el mismo código en un dispositivo real (Droid 2.0.1), todo lo que obtengo son cuadrados blancos.
Esto me sugiere que las texturas no se están cargando, pero no puedo entender por qué no se están cargando. Todas mis texturas son PNG de 32 bits con canales alfa, en res / raw para que no se optimicen según los documentos sdk .
Así es como estoy cargando mis texturas:
private void loadGLTexture(GL10 gl, Context context, int reasource_id, int texture_id)
{
//Get the texture from the Android resource directory
Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), reasource_id, sBitmapOptions);
//Generate one texture pointer...
gl.glGenTextures(1, textures, texture_id);
//...and bind it to our array
gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[texture_id]);
//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);
//Different possible texture parameters, e.g. GL10.GL_CLAMP_TO_EDGE
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);
//Use the 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();
}
Así es como estoy renderizando la textura:
//Clear
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
//Enable vertex buffer
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);
//Push transformation matrix
gl.glPushMatrix();
//Transformation matrices
gl.glTranslatef(x, y, 0.0f);
gl.glScalef(scalefactor, scalefactor, 0.0f);
gl.glColor4f(1.0f,1.0f,1.0f,1.0f);
//Bind the texture
gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[textureid]);
//Draw the vertices as triangles
gl.glDrawElements(GL10.GL_TRIANGLES, indices.length, GL10.GL_UNSIGNED_BYTE, indexBuffer);
//Pop the matrix back to where we left it
gl.glPopMatrix();
//Disable the client state before leaving
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
Y aquí están las opciones que he habilitado:
gl.glShadeModel(GL10.GL_SMOOTH); //Enable Smooth Shading
gl.glEnable(GL10.GL_DEPTH_TEST); //Enables Depth Testing
gl.glDepthFunc(GL10.GL_LEQUAL); //The Type Of Depth Testing To Do
gl.glEnable(GL10.GL_TEXTURE_2D);
gl.glEnable(GL10.GL_BLEND);
gl.glBlendFunc(GL10.GL_SRC_ALPHA,GL10.GL_ONE_MINUS_SRC_ALPHA);
Editar: Acabo de intentar suministrar un BitmapOptions a la llamada BitmapFactory.decodeResource (), pero parece que no soluciona el problema, a pesar de establecer manualmente el mismo preferredconfig, density y targetdensity.
Edit2: según lo solicitado, aquí hay una captura de pantalla del emulador funcionando. Los triángulos subyacentes se muestran con una textura circular representada en él, la transparencia funciona porque puede ver el fondo negro.
eliminado el enlace muerto de ImageShack
Aquí hay una foto de lo que hace el droide con exactamente el mismo código:
eliminado el enlace muerto de ImageShack
Edit3: Aquí están mis BitmapOptions, actualicé la llamada anterior con la forma en que ahora llamo a BitmapFactory, siguen los mismos resultados que a continuación: sBitmapOptions.inPreferredConfig = Bitmap.Config.RGB_565;
sBitmapOptions.inDensity = 160;
sBitmapOptions.inTargetDensity = 160;
sBitmapOptions.inScreenDensity = 160;
sBitmapOptions.inDither = false;
sBitmapOptions.inSampleSize = 1;
sBitmapOptions.inScaled = false;
Aquí están mis vértices, coords de texturas e índices:
/** The initial vertex definition */
private static final float vertices[] = {
-1.0f, -1.0f, 0.0f,
1.0f, -1.0f, 0.0f,
-1.0f, 1.0f, 0.0f,
1.0f, 1.0f, 0.0f
};
/** The initial texture coordinates (u, v) */
private static final float texture[] = {
//Mapping coordinates for the vertices
0.0f, 1.0f,
1.0f, 1.0f,
0.0f, 0.0f,
1.0f, 0.0f
};
/** The initial indices definition */
private static final byte indices[] = {
//Faces definition
0,1,3, 0,3,2
};
¿Hay alguna forma de volcar el contenido de la textura una vez que ha sido cargada en OpenGL ES? ¿Tal vez pueda comparar la textura cargada del emulador con la textura cargada del dispositivo real?
Lo intenté con una textura diferente (el icono predeterminado de Android) y, de nuevo, funciona bien para el emulador pero no se puede representar en el teléfono real.
Edit4: Intenté cambiar cuando cargué texturas. Sin suerte. Intentó usar un desplazamiento constante de 0 a glGenTextures, sin cambios.
¿Hay algo que estoy usando que el emulador admite que el teléfono real no?
Edit5: por Ryan a continuación, cambié el tamaño de mi textura de 200x200 a 256x256, y el problema NO se resolvió.
Editar: según lo solicitado, agregó las llamadas a glVertexPointer y glTexCoordPointer anteriores. Además, aquí está la inicialización de vertexBuffer, textureBuffer e indexBuffer:
ByteBuffer byteBuf = ByteBuffer.allocateDirect(vertices.length * 4);
byteBuf.order(ByteOrder.nativeOrder());
vertexBuffer = byteBuf.asFloatBuffer();
vertexBuffer.put(vertices);
vertexBuffer.position(0);
byteBuf = ByteBuffer.allocateDirect(texture.length * 4);
byteBuf.order(ByteOrder.nativeOrder());
textureBuffer = byteBuf.asFloatBuffer();
textureBuffer.put(texture);
textureBuffer.position(0);
indexBuffer = ByteBuffer.allocateDirect(indices.length);
indexBuffer.put(indices);
indexBuffer.position(0);
loadGLTextures(gl, this.context);
No estoy seguro de cuál es tu problema, soy bastante nuevo en el desarrollo en general, pero mis problemas de OpenGL con la diferencia entre el emulador y el teléfono fueron:
-Emulator puede admitir no 2 ^ x dimensiones para mapas de bits, el teléfono no puede -Emulator volcó la pantalla en NDK para OpenGL así que tuve que usar coordenadas negativas para definir la vista en el emulador, mientras que mi G1 usó las coordenadas no negadas.
Espero que esto pueda ayudarte de alguna manera.
Creo que tal vez tengas problemas para cargar la textura del APK. Intenta copiar la textura en la tarjeta SD y ver si puedes cargarla desde allí.
También soy nuevo en Android OpenGL ES dev. Tengo un Milestone (versión en euros para Droid).
Por lo que puedo ver hasta ahora, disparando varias aplicaciones tutoriales de diferentes libros / sitios web sobre mi hito, parece que este teléfono maneja OpenGL ES de una manera diferente a todos los otros teléfonos Android lanzados hasta ahora.
Creo que está relacionado con las extensiones OpenGL admitidas en el dispositivo.
revise este enlace para ver la lista de las extensiones admitidas, estoy seguro de que un gurú del código encontrará por qué exactamente el droide maneja las páginas abiertas de una manera tan extraña.
http://www.rbgrn.net/content/345-hands-on-motorola-droid-opengl-es-specs
Espero que esto ayude un poco
EDITADO:
Ajusté el manifest.xml y lo noté cuando usé
<uses-sdk android:minSdkVersion="6"/>
los recursos no se están cargando en absoluto.
Cuando usas
<uses-sdk android:minSdkVersion="3"/>
los recursos se cargan bien
Así que cambié a
<uses-sdk android:minSdkVersion="6"/>
y cambió la forma en que se carga el mapa de bits.
Intenta reemplazar:
//Get the texture from the Android resource directory
Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), reasource_id, sBitmapOptions);
con :
InputStream is = context.getResources().openRawResource(your.resource.there);
Bitmap bitmap = null;
try {
bitmap = BitmapFactory.decodeStream(is);
} finally {
//Always clear and close
try {
is.close();
is = null;
} catch (IOException e) {
}
}
Las texturas se están cargando bien en mi hito con ese código, ¡espero que este trabajo sea tuyo!
¿Estás usando la interfaz GL11 en alguna parte? GL11 no es compatible con todos los dispositivos. y también quita la línea glColor, ¿quizás tu textura se muestra pero sobrepintada por el color? aquí algunos fragmentos de código de cómo mostrar mis mallas de textura:
void draw(GL10 gl) {
// Enabled the vertices buffer for writing and to be used during
// rendering.
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
// Specifies the location and data format of an array of vertex
// coordinates to use when rendering.
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
gl.glEnable(GL10.GL_TEXTURE_2D);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER,
GL10.GL_LINEAR);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER,
GL10.GL_LINEAR);
gl.glBindTexture(GL10.GL_TEXTURE_2D, myTextureId);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);
gl.glDrawArrays(drawMode, 0, verticesCount);
gl.glDisable(GL10.GL_TEXTURE_2D);
// Disable the vertices buffer.
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
}
Tuve exactamente este problema cuando pasé de SDK 3 a 4. Mis texturas se mostrarían en el emulador pero no en el dispositivo real (Motorola Milestone / Droid).
Todas tus texturas deben ser poderes binarios de dos. Los míos eran 256x256. Sin embargo, la razón por la que las texturas no se muestran es que el sistema operativo las está escalando desde sus tamaños de potencia binarios para mostrarlas en la pantalla de alta densidad de Milestone.
La solución es fácil: simplemente mueva las texturas al directorio drawable-nodpi y el sistema operativo no las escalará cuando las cargue.
Asegúrese de cargar sus bitmaps con un BitmapConfig apropiado que no esté escalando su imagen detrás de las escenas, porque esto sucede.
Además, ¿hay alguna razón por la que esté almacenando sus pngs en / raw / en lugar de / drawable /?
La respuesta editada de Dullahx resolvió mi problema con el mismo problema. muchas gracias, ¡me estaba molestando los últimos dos días!
Intentaba mapear una textura en la pestaña de Samsung Galaxy, que se mostró con éxito en el emulador, pero solo se mostró el avión en el dispositivo.
Reemplacé mi código:
plane.loadBitmap(BitmapFactory.decodeResource(getResources(),R.drawable.jay));
Con este:
InputStream is = context.getResources().openRawResource(R.drawable.jay);
// Load the texture.
plane.loadBitmap(BitmapFactory.decodeStream(is));
y funcionó en el dispositivo también!
Pero tenga cuidado con minSdkVersion si también está tratando de asignar una textura en un rectángulo de tamaño de pantalla completa como yo. Si uso
<uses-sdk android:minSdkVersion="3"/>
en la pestaña de Samsung Galaxy, mi avión no se mostró en pantalla completa. Se procesó de acuerdo con el tamaño de pantalla completa de un dispositivo con la versión sdk 3. Cambié esto a
<uses-sdk android:minSdkVersion="8"/>
y mi rectángulo de pantalla completa está de vuelta con su textura activada.
Espero que esto ayude, también.