¿Qué ventaja tienen OpenGL, SFML y SDL sobre el renderizado de software?

24

Comencé a ver la transmisión de Handmade Hero , donde Casey Muratori crea un motor de juego sin usar frameworks o tal. Ayer llegué a la parte donde mostró cómo se dibuja una imagen en la pantalla. Según tengo entendido, él solo asignó un poco de memoria tan grande como el tamaño de la pantalla a la que quiere dibujar. Y luego creó un mapa de bits que pasó a la memoria intermedia que asignó y lo dibujó en la pantalla usando una función específica del sistema operativo.

Esto parece bastante sencillo. Usé GameMaker, cambié a Love2D, trabajé un poco con Sprite Kit, pero siempre me preguntaba qué estaba pasando realmente debajo de estas capas a veces confusas.

Dado eso, ¿por qué molestarse en usar bibliotecas de gráficos (OpenGL, SFML, SDL, ...) cuando todo lo que tiene que hacer es simplemente asignar algo de búfer, pasar un mapa de bits y dibujarlo en la pantalla?

Si luego desea dibujar cosas distintas en su pantalla, simplemente escríbalas en su mapa de bits que luego se pasa al búfer. Soy bastante nuevo en programación, pero esto me parece bastante simple. Por favor corrígeme si estoy equivocado.

usuario148013
fuente
11
más adelante en su serie (alrededor del episodio 220) usará opengl. La razón por la que hace eso es la velocidad.
Ratchet Freak
55
El truco es determinar qué dibujar en la pantalla. Todas las cosas de textura / sombreado de GPU, triángulos, proyecciones de cámara, etc. deben hacerse primero para decidir qué color debe ser cada píxel. Empujar los colores de píxeles a la pantalla es la parte fácil.
user14146
2
Para el registro, SDL y OpenGL no son mutuamente excluyentes. SDL es una "capa de abstracción de hardware" que también maneja ventanas, eventos y entradas en lugar de ser solo una biblioteca de gráficos. SDL también tiene soporte para ser usado junto con OpenGL para que SDL pueda hacer todo lo que no sea de gráficos mientras OpenGL maneja los gráficos. También tenga en cuenta que a menudo OpenGL funciona directamente con la GPU, mientras que SDL puede o no depender de la versión y el sistema para el que se compila.
Pharap
SFML usa OpenGL para renderizar, por lo que realmente todo lo que SFML hace es proporcionar una interfaz más simple para usar OpenGL.
Cornstalks
2
Techcnailyl lo que Casey está haciendo todavía está usando una biblioteca de gráficos. La biblioteca se llama GDI , y aunque es parte de la API principal del sistema operativo, técnicamente sigue siendo una biblioteca de gráficos.
Pharap

Respuestas:

41

No se trata solo de la velocidad de ejecución, sino también de la simplicidad. Aunque la representación del software utilizada en este ejemplo sería mucho más lenta que el uso de la aceleración de hardware (es decir, una GPU), dibujar algunos mapas de bits en la pantalla es una tarea tan trivial que no notará la caída del rendimiento.

Sin embargo, la actividad de bajo nivel como la rasterización de triángulos, la clasificación de profundidad y similares son conceptos bien entendidos que la GPU puede manejar implícitamente con unos pocos comandos. Re-implementar aquellos en modo software es esencialmente reinventar la rueda. Esto está bien si desea obtener una comprensión de bajo nivel de cómo se realiza el renderizado, yo mismo escribí un renderizador de software 3D solo para explorarlo un poco, pero para la mayoría de las circunstancias es una pérdida de tiempo cuando OpenGL puede hacerlo más rápido. la caja.

El ejemplo que ha dado suena extremadamente básico, simplemente dibujando una sola imagen en la pantalla, por lo tanto, la implementación es fácil. Sin embargo, una vez que comience a superponer la complejidad, verá que se vuelve cada vez más complicado hacer que todo se represente correctamente. Lo que la gente tenía que hacer en los días del terremoto de la representación del software 3D era una locura, aunque aprecio que no vayas tan lejos (todavía).

