Created
August 8, 2019 00:40
-
-
Save kawzar/28bc09c5be4f85de788d1f6477098d53 to your computer and use it in GitHub Desktop.
Manipulacion de objetos en 2D - Avion
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// TP 2 - MO2D | |
// | |
#include <iostream> // cout | |
#include <cstdlib> // exit | |
#include <cmath> // fabs | |
#include <GL/glut.h> | |
#include "Teclado.h" | |
#include "uglyfont.h" | |
using namespace std; | |
//------------------------------------------------------------ | |
// variables globales | |
int | |
w=800,h=600; // tamanio inicial de la ventana | |
int segundos_transcurridos; | |
int milisegundos; | |
double | |
AvionX = 400, | |
AvionY = 300, | |
AvionAng = 0, | |
ArmaAng = 0, | |
ArmaTamanio = 0, | |
ZAvion = 0.5f, | |
ZTurbinas = 0.6f; | |
const double PI=4*atan(1.0); | |
bool cl_info=true; // informa por la linea de comandos | |
//============================================================ | |
// Renderiza texto en pantalla usando UglyFont | |
void print_text(string cadena, float x, float y, float escala = 1.0, float r = 1.0, float g = 1.0, float b = 1.0, float a = 1.0, float angulo = 0.0, int centrado = 0, float width = 1.0) { | |
glPushAttrib(GL_ALL_ATTRIB_BITS); | |
glLineWidth(width); // ancho de linea del caracter | |
glColor4f(r, g, b, a); // color del caracter | |
glPushMatrix(); | |
glTranslatef(x, y, 0);// posicion del caracter | |
glScalef(escala, escala, escala);// escala del caracter | |
glRotatef(angulo, 0, 0, 1); // angulo del caracter | |
YsDrawUglyFont(cadena.c_str(), centrado); // el caracter puede estar centrado o no | |
glPopMatrix(); | |
glPopAttrib(); | |
} | |
void DibujarCabina() { | |
glColor3d(0.6,0.7,0.9); | |
glBegin( GL_TRIANGLE_FAN ); | |
glVertex2d(0, 0); | |
for(double r=0; r<PI*2; r+=0.1) | |
glVertex2d(cos(r), sin(r)); | |
glVertex2d(1.0,0.0); | |
glEnd(); | |
} | |
void DibujarCuerpo() { | |
glColor3d(0.4,0.4,0.4); | |
glBegin( GL_TRIANGLE_FAN ); | |
glVertex2d(0.0, 0.0); | |
glVertex2d(0.0, 70.0); | |
glVertex2d(-8, 35.0); | |
glVertex2d(-10, -30.0); | |
glVertex2d(0.0, -15.0); | |
glVertex2d(10, -30.0); | |
glVertex2d(8, 35.0); | |
glVertex2d(0.0, 70.0); | |
glEnd(); | |
} | |
void DibujarAla() { | |
glColor3d(0.7,0.7,0.7); | |
glBegin( GL_TRIANGLE_FAN ); | |
glVertex2d(35,10); | |
glVertex2d(0.0,20.0); | |
glVertex2d(0.0,0.0); | |
glVertex2d(35,4); | |
glVertex2d(50.0,0.0); | |
glEnd(); | |
} | |
void DibujarObstaculo() { | |
glPushMatrix(); | |
glTranslated(0, 0, ZAvion); | |
glPushMatrix(); | |
glTranslated(15, 15, ZTurbinas); | |
glColor3f(0.1, 0.2, 0.1); | |
GLdouble baseRadius = 40; | |
int lod = 30; | |
GLint slices = lod, stacks = lod; | |
GLUquadricObj *q = gluNewQuadric(); | |
gluQuadricDrawStyle(q, GLU_FILL); | |
gluDisk(q, 0, baseRadius, slices, stacks); | |
gluDeleteQuadric(q); | |
glColor3f(0, 0.1, 0); | |
glPointSize(2); | |
glBegin(GL_POINTS); | |
for (double x = 0; x < 2 * PI; x += 0.4) | |
glVertex2d(40.0*0.8*cos(x), 40.0*0.8*sin(x)); | |
glEnd(); | |
glPopMatrix(); | |
glPopMatrix(); | |
} | |
void DibujarFarol() { | |
glColor3d(1.0, 1.0, 0.87f); | |
glBegin(GL_TRIANGLES); | |
glVertex2d(0.f, 70.f); | |
glVertex2d(15.f, 90.f); | |
glVertex2d(-15.f, 90.f); | |
glEnd(); | |
} | |
void DibujarTurbinas() { | |
glColor3d(0.686, 0.933, 0.933); | |
glBegin(GL_POLYGON); | |
for (double i = 0.f; i < 2 * PI; i += PI / 6) | |
glVertex3f(cos(i) * 5.0f + 25.f, sin(i) * 5.0f + 18.f, 0.0); | |
glEnd(); | |
glBegin(GL_POLYGON); | |
for (double i = 0.f; i < 2 * PI; i += PI / 6) | |
glVertex3f(cos(i) * 5.0f - 25.f, sin(i) * 5.0f + 18.f, 0.0); | |
glEnd(); | |
} | |
void DibujarAvion() { | |
glPushMatrix();// inicio push1 | |
// Posiciona y rota el Avion en el modelo | |
glTranslated(AvionX,AvionY,ZAvion); // ===== Agregue el ZAvion para que no quede en la posicion 0.0 e igual no se ve ==== | |
glRotated(AvionAng,0,0,1); | |
//Dibujamos las distintas partes de la nave, aplicando las transformaciones necesarias | |
//Ala derecha | |
glPushMatrix(); | |
DibujarAla(); | |
glPopMatrix(); | |
//Ala izquierda | |
glPushMatrix(); | |
glScaled(-1,1,1); //Con este escalamiento logramos reflejar (x = -AnchoAla * x) | |
DibujarAla(); | |
glPopMatrix(); | |
//Cuerpo | |
DibujarCuerpo(); | |
//Cabina | |
glPushMatrix(); | |
glScaled(6,12,1); | |
DibujarCabina(); | |
glPopMatrix(); | |
glPushMatrix(); | |
DibujarFarol(); | |
glPopMatrix(); | |
glPushMatrix(); | |
DibujarTurbinas(); | |
glPopMatrix(); | |
DibujarObstaculo(); | |
// Luego de aplicar la traslacion (AvionX,AvionY) y la rotacion (AvionAng) inicial | |
// dibuja un punto en la posici�n 0,0 (es solo para ayuda) | |
glColor3f(0.0f,0.0f,0.0f); | |
glPointSize(5.0); | |
glBegin(GL_POINTS); | |
glVertex2d(0.0,0.0); | |
glEnd(); | |
glPopMatrix();// fin push1 | |
} | |
void DibujarPared() { | |
glColor3f(0.9f,0.9f,0.9f); | |
glLineWidth(5.0); | |
glBegin(GL_LINES); | |
glVertex2i(325,400); glVertex2i(325,200); | |
glVertex2i(325,200); glVertex2i(475,200); | |
glVertex2i(475,200); glVertex2i(475,400); | |
glEnd(); | |
} | |
void DibujarTexto() { | |
char st4[10] = ""; | |
sprintf(st4, "%d", segundos_transcurridos); | |
print_text(st4, 60.0, 60.0, 10.0, 0.902, 0.902, 0.980, 1.0, 0.0, 5, 1.0); | |
} | |
//============================================================ | |
// callbacks | |
//------------------------------------------------------------ | |
// arma un un nuevo buffer (back) y reemplaza el framebuffer | |
void Display_cb() { | |
// arma el back-buffer | |
glClear(GL_COLOR_BUFFER_BIT);// rellena con color de fondo | |
/* | |
// dibuja un punto en la posici�n x,y que querramos visualizar (es solo para probar) | |
glColor3f(1.0f,0.0f,0.0f); | |
glPointSize(5.0); | |
glBegin(GL_POINTS); | |
glVertex2d(50,50); | |
glEnd(); | |
*/ | |
DibujarPared(); | |
DibujarAvion(); | |
DibujarTexto(); | |
glutSwapBuffers(); // lo manda al monitor | |
// chequea errores | |
int errornum=glGetError(); | |
while(errornum!=GL_NO_ERROR){ | |
if (cl_info){ | |
if(errornum==GL_INVALID_ENUM) | |
cout << "GL_INVALID_ENUM" << endl; | |
else if(errornum==GL_INVALID_VALUE) | |
cout << "GL_INVALID_VALUE" << endl; | |
else if (errornum==GL_INVALID_OPERATION) | |
cout << "GL_INVALID_OPERATION" << endl; | |
else if (errornum==GL_STACK_OVERFLOW) | |
cout << "GL_STACK_OVERFLOW" << endl; | |
else if (errornum==GL_STACK_UNDERFLOW) | |
cout << "GL_STACK_UNDERFLOW" << endl; | |
else if (errornum==GL_OUT_OF_MEMORY) | |
cout << "GL_OUT_OF_MEMORY" << endl; | |
} | |
errornum=glGetError(); | |
} | |
} | |
void idle_cb() { | |
static unsigned int lt = 0; | |
int dt = glutGet(GLUT_ELAPSED_TIME) - lt; | |
if (dt > 60) { | |
lt = glutGet(GLUT_ELAPSED_TIME); | |
Display_cb(); | |
} | |
// GLUT_ELAPSED_TIME devuelve el numero de milisegundos desde que se llamo a glutInit | |
milisegundos = glutGet(GLUT_ELAPSED_TIME); | |
if (milisegundos % 1000 == 0) { | |
segundos_transcurridos = milisegundos / 1000; | |
if (segundos_transcurridos == 30) { | |
Display_cb(); | |
cout << "Termino el tiempo!" << endl; | |
cout << "Pasaron " << segundos_transcurridos << " segundos!" << endl; | |
exit(EXIT_SUCCESS); | |
} | |
} | |
} | |
//------------------------------------------------------------ | |
// Maneja cambios de ancho y alto de la ventana | |
void Reshape_cb(int width, int height){ | |
// cout << "reshape " << width << "x" << height << endl; | |
if (!width||!height) return; // minimizado ==> nada | |
w=width; h=height; | |
glViewport(0,0,w,h); // regi�n donde se dibuja (toda la ventana) | |
// rehace la matriz de proyecci�n (la porcion de espacio visible) | |
glMatrixMode(GL_PROJECTION); glLoadIdentity(); | |
glOrtho(0,w,0,h,-1,1); // unidades = pixeles | |
// las operaciones subsiguientes se aplican a la matriz de modelado GL_MODELVIEW | |
glMatrixMode(GL_MODELVIEW); | |
glutPostRedisplay(); // avisa que se debe redibujar | |
} | |
//------------------------------------------------------------ | |
// Teclado | |
// Maneja pulsaciones del teclado (ASCII keys) | |
// x,y posicion del mouse cuando se teclea (aqui no importan) | |
void Keyboard_cb(unsigned char key,int x,int y) { | |
// Convierte AvionAng de grados a radianes | |
double ang=AvionAng*PI/180.0; | |
switch(key){ | |
case 'w': | |
case 'W': | |
// double sin(double ang); // Calcula el seno de ang medido en radianes | |
AvionX-=5*sin(ang); | |
AvionY+=5*cos(ang); | |
glutPostRedisplay(); | |
break; | |
case 's': | |
case 'S': | |
AvionX+=5*sin(ang); | |
AvionY-=5*cos(ang); | |
glutPostRedisplay(); | |
break; | |
case 'a': | |
case 'A': | |
AvionAng+=2; | |
glutPostRedisplay(); | |
break; | |
case 'd': | |
case 'D': | |
AvionAng-=2; | |
glutPostRedisplay(); | |
break; | |
case 27: | |
exit(EXIT_SUCCESS); | |
break; | |
} | |
} | |
// Special keys (non-ASCII) | |
// teclas de funcion, flechas, page up/dn, home/end, insert | |
void Special_cb(int key,int xm=0,int ym=0) { | |
if (key==GLUT_KEY_F4 && glutGetModifiers()==GLUT_ACTIVE_ALT) // alt+f4 => exit | |
exit(EXIT_SUCCESS); | |
} | |
//------------------------------------------------------------ | |
void inicializa() { | |
// GLUT | |
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH); | |
glutInitWindowSize(w,h); glutInitWindowPosition(10,10); | |
glutCreateWindow("Ejemplo Avion"); // crea el main window | |
// declara los callbacks, los que (aun) no se usan (aun) no se declaran | |
glutDisplayFunc(Display_cb); | |
glutReshapeFunc(Reshape_cb); | |
glutKeyboardFunc(Keyboard_cb); | |
glutSpecialFunc(Special_cb); | |
glutIdleFunc(idle_cb); | |
// OpenGL | |
glEnable(GL_BLEND); | |
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | |
// Activamos el z buffer ======= Cuando agregue esto dejo de verse la imagen ======== | |
glEnable(GL_DEPTH_TEST); // Enable Depth Test | |
glDepthFunc(GL_LEQUAL); // Specify the value used for depth buffer comparisons | |
glDepthRange(0.0, 1.0); // glDepthRange(zNear, zFar) sets the mapping of the z values to [0.0,1.0] | |
glClearDepth(1.0); | |
// OpenGL | |
//glClearColor(0.23f,0.20f,0.01f,1.f); // color de fondo | |
glClearColor(0.01f,0.01f,0.01f,1.f); | |
// las operaciones subsiguientes se aplican a la matriz de modelado GL_MODELVIEW | |
glMatrixMode(GL_MODELVIEW); glLoadIdentity(); | |
} | |
//------------------------------------------------------------ | |
// main | |
int main(int argc,char** argv) { | |
// teclas a utilizar | |
cout << "Teclas a utilizar:" << endl; | |
cout << "w: avanza" << endl; | |
cout << "s: retrocede" << endl; | |
cout << "d: gira en sentido horario" << endl; | |
cout << "a: gira en sentido antihorario" << endl; | |
glutInit(&argc,argv); // inicializaci�n interna de GLUT | |
inicializa(); // define el estado inicial de GLUT y OpenGL | |
glutMainLoop(); // entra en loop de reconocimiento de eventos | |
return 0; // nunca se llega ac�, es s�lo para evitar un warning | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment