Pregunta

Tengo un código OpenGL que se comporta de manera inconsistente a través de diferentes hardware. Tengo un código que:

  1. Crea un búfer de procesamiento y une una textura a su búfer de color (Textura A)
  2. Establece este búfer de procesamiento como activo y ajusta la ventana gráfica, etc.
  3. Activa un sombreador de píxeles (desenfoque gaussiano, en este caso).
  4. Dibuja un quad a pantalla completa, con textura A en él.
  5. Desvincula el renderbuffer, etc.

En mi máquina de desarrollo, esto funciona bien y tiene la intención efecto de desenfoque de la textura en su lugar, sin embargo, en otro hardware Esto no parece funcionar.

Lo he reducido a dos posibilidades.

A) Hacer un renderbuffer a sí mismo no se supone que funcione, y solo funciona en mi máquina de desarrollo debido a algún tipo de casualidad.

O

B) Este enfoque debería funcionar, pero algo más está yendo mal.

¿Alguna idea? Honestamente, he tenido dificultades para encontrar detalles sobre este problema.

¿Fue útil?

Solución

A) es la respuesta correcta. La representación en el mismo búfer mientras se lee no está definida. Podría funcionar, podría no hacerlo, que es exactamente lo que está sucediendo.

En el caso de OpenGL, framebuffer_object extension tiene sección " 4.4.3 Representación cuando una imagen de un objeto de textura encuadernada también se adjunta al Framebuffer " que dice lo que sucede (básicamente, indefinido). En Direct3D9, el tiempo de ejecución de la depuración se queja en voz alta si utiliza esa configuración (pero podría funcionar dependiendo del hardware / controlador). En D3D10, el tiempo de ejecución siempre desenlaza el objetivo que se usa como destino, creo.

¿Por qué esto no está definido? Una de las razones por las que las GPU son tan rápidas es que pueden hacer muchas suposiciones. Por ejemplo, pueden asumir que las unidades que obtienen píxeles no necesitan comunicarse con las unidades que escriben píxeles. Por lo tanto, se puede leer una superficie, N ciclos más tarde, la lectura se completa, N ciclos más tarde, el sombreado de píxeles finaliza su ejecución, luego se coloca en algunos búferes de combinación de salida en la GPU y, finalmente, en algún punto se escribe en la memoria. Además de eso, las GPU se rasterizan en " undefined " orden (una GPU puede rasterizar en filas, otra en un orden de almacenamiento en caché, otra en otra totalmente distinta), por lo que no sabe qué partes de la superficie se escribirán primero.

Entonces, lo que debes hacer es crear varios buffers. En el caso de desenfoque / brillo, generalmente dos son suficientes: renderizar primero, luego leer & amp; difuminar eso mientras se escribe en segundo. Repita este proceso si es necesario de forma ping-pong.

Otros consejos

En algunos casos especiales, incluso el backbuffer puede ser suficiente. Simplemente no haces un glClear, y lo que has dibujado anteriormente todavía está allí. La advertencia es, por supuesto, que realmente no se puede leer desde el backbuffer. Pero para efectos como el desvanecimiento dentro y fuera, esto funciona.

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