Richard Greenlees
fuente
12
OpenGL conoce términos como puntos, líneas y triángulos. La mayoría de las veces trabajarás con triángulos. Para aprender a trabajar con OpenGL , puedo recomendar opengl-tutorial.org . Para saber qué hace OpenGL debajo del capó, eche un vistazo a la wiki oficial: opengl.org/wiki/Rendering_Pipeline_Overview
tkausl
1
Iba a +1, pero no me gusta la parte de "reinventar la rueda" porque siento que da la impresión equivocada en términos de la historia de la informática. La representación de mapa de bits fue lo primero, por lo tanto, OpenGL fue el que "reinventó la rueda". Sin embargo, tenían dos buenas razones para hacerlo: 1) Estandarización y 2) Aceleración de GPU. Reinventar la rueda no siempre es malo si la nueva versión es una mejora (es decir, ruedas con neumáticos frente a ruedas de vagones de madera). El punto clave aquí no debería ser que el renderizado de software está reinventando la rueda, sino que es inferior al renderizado de GPU.
Pharap
44
@Pharap, excepto que ahora , escribir un procesador de software es absolutamente reinventar la rueda, independientemente de si fue históricamente o no.
porglezomp
1
Esto es solo la mitad de una respuesta. La siguiente respuesta es la otra mitad, pero una respuesta completa (incluida una explicación de la diferencia entre OpenGL y las otras cosas que menciona) sería la respuesta adecuada a esta pregunta.
Jasper
1
@ user148013 "¿Opengl conoce términos como punto, línea, triángulo?" OpenGL moderno se ocupa exclusivamente de estas primitivas. No puedes rasterizar nada más que ellos.
Nax 'vi-vim-nvim'
25

Mi pregunta es: ¿por qué molestarse en usar algo como open gl, sfml, sdl cuando todo lo que tiene que hacer es simplemente asignar algo de búfer, pasar un mapa de bits y dibujarlo en la pantalla?

Corto: porque es rápido (OpenGL, DirectX).

Largo:

Puede pensar que puede hacerlo todo usted mismo. Dibuja píxeles en una pantalla. Puede escribir una pequeña biblioteca para dibujar formas, como quads o triángulos. Esto funcionará, por supuesto. Hay muchas bibliotecas por ahí para hacer exactamente esto. Algunos de ellos incluso implementan la especificación OpenGL (por lo que son como un lado del software para opengl) que hará exactamente lo que hace Casey Muratori. Calculan todo en el lado del software, establecen los píxeles en el lado del software y escriben el resultado en la pantalla.

Sin embargo esto es lento . La CPU que eventualmente ejecutará todas estas cosas no fue hecha para este escenario. Para eso están las GPU. Lo que hace OpenGL (a menos que sea una implementación de software, por supuesto) es tomar todo lo que le diga que haga y enviar todos los datos, todas las llamadas de extracción, casi todo a la tarjeta gráfica y decirle a la GPU que haga el trabajo. La GPU está hecha específicamente para este tipo de trabajo. Multiplicar números de coma flotante (eso es lo que hace mucho cuando dibuja una escena 3D) y ejecutar sombreadores. Y esto en paralelo. Solo para tener una idea de lo rápido que es la GPU, piense en una escena simple en 3D en pantalla completa con 1920x1080 píxeles. Estos son, multiplicados, 2,073,600 píxeles para dibujar. Por cadapíxel, la GPU ejecutará el fragment-shader al menos una vez , la mayoría de las veces más de una vez. Ahora, digamos que corremos a 60 cuadros por segundo. Esto significa que la GPU ejecuta el fragment-shader 2,073,600 * 60 = 124,416,000 veces por segundo . ¿Crees que puedes hacer algo así en tu CPU? (Esa es una explicación bastante simplificada, hay muchas más cosas a tener en cuenta, como cuántos píxeles dibuja sobre objetos cercanos, cuánto MSAA usa, etc., sin embargo, las 124,416,000 veces por segundo son probablemente las más bajas que puede obtener, y usted fácilmente tendrá mucho más de 60 fps con una escena simple)

Eso es lo que hacen OpenGL y Direct3D, para lo que hacen los motores, vea la respuesta de @Uri Popovs.

tkausl
fuente
8
Está creando un juego en 2D, ese es otro tema como el 3D. Y cuando digo lento , no necesariamente significa que tenga menos de 60 fps, sino que significa que la tarjeta gráfica hará el mismo trabajo en una fracción del tiempo que necesita la CPU, al menos cuando se trata de espacio 3D.
tkausl
44
Bueno, la razón por la que las GPU son mejores es porque están configuradas para paralelizar las invocaciones de sombreadores.
Ratchet Freak
44
@ user148013 Por lo que he visto de este tipo, diría que es exactamente lo contrario de "muy sabio".
Bartek Banachewicz
44
No es solo que sea más lento de renderizar (el renderizador de software de Casey fue sorprendentemente rápido). Es que también hay muchos datos para seguir empujando desde la RAM general a la RAM de video. Insertar un mapa de bits gigante en la tarjeta de video, dependiendo del tipo de bus, puede tomar una parte considerable de un tiempo de cuadro. Usando la GPU, empujas texturas ocasionalmente y las usas para cuadro tras cuadro.
Adrian McCarthy
2
@ user148013 Hay una diferencia entre programación llamativa y buena. Pueden superponerse, pero a menudo están en conflicto. Pondría "Puedo renderizar en software [al igual que MESA puede ...]" debajo de llamativo y ciertamente no es bueno .
11

