domingo, 19 de febrero de 2012

Arnow2D. Como crear una ventana con GLFW

Artículo perteneciente a la sección de motores gráficos

Hola a todos,

Dicen que rectificar es de sabios, así que durante unos instantes seré sabio :D. Me empeciné en no usar ninguna librería para este motor gráfico con el fin de que os fuera más fácil de entender, pero realmente lo complicaba todo más. Gracias a Dios que KillRazor y StrongCoder estaban ahí para hacerme ver el error (aunque reconozco que me costó :D).

Quien quiera ver toda la historia como fue que vea el siguiente link

En fin, al tema, el motor gráfico Arnow2D lo implementaré con la librería GLFW que aparte de ser totalmente libre (no como GLUT) nos da funcionalidades muy sencillas para poder crear ventanas y gestionar las entradas de usuario.

Para instalar la libreria y crear este tutorial me he basado en el siguiente link

Si tenéis problemas en la instalación o el linkado decidmelo y buscaremos solución a cada uno de los problemas puntuales que podáis tener.

Por ahora lo único que haremos será copypastear el tutorial de creación de ventanas con GLFW y ver que funciona. A partir de ahí iremos construyendo nuestro motor.

EDIT: Aqui os dejo el link donde bajaros el proyecto
Código:

#include <stdlib.h>
#include <GL/glfw.h>

void Init(void);
void Shut_Down(int return_code);
void Main_Loop(void);
void Draw_Square(float red, float green, float blue);
void Draw(void);

float rotate_y = 0,
      rotate_z = 0;
const float rotations_per_tick = .2;

int main(void)
{
  Init();
  Main_Loop();
  Shut_Down(0);
}

void Init(void)
{
  const int window_width = 800,
            window_height = 600;

  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, 5, 6, 5, 0, 0, 0, GLFW_WINDOW) != GL_TRUE)
    Shut_Down(1);

  glfwSetWindowTitle("The GLFW Window");

  // set the projection matrix to a normal frustum with a max depth of 50
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  float aspect_ratio = ((float)window_height) / window_width;
  glFrustum(.5, -.5, -.5 * aspect_ratio, .5 * aspect_ratio, 1, 50);
  glMatrixMode(GL_MODELVIEW);
}

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

void Main_Loop(void)
{
  // the time of the previous frame
  double old_time = glfwGetTime();
  // this just loops as long as the program runs
  while(1)
  {
    // calculate time elapsed, and the amount by which stuff rotates
    double current_time = glfwGetTime(),
           delta_rotate = (current_time - old_time) * rotations_per_tick * 360;
    old_time = current_time;
    // escape to quit, arrow keys to rotate view
    if (glfwGetKey(GLFW_KEY_ESC) == GLFW_PRESS)
      break;

    if (glfwGetKey(GLFW_KEY_LEFT) == GLFW_PRESS)
      rotate_y += delta_rotate;

    if (glfwGetKey(GLFW_KEY_RIGHT) == GLFW_PRESS)
      rotate_y -= delta_rotate;

    // z axis always rotates
    rotate_z += delta_rotate;

    // clear the buffer
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    // draw the figure
    Draw();

    // swap back and front buffers
    glfwSwapBuffers();
  }
}

void Draw_Square(float red, float green, float blue)
{
  // Draws a square with a gradient color at coordinates 0, 10
  glBegin(GL_QUADS);
  {
    glColor3f(red, green, blue);
    glVertex2i(1, 11);
    glColor3f(red * .8, green * .8, blue * .8);
    glVertex2i(-1, 11);
    glColor3f(red * .5, green * .5, blue * .5);
    glVertex2i(-1, 9);
    glColor3f(red * .8, green * .8, blue * .8);
    glVertex2i(1, 9);
  }
  glEnd();
}

void Draw(void)
{
  // reset view matrix
  glLoadIdentity();

  // move view back a bit
  glTranslatef(0, 0, -30);

  // apply the current rotation
  glRotatef(rotate_y, 0, 1, 0);
  glRotatef(rotate_z, 0, 0, 1);

  // by repeatedly rotating the view matrix during drawing, the
  // squares end up in a circle
  int i = 0, squares = 15;
  float red = 0, blue = 1;

  for (; i < squares; ++i)
  {
    glRotatef(360.0/squares, 0, 0, 1);

    // colors change for each square
    red += 1.0/12;
    blue -= 1.0/12;
    Draw_Square(red, .6, blue);
  }

}

Podría ser que os saliera una ventana de cmd diciendoos que no puede abrir GLFW, que no puede crear la ventana, y/o que el formato de pixel no es válido, tranquilos, actualizad los drivers de la tarjeta gráfica y os debería funcionar todo a la perfección. Si os da otros problemas, decidlo y le buscaremos solución.

Una vez ya lo tengaís funcionando copiad esta linea al principio para quitar la consola (extraido del LPEngine)


//Delete console
#pragma comment(linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"")


Espero que os sirva, nos vemos

LordPakusBlog

2 comentarios :

  1. A mi no me funciona lo de ocultar la consola. Yo uso msvc 2010 Express.
    ¿Le pasa esto a alguien más?

    ResponderEliminar
  2. Que raro...a mi siempre me ha funcionado... le has encontrado alguna explicación? Tal vez no pusiste la linea al principio de todo del archivo...

    ResponderEliminar

Entradas populares