Librería de apoyo para la creación de videojuegos SDL/OpenGL

Iniciado por SrCooper, 5 Septiembre 2013, 21:33 PM

0 Miembros y 1 Visitante están viendo este tema.

SrCooper

Buenas, ultimamente he tenido algunos días libres y he estado trabajando en una cosilla que he pensado que podría interesar y servir de ayuda a la hora de desarrollar videojuegos. Por supuesto, está en su versión alpha, y agradecería aportes, sugerencias y críticas que se hagan para que entre todos podamos ir mejorandola.

Basicamente, se trata de una serie de clases y funciones que podrían ser una base para cualquier videojuego. Esto quiere decir, una clase de la que derivan todos los objetos en pantalla, una clase que maneja estos objetos, etc. Es simplemente para partir de aquí cuando empezamos a desarrollar un videojuego, y así no tener que escribirlo todo cada vez.

He incluido además un el código de un pequeño juego que desarrollé en un par de horas con esta colección de archivos. Es un juego muy tonto, pero sirve de ejemplo para aprender la jerarquía de clases y todo eso.

Link: http://www.mediafire.com/download/6yvr866cp626a1a/Game_template.zip

Ningún archivo está compilado. He incluido el archivo de proyecto de codeblocks (para guardarlo como template) y el archivo Makefile si no tienes este IDE y usas linux.

Un saludo  y espero que os sirva
SrCooper

PD: Sinceramente, no sé usar los archivos Makefile. Espero que alguien me ayude con eso :laugh:

PD2: Acabo de darme cuenta de que hay que cambiar el SDL_GL_BUFFER_SIZE a 32 en la función init()

kaltorak

#1
Hola SrCooper

he localizado un error a parte del que mencionas en el post mira.

Código (cpp) [Seleccionar]
void Entity::setCoords(int X, int Y)
{
 if (X != NULL) box.x = X;
 if (X != NULL) box.y = Y;
}


Aquí le dices que compruebe si X es distinto de 0 y le dices que ponga X, pero debajo no deberías comprobar si Y es 0 en vez de comprobar nuevamente X??

Aparte por que motivo no se puede colocar en la posición 0,0 ??

Esto no es un error pero si un mal habito de programación en opengl

Código (cpp) [Seleccionar]
 glBegin(GL_QUADS);
 glTexCoord2i(0,0); glVertex2i(box.x, box.y);
 glTexCoord2i(1,0); glVertex2i(box.x + box.w, box.y);
 glTexCoord2i(1,1); glVertex2i(box.x + box.w, box.y + box.h);
 glTexCoord2i(0,1); glVertex2i(box.x, box.y + box.h);
 glEnd();


El motivo es que las tarjetas 3d mueven triángulos y no cuadrados, así que cuando le pasamos esto la tarjeta lo que hace es descomponer el cuadrado en 2 triángulos, con el gasto de recursos que ello con lleva, que si bien hoy en día es ínfimo, lo ideal para optimizar la librería seria que le pasaras los 2 triángulos en vez del cuadrado.

Haber si tengo un ratito esta noche y lo miro todo mas detenidamente  ;)

Un saludo
Kaltorak.



SrCooper

Sí, vi el error justo después de publicar el post. La función sería así:
Código (cpp) [Seleccionar]

void Entity::setCoords(int X, int Y)
{
  if (X != NULL) box.x = X;
  if (Y != NULL) box.y = Y;
}


La idea de la función setCoords era poder pasar NULL como parámetro si solo quieres cambiar una de las coordenadas. Tengo entendido que en un entero no es lo mismo poner 0 que poner NULL, ¿me equivoco?

No sabía lo de los triángulos. Para la próxima versión lo mejoraré.

Un saludo y gracias por echar un vistazo  ;)

SrCooper

amchacon

CitarTengo entendido que en un entero no es lo mismo poner 0 que poner NULL, ¿me equivoco?
Son equivalentes, de hecho NULL no es más que esto:
#define NULL 0

Los siguientes códigos serían igual de correctos para lo que tu quieres:

Código (cpp) [Seleccionar]
void Entity::setCoords(int X, int Y)
{
  if (X != NULL) box.x = X;
  if (Y != NULL) box.y = Y;
}


Código (cpp) [Seleccionar]
void Entity::setCoords(int X, int Y)
{
  if (X != 0) box.x = X;
  if (Y != 0) box.y = Y;
}


Código (cpp) [Seleccionar]
void Entity::setCoords(int X, int Y)
{
  if (X) box.x = X;
  if (Y) box.y = Y;
}
Por favor, no me manden MP con dudas. Usen el foro, gracias.

¡Visita mi programa estrella!

Rar File Missing: Esteganografía en un Rar

kaltorak

#4
Como bien te a dicho amchacon poner NULL o poner 0 es exactamente lo mismo.

Una opción es poner -1 y así decirle al programa que no lo use poniendo este código.

Código (cpp) [Seleccionar]

   void Entity::setCoords(int X, int Y)
   {
    if (X >= NULL) box.x = X;
    if (Y >= NULL) box.y = Y;
   }


O crear 2 nuevas funciones para definir cada una de las coordenadas por separado así.

Código (cpp) [Seleccionar]

   void Entity::setCoordX(int X)
   {
    box.x = X;
   }


Código (cpp) [Seleccionar]

   void Entity::setCoordY(int Y)
   {
    box.y = Y;
   }


Una comprobación que incluiría también en estas funciones, es que la coordenada introducida no exceda los limites de la pantalla, para evitar futuros errores a la hora de visualizar los objetos.

Y por ultimo y no con ello menos importante  ;D

