lunes, 16 de abril de 2012

Arnow2D. Minimotor 2D funcionando

Hola a todos...

Despues de tanto tiempo ya puedo subir el capitulo 3 del curso de como crear un motor 2D sencillo.

El motor usa opengl, glfw para las ventanas, corona para la carga de gráficos y quicktext para las fuentes.

Recomiendo que le echeis un ojo a :
http://lordpakus.blogspot.com.es/2011/06/gameengine-capitulo-6.html
http://lordpakus.blogspot.com.es/2011/06/gameengine-capitulo-7.html
http://lordpakus.blogspot.com.es/2011/06/gameengine-capitulo-9-graphics2dmanager.html

Le faltan lo sonidos, los tamaños de gráficos están hardcodeados y no tenemos todavía gestión de Z's, peroooo es un inicio de motor sencillo, en un solo cpp y que permite cargar y pintar gráficos.

El código lo podeis ver aqui

En próximos capitulos iremos puliendo recursivamente el código para darle más funcionalidades y que sea más mantenible.

Espero que os guste.

main.cpp


#include "Arnow2D.h"

GLuint graf;

void Draw(void)
{
A2D_Draw(0,0,graf);
}

void Main_Loop(void)
{
  while(1)
  {
//Limpiamos la pantalla
A2D_Clear();

Draw();

//Renderizamos la escena
A2D_Render();
  }
}

int main(void)
{
  A2D_Init();
  graf = A2D_Load("img_test.png");
  Main_Loop();
  glDeleteTextures( 1, &graf );
  A2D_DeInit();
}



Arnow2D.cpp

#include "Arnow2D.h"

//Pasamos a modo 2D
void switchToOrtho(void)
{
glDisable(GL_DEPTH_TEST);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glOrtho(0, 640, 0, 340, -5, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}

//Volvemos al modo 3D
void switchBackToFrustum (void)
{
glEnable(GL_DEPTH_TEST);
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
}

//Función de calculo de FPS
int CalcFPS()
{
static clock_t timer = clock(); //Temporizador para los FPS
static int FPS = 0;
static int LastFPS = 0;
FPS++;

if ( (clock() - timer) > 1000 )
{
LastFPS = FPS;
FPS = 0;
timer = clock();
}

return LastFPS;
}

void A2D_Draw(float x, float y, int id)
{
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, id);
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );

glBegin(GL_QUADS);
glTexCoord2f( 1.0f, 1.0f); glVertex2i( x - 128 , y - 128 ); // Top Right Of The Quad (Front)
glTexCoord2f( 0.0f, 1.0f); glVertex2i( x + 128 , y - 128 ); // Top Left Of The Quad (Front)
glTexCoord2f( 0.0f, 0.0f); glVertex2i( x + 128 , y + 128 ); // Bottom Left Of The Quad (Front)
glTexCoord2f( 1.0f, 0.0f); glVertex2i( x - 128 , y + 128 ); // Bottom Right Of The Quad (Front)
glEnd();
}

int A2D_Load(char cad[])
{
GLuint tex;
corona::Image* imagen=NULL;

cout << "Cargamos recurso: " << cad << "\n";

imagen = corona::OpenImage(cad);//corona::PF_R8G8B8A8

if(imagen==NULL)
{
cout << "Recurso no cargado\n";
return -1;
}

printf("Ancho:%d  Alto:%d\n",imagen->getWidth(),imagen->getHeight());
glGenTextures(1, &tex);
glBindTexture(GL_TEXTURE_2D, tex);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, imagen->getWidth(), imagen->getHeight(),0, GL_RGBA, GL_UNSIGNED_BYTE, imagen->getPixels());
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);

delete imagen;  

cout << "Recurso cargado\n";

return tex;
}

void A2D_Init(void)
{
  const int window_width = 1024,
            window_height = 768;

  if (glfwInit() != GL_TRUE)
    Shut_Down(1);

  // 800 x 600, 16 bit color, no depth, alpha or stencil buffers, windowed
  if (glfwOpenWindow(window_width, window_height, 8, 8, 8, 0, 0, 0, GLFW_WINDOW) != GL_TRUE)
    Shut_Down(1);

   glfwSetWindowTitle("Arnow2D Engine");
   glMatrixMode(GL_PROJECTION); // Select The Projection Matrix
   glLoadIdentity(); // Reset The Projection Matrix
   glOrtho(.5*window_width, -.5*window_width, -.5 * window_height, .5 * window_height, 1, 50);

glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
glLoadIdentity(); // Reset The Modelview Matrix
  glEnable(GL_TEXTURE_2D); // Enable Texture Mapping ( NEW )
glClearColor(0.0f, 0.0f, 0.0f, 0.5f); // Black Background
}

void A2D_DeInit(void)
{
Shut_Down(0);
}

void A2D_Clear(void)
{
    // clear the buffer
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glTranslatef(0,0, -30);
}

void A2D_Print(int x, int y, char *cad)
{
switchToOrtho();
glQuickText::printfAt(10.0,10.0, 0.0f ,1.0f , cad );
switchBackToFrustum();
}

void A2D_Render(void)
{
    char cadFPS[32];

sprintf(cadFPS,"FPS: %d",CalcFPS());
A2D_Print(10,10,cadFPS);

glfwSwapBuffers();
}

void Shut_Down(int return_code)
{
  glfwTerminate();
  exit(return_code);
}

Nos vemos


0 comentarios :

Publicar un comentario

Entradas populares