Anuncios

Bienvenidos sean a este post, hoy nos centraremos en como dibujar de una manera muy basica.

Anuncios

Si bien hasta ahora creamos una ventana y la mostramos todavia no renderizamos o dibujamos nada dentro de ella, para poder dibujar en la misma disponemos de dos estructuras:

  • SDL_Surface: contiene una coleccion de pixels y renderiza por software
  • SDL_Texture: tambien posee una coleccion de pixels pero renderiza por hardware
Anuncios

Como nosotros queremos el mejor rendimiento para nuestros juegos nos centraremos en la segunda estructura. Esto es asi porque hoy en dia la gran mayoria del HW tienen un minimo de aceleracion pero no se olviden que bajo algunas circunstancias necesitaremos utilizar la primera opcion. Antes de comenzar, vamos a necesitar una imagen para poder trabajar sobre ella. Para este post usaremos la imagen contenida en el siguiente archivo

Anuncios

Descarguen el archivo y extraigan el archivo en la pc. Lo siguiente sera utilizar el codigo que modificamos en el post anterior, en caso de no tenerlo les dejo un link para descargarlo:

Proyecto Juego

Anuncios

Simplemente deben extraerlo en el PC y dentro tendran todo lo necesario. Lo unico que deben volver a hacer es la habilitacion de SDL para el codigo. Para ello, les recomiendo primero eliminar al proyecto y luego visitar este post donde se explica como hacerlo. Una vez que esta todo configurado nuestro siguiente paso sera crear un nuevo directorio o carpeta dentro de nuestro proyecto, mas exactamente donde esta nuestro codigo fuente, al cual llamaremos assets y en este agregaremos la imagen que extrajimos recien. Si usaron la ruta predeterminada el path para guardar las imagenes sera de la siguiente manera:

C:\Users\<usuario local>\source\repos\Juego\Juego\assets
Anuncios

Con esto ya tenemos todo listo para comenzar a modificar nuestro proyecto Juego para poder renderizar la imagen.

Anuncios
Nota: 
En el caso de querer distribuir el juego recuerden copiar esta carpeta junto al .exe de lo contrario no hallara las imagenes, nosotros en cambio lo hacemos asi por un tema de que solamente necesitamos probarlo con el codigo fuente.
Anuncios

Pero antes de comenzar con la implementacion del manejo de la imagen, vamos a realizar algunas modificaciones en nuestro codigo. La primera sera en main.cpp y buscaremos la siguiente linea:

g_juego->iniciar("Juego", 320, 240, true);
Anuncios

Y la modificaremos de la siguiente manera:

g_juego->iniciar("Juego", 640, 480, false);
Anuncios

Esto eliminara el llamado a transformar el tamaño de la ventana a pantalla completa. Asi como tambien le cambiamos el tamaño a la ventana. Nuestro siguiente paso sera en Juego.h y lo primero que haremos sera agregar las siguientes dos lineas al inicio:

#include <SDL3/SDL_surface.h>
#include <SDL3/SDL_render.h>
Anuncios

Estas iran junto a la libreria basica de SDL y nos permitira acceder a nuevas funciones y constantes. Nuestro siguiente paso sera agregar las siguientes lineas en la parte privada de la clase:

	SDL_Texture* m_pTextura;
	SDL_FRect m_origenRectangulo;
	SDL_FRect m_destinoRectangulo;
Anuncios

Estos son solo declaraciones de objetos que los usaremos un poco mas adelante. Nuestro siguiente paso sera modificar a Juego.cpp, y en este iremos a la funcion iniciar para modificarla de la siguiente manera:

bool Juego::iniciar(const char* titulo, int ancho, int alto, bool pantallaCompleta) {
    int flags = 0;
    float w,h;
    if (pantallaCompleta)
        flags = SDL_WINDOW_FULLSCREEN;

    if (SDL_Init(SDL_INIT_EVENTS) != 0) {
        OutputDebugStringA("SDL_Init iniciado\n");
        m_pVentana = SDL_CreateWindow(titulo, ancho, alto, flags);

        if (m_pVentana != 0) {
            OutputDebugStringA("Ventana Creada\n");
            m_pRenderer = SDL_CreateRenderer(m_pVentana, NULL);
            if (m_pRenderer != 0) {
                OutputDebugStringA("Render Exitoso\n");
                SDL_SetRenderDrawColor(m_pRenderer, 255, 255, 255, 255);
            }
            else {
                OutputDebugStringA("Render Fallido\n");
                return false;
            }
        }
        else {
            OutputDebugStringA("Ventana no Creada\n");
            return false;
        }
    }
    else {
        OutputDebugStringA("Inicio Fallido\n");
        return false;
    }

    OutputDebugStringA("Inicio Exitoso\n");
    m_bCorriendo = true;

    SDL_Surface* iSurfaceTemp = SDL_LoadBMP("assets/rider.bmp");
    m_pTextura = SDL_CreateTextureFromSurface(
        m_pRenderer,
        iSurfaceTemp);
    SDL_DestroySurface(iSurfaceTemp);
    SDL_GetTextureProperties(m_pTextura);
    SDL_GetTextureSize(m_pTextura, &w, &h);
    m_destinoRectangulo.x = m_origenRectangulo.x = 0;
    m_destinoRectangulo.y = m_origenRectangulo.y = 0;
    m_destinoRectangulo.w = m_origenRectangulo.w = w;
    m_destinoRectangulo.h = m_origenRectangulo.h = h;

    return true;
}
Anuncios