Lo que hace se llama representación de software , lo que hace OpenGL se llama representación de GPU

¿Cual es la diferencia entre ellos? Velocidad y memoria.

La rasterización (completar triángulos en la pantalla) lleva algún tiempo. Si lo hace en la CPU, esencialmente le quita ese tiempo a la lógica del juego, especialmente si no está bien optimizado.

Y no importa cuán pequeña sea la imagen, necesita asignarle cierta cantidad de memoria. Las GPU tienen una memoria de video para esto.

Bálint
fuente
¿También es posible la representación de software en OS X? Porque parece que todo lo que tiene que ver con los gráficos fue hecho por OpenGl ahora Metal.
user148013
2
@ user148013 Tienes algunos malentendidos. OpenGL es una API multiplataforma, por lo que puede ejecutarse en OS X, de hecho, puede ejecutarse en todo con una GPU "moderna" (posterior a 2000). Metal es una API separada solo para dispositivos Apple. El renderizado de software también es algo diferente de ambos, y sí, también se puede hacer en OS X. Básicamente se trata de configurar píxeles manualmente en la pantalla con la CPU.
Bálint
Eso es exactamente por lo que pregunté porque, por lo que sé, la representación del software no se puede hacer en OS X. Cocoa se acerca a OpenGl, Quarz usa OpenGl, Core Framework usa OpenGl. Todos ahora usan Metal como su camino más rápido. Pero no he encontrado una sola función que dibuje un búfer en la pantalla sin el uso de la GPU (OpenGl, Metal).
user148013
1
@ user148013 Porque no es específico de un sistema operativo ni de implementaciones. Digamos que desea implementarlo en Java, porque esa es una opción famosa para el desarrollo multiplataforma. Con Java, puede hacerlo creando primero una ventana (JFrame), luego, en lugar de dibujar directamente sobre ella, dibuja en una imagen, luego coloca esta imagen en el marco. Sin embargo, no sabrá los términos "triángulo" o "línea". Solo colores. Debe implementarlo usted mismo con un algoritmo de rasterización. Es por eso que preferimos OpenGL, es más rápido y un poco más fácil de usar. Básicamente es una API de rasterización.
Bálint
2
@ user148013 ¿Por qué no podrían? Si pueden abrir una ventana y pueden dibujar 1 imagen en ella sin una API, entonces pueden hacerlo.
Bálint
8

Si bien las respuestas de otros son más correctas que cualquier respuesta que pueda dar, quiero señalar el malentendido fundamental sobre cómo funciona el desarrollo de software que creo que subyace en su pregunta. Si bien siempre es posible hacer las cosas "solo" sin un marco, y a menudo hay un gran beneficio educativo al hacerlo, la realidad es que no es así como se crea el software moderno.

Alguien creó el hardware y los lenguajes de máquina que se ejecutan en él. Alguien más crea lenguajes y compiladores de nivel superior, controladores y sistemas operativos, bibliotecas de gráficos y así sucesivamente. Cada uno de nosotros construimos sobre el trabajo de nuestros predecesores. Eso no es solo "está bien", es un requisito.

Estás dibujando la línea de lo que es "aceptable" o no en un punto arbitrario de la cadena de herramientas. Podría decir con la misma facilidad "¿por qué usar C ++ cuando podría hacer lo mismo en el ensamblaje?", O "¿por qué confiar en los controladores del teclado cuando podría leer fácilmente los voltajes que salen de sus cables y calcularlos usted mismo?" No hay suficientes horas en el día o años en la vida para que todos puedan hacer todo por sí mismos.

Esto no se aplica solo al desarrollo de software, sino a la vida moderna en general. ¿Alguna vez has oído hablar del chico que construyó una tostadora, desde cero? http://www.thomasthwaites.com/the-toaster-project/ . Tomó mucho tiempo y mucho esfuerzo. Para una tostadora ¡Intenta construir todo lo necesario para actualizar un videojuego fuera del éter por tu cuenta!

erich8
fuente
2
Creo que esta es una buena respuesta porque establece por qué el uso de frameworks es bueno sin menospreciar la idea de reinventar la rueda con fines educativos.
Pharap
3