Aquí te dejo un código para que veas como hacer un cuadro con dos triángulos en Opengl, tanto con color, como con texturas  ;)

Código (cpp) [Seleccionar]

#ifdef __cplusplus
    #include <cstdlib>
#else
    #include <stdlib.h>
#endif

#include <SDL/SDL.h>
#include <SDL/SDL_opengl.h>
#include <SDL/SDL_Image.h>


int main ( int argc, char** argv )
{

//Definimos las variable box y box1 del tipo SDL_Rect
SDL_Rect box,box1;

//Inicializamos los valores de box para posicionarlo en las posicion 100,100 y le damos un ancho y un alto de 100.
box.x = 100;
box.y = 100;
box.w = 100;
box.h = 100;

/*Inicializamos los valores de box1 para posicionarlo en las posicion 300,200
   y le damos el ancho y un alto de la imagen que vamos a cargar como textura.*/
box1.x = 300;
box1.y = 200;
box1.w = 34;
box1.h = 26;

//Inicializamos el modo de video de las SDL.
SDL_Init(SDL_INIT_VIDEO);

//Creamos la Surface principal del juego, la que se va a mostrar en pantalla.
SDL_SetVideoMode(640, 480, 32, SDL_OPENGL | SDL_GL_DOUBLEBUFFER | SDL_HWSURFACE | SDL_HWACCEL );

//Cambiamos el titulo de la ventana por "Cuadro Hecho con triangulos".
SDL_WM_SetCaption ("Cuadro Hecho con triangulos", NULL);

//Activamos el modo Interpolado de Opengl
glShadeModel(GL_SMOOTH);
//cargamos la matriz de proyección en modo ortográfico al solo usar 2D
glOrtho(0, 640, 480, 0, -1, 1);

//Carmos la imagen que vamos a usar como textura.
SDL_Surface *Image = IMG_Load("conejo.png");

//Definimos la variable Textura que contendra la ID de la textura.
GLuint Textura;

//Generamos el ID de la Textura.
glGenTextures(1, &Textura);
//Referenciamos la TExtura para que todas las operaciones posteriores afecten a esa textura.
glBindTexture(GL_TEXTURE_2D, Textura);
//Aplicamos los filtros a la textura para que se escale en funcion de la distancia.
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
//Creamos la Textura.
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, Image->w, Image->h, 0, GL_RGB, GL_UNSIGNED_BYTE, Image->pixels);

//Liberamos la imagen cargada por que ya no la vamos a usar mas.
SDL_FreeSurface(Image);

    bool done = false;
    //Bucle principal
    while (!done)
    {
        /*Comprobamos los eventos del sistema para comprobar si la ventana a sido cerrada o si se
          pulsa escape en caso de que asi sea ponemos El valor true en done para que finalice la
          ejecucion del programa.*/
        SDL_Event event;
        while (SDL_PollEvent(&event))
        {
            switch (event.type)
            {
            case SDL_QUIT:
                done = true;
                break;

            case SDL_KEYDOWN:
                {
                    if (event.key.keysym.sym == SDLK_ESCAPE)
                        done = true;
                    break;
                }
            }
        }

////////////Primer cuadro sin texturizar pintado de verde.///////////////

  //Seleccionamos el color verde para Pintar el primer cuadro.
  glColor3ub(0,255,0);
  //Comenzamos a pintar el primer cuadro usando 2 triangulos.
  glBegin(GL_TRIANGLES);
  //Primer triangulo
  glVertex2i(box.x, box.y);
  glVertex2i(box.x, box.y + box.h);
  glVertex2i(box.x + box.w, box.y);

  //Segundo Triangulo
  glVertex2i(box.x, box.y + box.h);
  glVertex2i(box.x + box.w, box.y);
  glVertex2i(box.x + box.w, box.y + box.h);
  glEnd();

////////////Fin del primer cuadro sin texturizar.///////////////


//////////////////Segundo cuadro aplicándole texturas./////////////

  //Especificamos el modo de aplicar la textura sobre el cuadro para que no le afecte el color del cuadro.
  glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL );

  //Activamos la Textura para usarla en el cuadro
  glEnable(GL_TEXTURE_2D);
  //Comenzamos a pintar el segundo cuadro usando 2 triangulos.
  glBegin(GL_TRIANGLES);
  //Primer Triangulo
  glTexCoord2i(0,0);glVertex2i(box1.x, box1.y);
  glTexCoord2i(0,1);glVertex2i(box1.x, box1.y + box1.h);
  glTexCoord2i(1,0);glVertex2i(box1.x + box1.w, box1.y);
  //Segundo Triangulo
  glTexCoord2i(0,1);glVertex2i(box1.x, box1.y + box1.h);
  glTexCoord2i(1,0);glVertex2i(box1.x + box1.w, box1.y);
  glTexCoord2i(1,1);glVertex2i(box1.x + box1.w, box1.y + box1.h);
  glEnd();
  //Desactivamos la textura.
  glDisable(GL_TEXTURE_2D);

  ////////////////////Fin del Segundo cuadro usando texturas./////////////////////////

  //Mostramos el buffer en pantalla
  SDL_GL_SwapBuffers();

    }

//Devolvemos 0 por que todo a salido bien.
return 0;
}


Se que faltan muchas cosas, pero como era solo para que vieras como funcionaba lo de los dos triángulos no me he complicado mucho la vida  ;D

Aquí te lo dejo el código fuente, esta echo en Windows por que no puedo usar Opengl en Linux, por que lo tengo virtualizado con VirtualBox y no funciona  :-(

http://ultrashare.net/hosting/fl/38544fe607

Un saludo
Kaltorak.