Pregunta

Actualmente estoy desarrollando una pequeña OpenGL juego para la plataforma Android y me pregunto si hay una manera fácil de procesar el texto en la parte superior de la frame (como un HUD con la puntuación de los jugadores, etc).El texto tendría que utilizar una fuente personalizada, también.

He visto un ejemplo con una Vista como una superposición, pero no sé si quiero hacer eso ya que yo podría adaptar el juego a otras plataformas más adelante.

Alguna idea?

¿Fue útil?

Solución

El SDK de Android no viene con ninguna manera fácil de dibujar texto en vistas de OpenGL. dejándole con las siguientes opciones.

  1. Colocar una TextView sobre su SurfaceView. Esto es lento y malo, pero el enfoque más directo.
  2. Render cadenas comunes a las texturas, y simplemente dibujar las texturas. Este es por lejos el más simple y más rápido, pero el menos flexible.
  3. liar su propio código de representación de texto basado en un sprite. Probablemente segunda mejor opción si 2 no es una opción. Una buena manera de conseguir sus pies mojados, pero tenga en cuenta que aunque parece sencillo (y rasgos básicos son), que de obtener más y más difícil a medida que agrega más características (textura de la alineación, que trata de saltos de línea, fuentes de ancho variable, etc. ) - si se toma esta ruta, que sea tan simple como usted puede conseguir lejos con
  4. Utilice una biblioteca de off-the-shelf / de código abierto. Hay algunos en torno a si usted busca en Google, el truco es conseguir integrada y funcionando. Pero por lo menos, una vez que se hace eso, usted tendrá toda la flexibilidad y la madurez que proporcionan.

Otros consejos

representación de texto a una textura es más simple de lo que el texto de demostración Sprite hacen que parece, la idea básica es utilizar la clase Canvas para rendir a un mapa de bits y luego pasar el mapa de bits a una textura de OpenGL:

// Create an empty, mutable bitmap
Bitmap bitmap = Bitmap.createBitmap(256, 256, Bitmap.Config.ARGB_4444);
// get a canvas to paint over the bitmap
Canvas canvas = new Canvas(bitmap);
bitmap.eraseColor(0);

// get a background image from resources
// note the image format must match the bitmap format
Drawable background = context.getResources().getDrawable(R.drawable.background);
background.setBounds(0, 0, 256, 256);
background.draw(canvas); // draw the background to our bitmap

// Draw the text
Paint textPaint = new Paint();
textPaint.setTextSize(32);
textPaint.setAntiAlias(true);
textPaint.setARGB(0xff, 0x00, 0x00, 0x00);
// draw the text centered
canvas.drawText("Hello World", 16,112, textPaint);

//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);

//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();

He escrito un tutorial que se expande sobre la respuesta publicado por JVitela . Básicamente, se utiliza la misma idea, pero en lugar de la prestación de cada cuerda a una textura, que hace que todos los caracteres de un archivo de fuente a una textura y la usa para permitir la representación de texto dinámico completo sin más retrasos (una vez que se complete la inicialización) .

La principal ventaja de mi método, en comparación con los diversos generadores atlas de fuente, es que se puede enviar pequeños archivos de fuentes (.ttf .otf) con su proyecto en lugar de tener que enviar grandes mapas de bits para cada variación y tamaño de fuente. Puede generar fuentes de calidad perfecta en cualquier resolución usando solamente un archivo de fuente:)

El tutorial incluye código completo que se puede utilizar en cualquier proyecto:)

De acuerdo a este enlace:

http://code.neenbedankt.com/how-to-render-an-android-view-to-a-bitmap

Usted puede hacer cualquier punto de Vista para un mapa de bits.Es probablemente vale la pena suponiendo que usted puede ubicar un punto de vista que usted necesita (incluyendo texto, imágenes, etc.) y, a continuación, volverlo a un mapa de bits.

El uso de JVitela del código por encima de usted debe ser capaz de usar ese mapa de bits como una textura de OpenGL.

Tome un vistazo a CBFG y el puerto androide del código de carga / prestación. Usted debe ser capaz de soltar el código en su proyecto y usar de inmediato.

CBFG - http://www.codehead.co.uk/cbfg

cargador de Android - http://www.codehead.co.uk/cbfg/TexFont.java

Miré el ejemplo de texto de sprites y se ve muy complicado para tal tarea, he considerado la representación de una textura demasiado, pero estoy preocupado por el impacto en el rendimiento que pueda causar. Yo sólo podría tener que ir con una vista en lugar y se preocupan por portar cuando es el momento de cruzar ese puente:)

Mira el "Sprite de texto" muestra en el GLSurfaceView muestras .

En mi humilde opinión hay tres razones para utilizar OpenGL ES en un juego:

  1. evitar diferencias entre plataformas móviles mediante el uso de un estándar abierto;
  2. Para tener un mayor control del proceso de render;
  3. Para beneficiarse de procesamiento paralelo GPU;

Dibujo texto es siempre un problema en el diseño del juego, debido a que está dibujando cosas, por lo que no se puede tener la apariencia de una actividad común, con widgets y así sucesivamente.

Puede utilizar un marco para generar fuentes de mapa de bits a partir de fuentes TrueType y hacerlos. Todos los marcos que he visto operan de la misma manera: generan el vértice y coordenadas de textura para el texto en el sorteo. Este no es el uso más eficiente de OpenGL.

La mejor manera es asignar tampones (objetos de vértice tampón - OISCIV) remotos. Para los vértices y texturas temprano en código, evitando las operaciones de transferencia de memoria perezosos en el tiempo sorteo

