#include #include #include //#include #include #include using namespace std; // Pr_OO_15I.cpp: define el punto de entrada de la aplicaciуn de consola. // #define YGROUND 1.f #define EX 0.0f #define EY 1.0f #define EZ 3.0f #define CX 0.0f #define CY YGROUND #define CZ 0.0f #define DELTA 0.01f #define DELTA_R 0.01f GLfloat delta = DELTA, deltaR = DELTA_R, yRot = 0.0f; // Rotation angle for animation GLboolean bCull = (GLboolean)true, bDepth = (GLboolean)true, bOutline = (GLboolean)true, bShade = (GLboolean)true; GLsizei wSize = 500, hSize = 500; GLfloat ex = EX, ey = EY + CY, ez = EZ, cx = CX, cy = CY, cz = CZ; GLfloat vPlanoPiso[4] = { 0.f, 1.f, 0.f, YGROUND }, vPosLuz[3] = { 2.f, 5.f, -3.f }, MatSombra[16]; GLfloat m[16], mP[16], mVP[4]; void gltMakeShadowMatrix(GLfloat vPlaneEquation[], GLfloat vLightPos[], GLfloat destMat[]) { GLfloat dot; // Dot product of plane and light position dot = vPlaneEquation[0] * vLightPos[0] + vPlaneEquation[1] * vLightPos[1] + vPlaneEquation[2] * vLightPos[2] + vPlaneEquation[3] * vLightPos[3]; // Now do the projection // First column destMat[0] = dot - vLightPos[0] * vPlaneEquation[0]; destMat[4] = 0.0f - vLightPos[0] * vPlaneEquation[1]; destMat[8] = 0.0f - vLightPos[0] * vPlaneEquation[2]; destMat[12] = 0.0f - vLightPos[0] * vPlaneEquation[3]; // Second column destMat[1] = 0.0f - vLightPos[1] * vPlaneEquation[0]; destMat[5] = dot - vLightPos[1] * vPlaneEquation[1]; destMat[9] = 0.0f - vLightPos[1] * vPlaneEquation[2]; destMat[13] = 0.0f - vLightPos[1] * vPlaneEquation[3]; // Third Column destMat[2] = 0.0f - vLightPos[2] * vPlaneEquation[0]; destMat[6] = 0.0f - vLightPos[2] * vPlaneEquation[1]; destMat[10] = dot - vLightPos[2] * vPlaneEquation[2]; destMat[14] = 0.0f - vLightPos[2] * vPlaneEquation[3]; // Fourth Column destMat[3] = 0.0f - vLightPos[3] * vPlaneEquation[0]; destMat[7] = 0.0f - vLightPos[3] * vPlaneEquation[1]; destMat[11] = 0.0f - vLightPos[3] * vPlaneEquation[2]; destMat[15] = dot - vLightPos[3] * vPlaneEquation[3]; } void pickScreenVertexCoord(GLfloat xV, GLfloat yV, GLfloat zV, GLfloat & xSCR, GLfloat &ySCR){ GLfloat scr[4], scrt[4]; glGetFloatv(GL_VIEWPORT, mVP); glGetFloatv(GL_PROJECTION_MATRIX, mP); glGetFloatv(GL_MODELVIEW_MATRIX, m); glPushMatrix(); glLoadIdentity(); glMultMatrixf(mP); glMultMatrixf(m); glGetFloatv(GL_MODELVIEW_MATRIX, m); scr[0] = m[0] * xV + m[4] * yV + m[8] * zV + m[12] * 1.f; scr[1] = m[1] * xV + m[5] * yV + m[9] * zV + m[13] * 1.f; scr[2] = m[2] * xV + m[6] * yV + m[10] * zV + m[14] * 1.f; scr[3] = m[3] * xV + m[7] * yV + m[11] * zV + m[15] * 1.f; glPopMatrix(); xSCR = (mVP[2] - mVP[0])*0.5*(1.f + scr[0] / scr[3]); ySCR = (mVP[3] - mVP[1])*0.5*(1.f + scr[1] / scr[3]); cout << "Vertex x, y, z = " << xV <<" "<< yV <<" "<< zV << endl; cout << "Screen coordinates x, y = " << xSCR << " " << ySCR << endl; cout << "wSize, hSize = " << wSize << " " << hSize << endl; } void Cara(){ /*V_screen = M_Viewport * M_Projection * M_ModelView * V_local*/ glBegin(GL_QUADS); glVertex2f(-1.f, -1.f); glVertex2f(1.f, -1.f); glVertex2f(1.f, 1.f); glVertex2f(-1.f, 1.f); glEnd(); } void Cara_de_Cubo(){ glPushMatrix(); glTranslatef(0.f, 0.f, 1.f); Cara(); glPopMatrix(); } void Objetos_sin_colores(){ Cara_de_Cubo(); glPushMatrix(); glRotatef(90.f, 0.f, 1.f, 0.f); Cara_de_Cubo(); glPopMatrix(); glPushMatrix(); glRotatef(180.f, 0.f, 1.f, 0.f); Cara_de_Cubo(); glPopMatrix(); glPushMatrix(); glRotatef(270.f, 0.f, 1.f, 0.f); Cara_de_Cubo(); glPopMatrix(); } void Objetos(){ glColor3f(1.f, 0.f, 0.f); Cara_de_Cubo(); glColor3f(0.f, 1.f, 0.f); glPushMatrix(); glRotatef(90.f, 0.f, 1.f, 0.f); Cara_de_Cubo(); glPopMatrix(); glColor3f(0.f, 0.f, 1.f); glPushMatrix(); glRotatef(180.f, 0.f, 1.f, 0.f); Cara_de_Cubo(); glPopMatrix(); glColor3f(0.f, 1.f, 1.f); glPushMatrix(); glRotatef(270.f, 0.f, 1.f, 0.f); Cara_de_Cubo(); glPopMatrix(); } void SombradeMiMundo(/*datosdeLuz, datosdePlano*/){ glColor4f(0.4f, 0.4f, 0.4f, 0.65f); glPushMatrix(); gltMakeShadowMatrix(vPlanoPiso, vPosLuz, MatSombra); /*MatrizSombra(datosdeLuz, datosdePlano, matrizdeSombra);*/ glMultMatrixf(MatSombra/*matrizdeSombra*/); Objetos_sin_colores(); //Objetos_de_MiMundo(); glPopMatrix(); } void Luz(){ glPushMatrix(); glTranslatef(vPosLuz[0], vPosLuz[1], vPosLuz[2]); glColor3f(6.f, 6.f, 0.f); glutSolidSphere(0.3f, 20, 20); glPopMatrix(); } void Piso(){ glColor4f(0.8f, 0.8f, 0.8f, 0.65F); glBegin(GL_QUADS); glVertex3f(-7.f, -YGROUND, -7.f); glVertex3f(7.f, -YGROUND, -7.f); glVertex3f(7.f, -YGROUND, 7.f); glVertex3f(-7.f, -YGROUND, 7.f); glEnd(); } void RenderScene(void) { // Reset coordinate system glLoadIdentity(); gluLookAt(ex, ey, ez, cx, cy, cz, 0.0, 1.0, 0.0); // Clear the window with current clearing color glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushMatrix(); // recordar la matriz actual glFrontFace(GL_CW); // cambiar orientacion de poligonos para invertir los lados delanteros y traseros /* dibujar mundo invertido */ glScalef(1.0f, -1.0f, 1.0f); glTranslatef(0.0f, 2.0f*vPlanoPiso[3], 0.0f); Luz(); Objetos(); glFrontFace(GL_CCW); // restaurar orientaciуn glPopMatrix(); //glDisable(GL_LIGHTING); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); GLfloat xSCR, ySCR; pickScreenVertexCoord(-7.f, -YGROUND, -7.f, xSCR, ySCR); Piso(); glDisable(GL_BLEND); //glEnable(GL_LIGHTING); // restaurar matriz ////////////////// Luz(); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glDisable(GL_DEPTH_TEST); SombradeMiMundo(); glEnable(GL_DEPTH_TEST); glDisable(GL_BLEND); pickScreenVertexCoord(-1.f, -1.f, -0.f, xSCR, ySCR); Objetos(); glFlush(); } void ChangeSize(GLsizei w, GLsizei h) { // Set Viewport to window dimensions glViewport(0, 0, (GLsizei)w, (GLsizei)h); wSize = (GLsizei)w; hSize = (GLsizei)h; glMatrixMode(GL_PROJECTION); glLoadIdentity(); //glOrtho (-100.0, 100.0, -100, 100, -270.0, 270.0); //glFrustum (-1.0, 1.0, -1.0, 1.0, 1.5, 20.0); gluPerspective(60.0, 1.0, 1.5, 2000.0); glMatrixMode(GL_MODELVIEW); } void SetupRC() { // Bluish background glClearColor(0.0f, 0.0f, .50f, 1.0f); // Set color shading model to flat glShadeModel(GL_FLAT); // Clockwise-wound polygons are front facing; this is reversed // because we are using triangle fans glFrontFace(GL_CCW); } void SpecialKeys(int key, int x, int y) { GLfloat dx, dy, dz, dx0, dy0, dz0; if (key == GLUT_KEY_UP) {//increase distance from camera to origin dx = cx - ex; dy = cy - ey; dz = cz - ez; ex -= deltaR*dx; ey -= deltaR*dy; ez -= deltaR*dz; yRot += 0.5f; glutPostRedisplay(); return; } if (key == GLUT_KEY_DOWN) {//reduce distance from camera to origin (close up) dx = cx - ex; dy = cy - ey; dz = cz - ez; ex += deltaR*dx; ey += deltaR*dy; ez += deltaR*dz; yRot += 0.5f; glutPostRedisplay(); return; } if (key == GLUT_KEY_LEFT) //Rotate (+) camera around origin in Oxz plane { dx0 = cz - ez; dz0 = ex - cx; dx = cx - ex; dz = cz - ez; GLfloat s = sqrtf(dx*dx + dz*dz); dx += delta*dx0; dz += delta*dz0; GLfloat s1 = sqrtf(dx*dx + dz*dz) / s; dx /= s1; dz /= s1; ex = cx - dx; ez = cz - dz; yRot += 0.5f; glutPostRedisplay(); return; } if (key == GLUT_KEY_RIGHT) //Rotate (-) camera around origin in Oxz plane { dx0 = cz - ez; dz0 = ex - cx; dx = cx - ex; dz = cz - ez; GLfloat s = sqrtf(dx*dx + dz*dz); dx -= delta*dx0; dz -= delta*dz0; GLfloat s1 = sqrtf(dx*dx + dz*dz) / s; dx /= s1; dz /= s1; ex = cx - dx; ez = cz - dz; yRot += 0.5f; glutPostRedisplay(); return; } if (key == GLUT_KEY_F1){ bCull = !bCull; // Turn on/off culling on if flag is set if (bCull) glEnable(GL_CULL_FACE); else glDisable(GL_CULL_FACE); yRot += 0.5f; glutPostRedisplay(); return; } if (key == GLUT_KEY_F2){ bDepth = !bDepth; if (bDepth) glEnable(GL_DEPTH_TEST); else glDisable(GL_DEPTH_TEST); yRot += 0.5f; glutPostRedisplay(); return; } if (key == GLUT_KEY_F3){ bOutline = !bOutline; // Draw the back side as a wireframe only, if flag is set if (bOutline)glPolygonMode(GL_BACK, GL_LINE); else glPolygonMode(GL_BACK, GL_FILL); yRot += 0.5f; glutPostRedisplay(); return; } if (key == GLUT_KEY_F4) { bShade = !bShade; if (bShade){ glShadeModel(GL_FLAT); } else { glShadeModel(GL_SMOOTH); } yRot += 0.5f; glutPostRedisplay(); return; } if (key == GLUT_KEY_F5)//Rotate camera around scene center in Oyz plane { dy0 = cz - ez; dz0 = ey - cy; dy = cy - ey; dz = cz - ez; GLfloat s = sqrtf(dy*dy + dz*dz); dy += delta*dy0; dz += delta*dz0; GLfloat s1 = sqrtf(dy*dy + dz*dz) / s; dy /= s1; dz /= s1; ey = cy - dy; ez = cz - dz; yRot += 0.5f; glutPostRedisplay(); return; } if (key == GLUT_KEY_F6)//Rotate camera around scene center in Oyz plane { dy0 = cz - ez; dz0 = ey - cy; dy = cy - ey; dz = cz - ez; GLfloat s = sqrtf(dy*dy + dz*dz); dy -= delta*dy0; dz -= delta*dz0; GLfloat s1 = sqrtf(dy*dy + dz*dz) / s; dy /= s1; dz /= s1; ey = cy - dy; ez = cz - dz; yRot += 0.5f; glutPostRedisplay(); return; } } void mouse(GLint boton, GLint accion, GLint xMouse, GLint yMouse) { if (boton == GLUT_LEFT_BUTTON && accion == GLUT_DOWN){ { cout << "\n wSize= " << wSize << " hSize=" << hSize << endl; cout << " xMouse=" << xMouse << " yMouse=" << yMouse << endl; cout << " hSize - yMouse=" << hSize - yMouse << endl; } } } int main(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); glutInitWindowSize(wSize, hSize); glutInitWindowPosition(100, 100); glutCreateWindow(argv[0]); glutDisplayFunc(RenderScene); glutReshapeFunc(ChangeSize); glutSpecialFunc(SpecialKeys); glutMouseFunc(mouse); SetupRC(); glutMainLoop(); return 0; }