2012-08-14 17 views
5

Actualmente estoy trabajando en un 2D RPG escrito en Java 1.6 con el LWJGL. Implementé el uso de VBO en mi juego y ahora mantengo dos de ellos: uno para datos de vértices y otro para coords de texturas.Actualización de datos de VBO con glBufferSubData()

Todo funciona bien, excepto que todavía no tengo una manera muy lógica de actualizar los Objetos. Como ejemplo, si quiero que cierto azulejo cambie su textura (cambie las coordenadas de la textura dentro del VBO para mostrar otra área de la Hoja de Textura), no veo la manera de cambiar solo las coordenadas de la textura que corresponden a este solo azulejo Todo lo que puedo pensar ahora es llenar los buffers con todos los datos necesarios en cada bucle y subirlos con glBufferData en cada fotograma. Funciona, pero no parece ser la mejor manera de hacerlo (¿o no?).

Ahora, existe el comando glBufferSubData que no asignará nueva memoria sino que solo cambiará la parte que le digo que cambie. El problema es que no sé cómo hacer un seguimiento del área que debe cambiarse (el desplazamiento). LWJGL ofrece un glBufferSubData (destino, desplazamiento, datos); comando, que solo necesita el inicio del búfer para funcionar. ¿El desplazamiento es algo así como un índice?

Así que si primero subo estos tampones a la VBO y luego quiero cambiar el segundo valor del segundo flotador []:

FloatBuffer vertexData = BufferUtils.createFloatBuffer(amountOfVertices * vertexSize); 
vertexData.put(new float[]{100, 100, 300, 100, 300, 300, 100, 300}); 
vertexData.put(new float[]{400, 100, 600, 100, 600, 300, 400, 300}); 
vertexData.flip(); 

que generarían los nuevos datos, lo puso dentro de un pequeño FloatBuffer y subirlo con glBufferSubData (GL_VERTEX_ARRAY, 10, newFloatBuffer) ;? 10 es porque quiero cambiar valores del décimo valor anterior.

¿Es correcto? Hay una mejor manera de hacerlo? Y otra vez: ¿está bien si vuelvo a cargar toda la información en cada fotograma?

+0

Hay formas más sencillas de hacerlo. O simplemente dibuja la misma geometría con otra textura. O bien, haz la modificación de coordenadas de textura en el sombreador de vértices. –

Respuesta

6

LWJGL'sglBufferSubData() espera el desplazamiento como recuento de bytes, ya que uno debería poder escribir datos arbitrarios en ubicaciones de búfer arbitrarias. Si desea actualizar el flotante en el índice i, el desplazamiento sería i * 4, ya que los flotadores java toman, el muy común, 4 bytes. Se escribirán todos los contenidos del buffer restantes, por lo tanto, se requiere que el buffer objetivo tenga una capacidad de al menos
(i + floatBuffer.remaining()) * 4 bytes. Para una correcta preparación, consulte el método Buffers flip() o use position(int) junto con limit(int) para especificar el contenido restante para escribir.

Esta estrategia de actualización está bien siempre que no llame a glBufferSubData() demasiadas veces con FloatBuffers temporales. También podría tener un segundo búfer de destino con el mismo tamaño para el intercambio (ping pong), que podría asignarse usando MapBuffer() para una actualización general, mientras que el otro está en uso.

Prefiero mantener un FloatBuffer completo en el lado del cliente y cargarlo de inmediato usando glBufferData() en lugar de llamar al glBufferSubData() muchas veces. Pero sin conocer algunos números, es difícil de decir.

+0

Muchas gracias. Implementaré la estrategia de Cliente FloatBuffer y la mantendré por ahora. Más tarde probaré los sombreadores de vértices. – Thiago

+0

¡De nada! Los sombreadores son un área interesante. Si tiene que cambiar áreas de textura de igual tamaño, las texturas de matriz son una alternativa alternativa a un mapa/hoja de textura. Las texturas 3D se pueden usar para combinar el cambio sin problemas. – Sam

Cuestiones relacionadas