Los motores hacen mucho más que simplemente dibujar una imagen en la pantalla. Manejan la iluminación, las sombras, la entrada, la detección de colisiones. Incluso solo la parte de representación es mucho más compleja que simplemente empujar un búfer en la pantalla. Especialmente para escenas 3D, debe hacer muchos cálculos con datos mucho más complejos que un mapa de bits. Permíteme darte una analogía con un automóvil: lo que estás describiendo como simple es el escape del automóvil. Simplemente haces una tubería con el tamaño correcto y luego empujas el gas de un extremo al otro. Sin embargo, esto está lejos de ser lo único que sucede en el mecanismo del automóvil.

Uri Popov
fuente
3

Las respuestas anteriores son excelentes, pero ninguna realmente pasa por la razón más importante de por qué se prefiere OpenGL y tal. La razón principal es hacer uso de hardware dedicado diseñado especialmente para trabajar con cosas como renderizar millones de píxeles en una pantalla, la GPU .

Con el renderizado de software, usando la CPU, el renderizador se repetirá, uno por uno, sobre todos los píxeles en un mapa de bits y emitirá órdenes para mostrar cada uno en la pantalla. Entonces, si está renderizando una imagen de tamaño 1000x1000, esos 1,000,000 bucles para que su CPU repita. Están diseñados teniendo en cuenta el control después de todo; muchas condiciones, saltando de un conjunto de instrucciones a otro y una estricta dirección de flujo de control. Sin embargo, una GPU está diseñada con el conocimiento de que realizará muchos bucles similares sobre píxeles en la pantalla.Una GPU tomaría un ciclo for con 1000000 iteraciones y dividiría el trabajo entre su gran cantidad de núcleos para que cada uno trabaje ** en paralelo e independiente el uno del otro **. Entonces, a diferencia de la CPU, cada vez que una GPU se encuentra con una condición if-else, manejará ambas ramas de código en dos núcleos de sí misma Y LUEGO, al final, verá qué evalúa la condición y descarta el resultado de la rama innecesaria (es por eso que muchas condiciones if-else en sombreadores GPU están mal vistas; siempre son responsables de un desperdicio).

Entonces, sí, las GPU se basan en el paralelismo . Eso hace que trabajar en píxeles para ellos sea mucho más rápido en comparación con las CPU.

Aiman ​​Al-Eryani
fuente
0

Consulte ¿Realmente necesito usar una API de gráficos?

Claro, puede solicitar un búfer, configurar algunos bits y escribirlo en la pantalla. Esa era esencialmente la única forma de hacer programación de gráficos en la PC hasta la disponibilidad de aceleradores de gráficos a mediados de los 90 de 3DFX. Incluso en Windows, DirectX fue desarrollado para dar acceso directo a la memoria de video.

Pero en el hardware que no es de PC, máquinas de juegos dedicadas, siempre ha habido técnicas para acelerar los gráficos al descargar el trabajo del procesador. Incluso el Atari 2600 tenía "sprites de hardware", en parte porque no tenía suficiente RAM para un framebuffer.

Las consolas de juegos posteriores (mediados de los 80) fueron optimizadas para juegos de plataforma. De nuevo, no framebuffer; en cambio, el programador podría especificar cuadrículas de mosaicos :

El hardware de gráficos Genesis consta de 2 planos desplazables. Cada plano está hecho de azulejos. Cada mosaico es un cuadrado de 8x8 píxeles con 4 bits por píxel. Cada píxel puede tener 16 colores. Cada mosaico puede usar 1 de 4 tablas de colores, por lo que en la pantalla puede obtener 64 colores a la vez, pero solo 16 en cualquier mosaico específico. Las fichas requieren 32 bytes. Hay 64K de memoria gráfica. Esto permitiría 2048 mosaicos únicos si la memoria no se utilizara para nada más.

pjc50
fuente
-2

Las CPU modernas son lo suficientemente rápidas como para hacer cualquier juego 2D en software, por lo que para gráficos 2D OpenGL / DirectX no ofrecería ventajas, además de agregar otra dependencia y una capa de complejidad a su proyecto, como, por ejemplo, configurar una matriz de proyección 3D para dibujar un montón de sprites y cargando datos a GPU.

OpenGL también lo obligaría a empaquetar todos sus sprites dentro de texturas de 512x512 (un artefacto de consolas antiguas, como PSX, empaquetando gráficos en páginas de memoria de video), requiriéndole que escriba un código de empaque de sprites bastante complejo.

Por otro lado, si está haciendo 3d, renderizando millones de triángulos con sombreado complejo, entonces la GPU es inevitable. Hace mucho tiempo, existía una versión más simple en 2D de Direct3d, llamada DirectDraw, que GPU aceleró el dibujo de sprites, pero ahora Microsoft ya no lo admite, posiblemente porque las CPU son lo suficientemente rápidas para hacer 2D sin aceleración, si no le importa el ahorro de energía. .

SmugLispWeenie
fuente