Skip to content

Instantly share code, notes, and snippets.

@kawzar
Created August 8, 2019 00:40
Show Gist options
  • Save kawzar/28bc09c5be4f85de788d1f6477098d53 to your computer and use it in GitHub Desktop.
Save kawzar/28bc09c5be4f85de788d1f6477098d53 to your computer and use it in GitHub Desktop.
Manipulacion de objetos en 2D - Avion
// 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