Tenga en cuenta que los jugadores no les gusta leer el texto, por lo que no va a escribir un texto largo generada dinámicamente. Para las etiquetas, puede utilizar texturas estáticas, dejando de texto dinámico para el tiempo y la puntuación, y ambos son numéricos con unos pocos caracteres.

Por lo tanto, mi solución es simple:

  1. Crear textura para etiquetas y advertencias comunes;
  2. Crear textura para los números 0-9, ":", "+" y "-". Una textura para cada personaje;
  3. Generar OISCIV a distancia para todas las posiciones en la pantalla. Puedo representar el texto estático o dinámico en el que las posiciones, pero los OISCIV son estáticas;
  4. Generar sólo una textura VBO, como texto siempre se hace de una manera;
  5. En tiempo de empate, se renderiza el texto estático;
  6. En el texto dinámico, que puede mirar en la posición VBO, conseguir la textura carácter y dibujarlo, un carácter a la vez.

Draw operaciones son rápidos, si se utiliza amortiguadores estáticos remoto.

se crea un archivo XML con posiciones de la pantalla (en base a porcentaje en diagonal de la pantalla) y texturas (estáticas y caracteres), y luego se me carga esta XML antes de la representación.

Para obtener una alta tasa de FPS, se debe evitar la generación de OISCIV durante el sorteo.

Si usted insiste en el uso de GL, podría representar el texto a texturas. Suponiendo que la mayor parte del HUD es relativamente estático, que no debería tener que cargar las texturas a la memoria de textura demasiado a menudo.

Tome un vistazo a CBFG y el puerto Android de la carga / prestación código. Usted debe ser capaz de soltar el código en su proyecto y utilizarlo enseguida.

  1. CBFG

  2. cargador de Android

tengo problemas con esta aplicación. Se muestra sólo un carácter, cuando intento hacer cambiar el tamaño del mapa de bits de la fuente (Necesito letras especiales) sorteo todo falla: (

He estado buscando esto durante unas horas, este fue el primer artículo que encontré con y aunque tiene la mejor respuesta, las respuestas más populares que creo que son de la marca. Ciertamente, para lo que necesitaba. Weichsel de respuestas y de shakazed tenían razón en el botón, pero un poco oscurecida en los artículos. Para poner derecho a un proyecto. Aquí: Basta con crear un nuevo proyecto basado en Android muestra existente. Elija ApiDemos:

Mira debajo de la carpeta de origen

ApiDemos/src/com/example/android/apis/graphics/spritetext

Y usted encontrará todo lo que necesita.

texto estático

  • Generar una imagen con todas las palabras que se usan en su PC (por ejemplo con GIMP).
  • Cargar esto como una textura y usarlo como material para un avión.

texto largo que necesita ser actualizada de vez en cuando:

  • Que sorteo androide en un lienzo de mapa de bits (solución de JVitela).
  • Cargar este como material para un avión.
  • Uso textura diferente coordenadas de cada palabra.

En un número (formateado 00,0):

  • Generar una imagen con todos los números y un punto.
  • Cargar este como material para un avión.
  • Uso debajo de sombreado.
  • En el caso onDraw solamente actualizar la variable de valor enviado al sombreado.

    precision highp float;
    precision highp sampler2D;
    
    uniform float uTime;
    uniform float uValue;
    uniform vec3 iResolution;
    
    varying vec4 v_Color;
    varying vec2 vTextureCoord;
    uniform sampler2D s_texture;
    
    void main() {
    
    vec4 fragColor = vec4(1.0, 0.5, 0.2, 0.5);
    vec2 uv = vTextureCoord;
    
    float devisor = 10.75;
    float digit;
    float i;
    float uCol;
    float uRow;
    
    if (uv.y < 0.45) {
        if (uv.x > 0.75) {
            digit = floor(uValue*10.0);
            digit = digit - floor(digit/10.0)*10.0;
            i = 48.0 - 32.0 + digit;
            uRow = floor(i / 10.0);
            uCol = i - 10.0 * uRow;
            fragColor = texture2D( s_texture, uv / devisor * 2.0 + vec2((uCol-1.5) / devisor, uRow / devisor) );
        } else if (uv.x > 0.5) {
            uCol = 4.0;
            uRow = 1.0;
            fragColor = texture2D( s_texture, uv / devisor * 2.0 + vec2((uCol-1.0) / devisor, uRow / devisor) );
        } else if (uv.x > 0.25) {
            digit = floor(uValue);
            digit = digit - floor(digit/10.0)*10.0;
            i = 48.0 - 32.0 + digit;
            uRow = floor(i / 10.0);
            uCol = i - 10.0 * uRow;
            fragColor = texture2D( s_texture, uv / devisor * 2.0 + vec2((uCol-0.5) / devisor, uRow / devisor) );
        } else if (uValue >= 10.0) {
            digit = floor(uValue/10.0);
            digit = digit - floor(digit/10.0)*10.0;
            i = 48.0 - 32.0 + digit;
            uRow = floor(i / 10.0);
            uCol = i - 10.0 * uRow;
            fragColor = texture2D( s_texture, uv / devisor * 2.0 + vec2((uCol-0.0) / devisor, uRow / devisor) );
        } else {
            fragColor = vec4(0.0, 0.0, 0.0, 0.0);
        }
    } else {
        fragColor = vec4(0.0, 0.0, 0.0, 0.0);
    }
    gl_FragColor = fragColor;
    
    }
    

Por encima de código funciona para una textura atlas donde los números empiezan desde 0 en la séptima columna de la segunda fila de los atlas de fuente (textura).

Consulte https://www.shadertoy.com/view/Xl23Dw para la demostración ( con la textura del mal sin embargo)

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top