2010-11-06 10 views
6

He estado trabajando en algún código de procesamiento de sonido y ahora estoy haciendo algunas visualizaciones. Terminé de hacer un espectrograma spectrogram, pero la forma en que lo estoy dibujando es demasiado lento.Dibujando grandes cantidades de píxeles en OpenGL

Estoy usando OpenGL para hacer dibujos 2D, lo que ha dificultado la búsqueda de ayuda. También soy muy nuevo en OpenGL, así que no sé cómo se hacen las cosas de manera estándar.

Estoy almacenando los valores de r, g, b para cada píxel en una matriz grande. Cada vez que obtengo un pequeño segmento de sonido, lo proceso y lo convierto en una columna de píxeles. Todo se desplaza a la izquierda 1 píxel, y la nueva línea se pone al final.

Cada vez que vuelvo a dibujar, hago un bucle para configurar el color y dibujar cada píxel de forma individual, lo que parece ser una manera horriblemente ineficiente de hacerlo.

¿Hay una mejor manera de hacerlo? ¿Hay algún método para simplemente cambiar un montón de píxeles?

+7

¿Por qué no construir un mapa de bits a partir de su espectrograma, luego usar el mapa de bits como una textura para un gl quad? –

Respuesta

3

Son muchas formas de mejorar la velocidad de dibujo. Lo más simple sería asignar una textura RGB que dibujará usando un cuadrante de textura alineado con la pantalla. Cada vez que desee dibujar una nueva línea, puede usar glTexSubImage2d para cargar un nuevo subconjunto de la textura y luego volver a dibujar el cuadrángulo.

+0

Ok lo descubrí, y en cierto modo lo hice. Una cosa que olvidé mencionar es que los valores de mi píxel se almacenan en un búfer circular, lo que hace las cosas un poco más desafiantes, pero se puede solucionar. Creo una textura a partir de todos los píxeles cada vez que agrego una línea, luego lo mapeo apropiadamente con el quad. Puedo manejar fácilmente el desplazamiento desde el buffer circular usando un par de mapeos adicionales en el quad. Está lejos de ser óptimo, pero es mucho más rápido que lo que tenía antes. – MattRS

1

¿Quizás está pasando mucha más información a la tarjeta gráfica que píxeles? Esto podría suceder si el tamaño de su FFT es mucho mayor que la altura del área de dibujo o si el número de líneas espectrales es mucho mayor que su ancho. Si es así, es posible que el cuello de la botella esté pasando demasiados datos a través del autobús. Intente reducir el número de líneas espectrales promediándolas o recogiéndolas (tomando el máximo en cada contenedor para un conjunto de líneas consecutivas).

+0

Buen consejo, pero ya estoy manejando eso. Ese problema fue mi método de dibujo groseramente ineficiente. – MattRS

1

Sé que esta es una pregunta anterior, pero. . .

usa un buffer circular para almacenar los píxeles, y luego simplemente llaman glDrawPixels dos veces con las compensaciones adecuadas. Algo así no probado C:

#define SIZE_X 800 
#define SIZE_Y 600 
unsigned char pixels[SIZE_Y][SIZE_X*2][3]; 
int start = 0; 

void add_line(const unsigned char line[SIZE_Y][1][3]) { 
    int i,j,coord=(start+SIZE_X)%(2*SIZE_X); 
    for (i=0;i<SIZE_Y;++i) for (j=0;j<3;++j) pixels[i][coord][j] = line[i][0][j]; 
    start = (start+1) % (2*SIZE_X); 
} 
void draw(void) { 
    int w; 
    w = 2*SIZE_X-start; 
    if (w!=0) glDrawPixels(w,SIZE_Y,GL_RGB,GL_UNSIGNED_BYTE,3*sizeof(unsigned char)*SIZE_Y*start+pixels); 
    w = SIZE_X - w; 
    if (w!=0) glDrawPixels(SIZE_X,SIZE_Y,GL_RGB,GL_UNSIGNED_BYTE,pixels); 
} 
Cuestiones relacionadas