Imprimir Pixels

MΓ©tricas de la pantalla

Antes de empezar, me gustarΓ­a asegurarme de que todos estamos en la misma pΓ‘gina.

Una pantalla de ordenador es bΓ‘sicamente un objeto 2D que tiene coordenadas x e y. Por convenciΓ³n, se considera que la esquina superior izquierda de la pantalla es el origen (x = 0, y = 0).

Consideremos una resoluciΓ³n de pantalla comΓΊn, que es 1920x1080.

En este caso, eso significa que hay 1080 filas de pΓ­xeles en la pantalla, y que cada fila tiene 1920 pΓ­xeles. El eje y se utiliza para representar el nΓΊmero de filas, mientras que el eje x se utiliza para representar el nΓΊmero de columnas.

Imprimir un pixel

Dibujar pΓ­xeles es lo mΓ‘s bΓ‘sico para lo que sirve una librerΓ­a grΓ‘fica, y minilibx nos proporciona formas sencillas de hacerlo.

La forma mΓ‘s sencilla es utilizar la funciΓ³n mlx_pixel_put. Echemos un vistazo al prototipo:

int    mlx_pixel_put ( void *mlx_ptr, void *win_ptr, int x, int y, int color );

La funciΓ³n mlx_pixel_put () dibuja un pΓ­xel definido en la ventana win_ptr utilizando las coordenadas (x, y), y el color especificado.

Otra opcion para imprimir en pantalla es mlx_string_put. Aunque no se muy util esta funcion escribir en la poscion que deses en pantalla el sting que le mandes.

int    mlx_string_put ( void *mlx_ptr, void *win_ptr, int x, int y, int color, char *string );

Gestion de colores

El parΓ‘metro de color tiene un tipo int.

El color mostrado debe ser codificado en este entero, siguiendo un esquema definido.

Todos los colores visualizables pueden dividirse en 3 colores bΓ‘sicos: rojo, verde y azul.

Tres valores asociados, en el rango 0-255, representan la cantidad de cada color que se mezcla para crear el color original.

Estos tres valores deben establecerse dentro del entero para mostrar el color correcto. Los tres bytes menos significativos de este entero se rellenan como se muestra en la imagen siguiente:

           | 0 | R | G | B |   color integer
           +---+---+---+---+

Al rellenar el entero, asegΓΊrate de evitar problemas endianos. Recuerda que el byte "azul" debe ser siempre el menos significativo.

Para una explicacion de los colores mas profunda:

Impirmir un cuadrado

Ahora que sabemos cΓ³mo poner un pΓ­xel en la pantalla, implementar una funciΓ³n que ponga un rectΓ‘ngulo en su lugar es bastante sencillo. Los rectΓ‘ngulos son realmente ΓΊtiles, y es muy probable que los usemos mucho.

AquΓ­ hay una implementaciΓ³n que podemos usar:

#define GREEN_PIXEL 0xFF00

typedef struct s_rect
{
	int	x;
	int	y;
	int width;
	int height;
	int color;
}	t_rect;

/* The x and y coordinates of the rect corresponds to its upper left corner. */

int render_rect(t_data *data, t_rect rect)
{
	int	i;
	int j;

	if (data->win_ptr == NULL)
		return (1);
	i = rect.y;
	while (i < rect.y + rect.height)
	{
		j = rect.x;
		while (j < rect.x + rect.width)
			mlx_pixel_put(data->mlx_ptr, data->win_ptr, j++, i, rect.color);
		++i;
	}
	return (0);
}

Antes del mlx_pixel_put es recomendable checkear si la ventana sigue abierta comprobando si el puntero que apunta a esta no es NULL, para asi no imprimir en una ventana que no existe.

INCONVENIENTES de mlx_pixel_put

In this section, I'm going to explain why the approach of using the mlx_pixel_put IS BAD!!!. I know, I know, that's not really nice. I just teached you something and now I'm saying it's useless! Trust me, what we learned together is far from being pointless. In fact, thanks to that we'll find what the problem is.

Para visualizar lo que estΓ‘ mal, implementemos una funciΓ³n render_background que cambiarΓ‘ el color de fondo de la ventana:

void	render_background(t_data *data, int color)
{
	int	i;
	int	j;

	if (data->win_ptr == NULL)
		return ;
	i = 0;
	while (i < WINDOW_HEIGHT)
	{
		j = 0;
		while (j < WINDOW_WIDTH)
			mlx_pixel_put(data->mlx_ptr, data->win_ptr, j++, i, color);
		++i;
	}
}

Si a la ejecucion de nuestro main aΓ±adimos antes esta funcion tendremos el siguiente resultado. Ten en cuneta que hay que ejuctarla antes de imprimir los cadrads, para no que no se sobreponga.

Uh. Que feo parpadeo tenemos ahora.

Bien. Bueno, el problema que tenemos aquΓ­ es bastante simple.

La funciΓ³n mlx_pixel_put bΓ‘sicamente dibuja el pΓ­xel en la ventana directamente, y la persona que estΓ‘ mirando la ventana verΓ‘ el cambio instantΓ‘neamente. Eso es malo aquΓ­ porque lo que realmente queremos hacer es esperar a que se dibuje todo el fondo, asΓ­ como los rectΓ‘ngulos, y luego empujar eso en la ventana. Como todo se hace sin ningΓΊn retraso, esto nos estΓ‘ dando este efecto de parpadeo sucio.

AdemΓ‘s, tenga en cuenta que esta tΓ©cnica es lenta. Tal vez no se note en tu mΓ‘quina, pero es realmente lento, crΓ©eme.

Por lo tanto, necesitamos una soluciΓ³n a estos dos problemas. Bueno, no te preocupes, el minilibx nos proporciona una soluciΓ³n. Es un poco mΓ‘s complicado que poner un simple pΓ­xel en la ventana, Β‘pero vale la pena!. Para esto hay su utilizan las imagenes

Last updated