Vamos a analizar las nuevas lineas que agregamos. El primer cambio que agregamos es el siguiente:

float w,h;
Anuncios

Estas las declaramos para poder almacenar el ancho y alto de la textura, respectivamente, pero sobre esto hablaremos un poco mas adelante. Ahora pasemos a los verdaderos cambios y para ello veamos este primer segmento:

    SDL_Surface* iSurfaceTemp = SDL_LoadBMP("assets/rider.bmp");
    m_pTextura = SDL_CreateTextureFromSurface(
        m_pRenderer,
        iSurfaceTemp);
    SDL_DestroySurface(iSurfaceTemp);
Anuncios
Anuncios

Lo primero que haremos sera crear un objeto de tipo SDL_Surface, en este almacenaremos a la imagen que guardamos en la carpeta assets mediante la funcion SDL_LoadBMP. Por esta razon, creamos un objeto de este tipo. Lo siguiente sera definir a m_pTextura, una de las variables que agregamos en el archivo de encabezado. Para ello, usamos el metodo SDL_CreateTextureFromSurface al cual primero le pasaremos nuestro objeto renderer y luego pasamos el valor almacenado en el objeto donde cargamos la imagen. Con esto cargado no necesitaremos mas del objeto iSurfaceTemp, por esta razon usamos la funcion SDL_DestroySurface para sacarla de la memoria. Nuestro siguiente paso sera obtener las dimensiones de la imagen y para ello agregaremos la siguiente linea detras de las anteriores:

SDL_GetTextureProperties(m_pTextura);
SDL_GetTextureSize(m_pTextura, &w, &h);
Anuncios

La primer linea se encarga de obtener todas las propiedades de la textura. La siguiente es la que se encarga de obtener el ancho y el alto. Para ello, utiliza las acciones realizadas por la funcion anterior y el objeto de la textura. Estos datos los almacenamos en esas variables y los tenemos listos para utilizar. Con nuestros valores establecidos, nuestro siguiente paso sera establecer los valores de las distintas propiedades para los objetos que declaramos en la parte privada de la clase:

    m_destinoRectangulo.x = m_origenRectangulo.x = 0;
    m_destinoRectangulo.y = m_origenRectangulo.y = 0;
    m_destinoRectangulo.w = m_origenRectangulo.w = w;
    m_destinoRectangulo.h = m_origenRectangulo.h = h;
Anuncios

Las dos primeras lineas seran para establecer el eje X e Y tanto de m_destinoRectangulo como de m_origenRectangulo. Una vez establecido nuestro siguiente paso sera establecer el valor de ancho y alto de m_destinoRectangulo y m_origenRectangulo, y para ello les pasamos los valores que obtuvimos anteriormente. Ya tenemos los objetos que son necesarios para poder asignar nuestra textura. Ahora solo nos resta modificar la funcion renderizar donde reemplazaremos el codigo existente por el siguiente:

void Juego::renderizar() {
    SDL_SetRenderDrawColor(m_pRenderer, 255, 255, 255, 255);
    SDL_RenderClear(m_pRenderer);
    SDL_RenderTexture(m_pRenderer, m_pTextura, &m_origenRectangulo, 
        &m_destinoRectangulo);
    SDL_RenderPresent(m_pRenderer);
}
Anuncios

Las primeras dos lineas se encargan de pintar de blanco a la ventana o seccion de renderizado. La siguiente funcion se encargara de agregar a nuestra imagen en el renderizado. Oberven que primero informamos el objeto que posee la renderizacion, luego la textura o imagen que cargamos. Por ultimo, pasamos los dos rectangulos que iniciamos en la funcion iniciar. Con esto ya tenemos todo lo necesario para mostrar nuestra imagen. Pasemos a compilarlo y ejecutarlo para ver como es la salida:

Anuncios

Si lograron lo mismo, Felicitaciones!!! Acaban de crear su primer sprite en uan ventana!, con esto ya tenemos la nocion basica de como graficar con SDL pero esto no acaba aca sino que nos falta otras opciones mas interesantes pero eso sera tema para los proximos posts.

Anuncios

En resumen, hoy hemos visto como es la capacidad basica para cargar imagenes en la renderizacion, hemos hecho las modificaciones minimas y necesarias para poder hacerlo, hemos visto algunas nociones basicas de los datos que necesitaremos, tambien hemos visto como es el resultado final. Espero les haya sido de utilidad y les dejo un link a GitHub donde estan los codigos creados hoy:

Dibujo Basico / GitHub

Les dejo algunas de mis redes sociales para seguirme o recibir una notificacion cada vez que subo un nuevo post:

Anuncios

Donación

Es para mantenimento del sitio, gracias!

$1.50