Antes que nada, me presento, mi nombre es Arturo y soy Estudiante de Ing. En Computacion.
Les aviso que soy un total novato para OpenGL y al tratar de agregarle iluminación a este sistema solar me pinta absolutamente todo de rojo, no se por donde estará el error o si me este faltando algo.
Estoy usando C++ (aunque prácticamente de "++" no tiene nada)
Espero y puedan echarme una mano.
¡Saludos!
Les aviso que soy un total novato para OpenGL y al tratar de agregarle iluminación a este sistema solar me pinta absolutamente todo de rojo, no se por donde estará el error o si me este faltando algo.
Estoy usando C++ (aunque prácticamente de "++" no tiene nada)
Espero y puedan echarme una mano.
Código [Seleccionar]
#include "stdafx.h"
#include "GL/glut.h"
#include "math.h"
#define GL_PI 3.1415f
#define YGROUND 0.0f
#define LIGHT_X 3.0f
#define LIGHT_Y 8.5f
#define LIGHT_Z 1.0f
#define LIGHT_A 1.0f
GLfloat yground = YGROUND;
GLfloat vGroundPlane[4] = { 0.0f, 1.0f, 0.0f, -yground };
GLfloat lightPos[] = { LIGHT_X, LIGHT_Y, LIGHT_Z, LIGHT_A };
GLfloat shadowMat[16];
GLfloat xRot = 0.45f;
GLfloat yRot = 0.35f;
GLboolean bCull = glIsEnabled(GL_CULL_FACE);
GLboolean bDepth = glIsEnabled(GL_DEPTH_TEST);
GLboolean bOutline = (GLboolean)true;
GLenum shademode = GL_FLAT;
GLfloat ex = 0.0f;
GLfloat ey = 5.0f;
GLfloat ez = -10.0f;
GLfloat delta = 0.01f;
GLfloat deltaR = 0.01f;
int anioA = 0, anioB = 0, anioC = 0, dia = 0, luna = 0;
int angulo_z = 0;
int flag = 1;
///////////////////////////////////////////////////////////
float colores[6][4] = { { 0.0f, 1.0f, 0.0f, 0.75f }, { 1.0f, 0.0f, 0.0f, 0.75f }, { 0.0f, 0.0f, 1.0f, 0.75f }, { 0.5f, 0.5f, 0.0f, 0.75f }, { 0.5f, 0.0f, 0.5f, 0.75f }, { 0.0f, 0.5f, 0.5f, 0.75f } };
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 SetupRC()
{
// Black background
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
// Set color shading model to flat
glShadeModel(shademode);
// Clockwise-wound polygons are front facing; this is reversed
// because we are using triangle fans
glFrontFace(GL_CCW);
glEnable(GL_LIGHTING);
//Componentes de la luz
GLfloat ambientLight[] = { 0.8f, 0.8f, 0.8f, 1.0f };
GLfloat diffuseLight[] = { 1.0f, 1.0f, 1.0f, 1.0f };
GLfloat specularLight[] = { 1.0f, 1.0f, 1.0f, 1.0f };
glLightfv(GL_LIGHT0, GL_AMBIENT, ambientLight);
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseLight);
glLightfv(GL_LIGHT0, GL_SPECULAR, specularLight);
//Luz direccional
glLightfv(GL_LIGHT0, GL_POSITION, lightPos);
//Luz ambiental global
GLfloat globalAmbientLight[] = { 0.5f, 0.5f, 0.5f, 1.0f };
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, globalAmbientLight);
//Color del material
GLfloat ambientDifusse[] = { 0.7f, 0.0f, 0.0f, 1.0f };
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, ambientDifusse);
}
void sol(){
glPushMatrix();
glTranslatef(0.0f, 2.0f, 0.0f);
if (flag == 1){
glColor4f(1.0f, 1.0f, 0.0f, 0.75f);
}
if (bCull) glutSolidSphere(0.7f, 20, 16);
else glutWireSphere(0.7f, 20, 16);
glPopMatrix();
}
void Piso(){
glColor4f(0.55f, .55f, 0.55f, 0.55f);
glBegin(GL_QUADS);
glVertex3f(15.0f, 0.0f, 15.0f);
glVertex3f(15.0f, 0.0f, -15.0f);
glVertex3f(-15.0f, 0.0f, -15.0f);
glVertex3f(-15.0f, 0.0f, 15.0f);
glEnd();
}
void Draw_Light(void){
glPushMatrix();
glColor4f(1.0f, 1.0f, 0.0f, 0.75f);
glTranslatef(lightPos[0], lightPos[1], lightPos[2]);
glutSolidSphere(0.1f, 10, 10);
glPopMatrix();
}
void planetas(float p_anio, float p_dia, float p_luna, float tamanio, float distancia, float l_distancia, float p_color[])
{
glPushMatrix();
glTranslatef(0.0f, 2.0f, 0.0f);
glPushMatrix();
glRotatef(angulo_z, 0.0, 0.0, 0.0); //Ángulo constante de inclinacion en z
glRotatef((GLfloat)p_anio, 0.0, 1.0, 0.0); //Ángulo según el número de años
glTranslatef(distancia, 0.0, 0.0); //Distancia entre el Sol y el primer planeta (o entre planeta y planeta)
glPushMatrix();
glRotatef((GLfloat)p_dia, 0.0, 1.0, 0.0); //Ángulo del planeta según el día
if (flag == 1){
glColor4f(p_color[0], p_color[1], p_color[2], p_color[4]); // Color del planeta
}
if (bCull) glutSolidSphere(tamanio, 10, 8); /* Dibuja un primer planeta */
else glutWireSphere(tamanio, 10, 8);
glPopMatrix();
glRotatef(25, 0.0, 0.0, 0.0); //Ángulo constante de la Luna respecto a algún planeta
glRotatef((GLfloat)p_luna, 0.0, 1.0, 0.0); //Ángulo de la Luna según la hora
glTranslatef(l_distancia, 0.0, 0.0); //Distancia de la Luna respecto al planeta
if (flag == 1){
glColor4f(0.7, 0.7, 0.7, 0.75); //Color de la Luna
}
if (bCull) glutSolidSphere(0.07, 10, 8); //Dibuja la luna del primer planeta
else glutWireSphere(0.07, 10, 8);
glPopMatrix();
glPopMatrix();
}
void Sistema_para_sombra(void){
glPushMatrix();
glTranslatef(0., 1.5, 0.);
planetas(anioA, dia, luna, 0.1, 1.5, 0.25, colores[0]);
planetas(anioB, dia, luna, 0.2, 3.0, 0.35, colores[1]);
planetas(anioC, dia, luna, 0.3, 4.5, 0.45, colores[2]);
sol();
glPopMatrix();
}
void Sombra_Sistema(){
glLightfv(GL_LIGHT0, GL_POSITION, lightPos);
gltMakeShadowMatrix(vGroundPlane, lightPos, shadowMat);
glPushMatrix();
// Multiply by shadow projection matrix
gltMakeShadowMatrix(vGroundPlane, lightPos, shadowMat);
glMultMatrixf((GLfloat *)shadowMat);
glColor3f(0.25f, 0.25f, 0.25f);
Sistema_para_sombra();
glPopMatrix();
}
void Mundo(){
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
gluLookAt(ex, ey, ez, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
if (bCull) glEnable(GL_CULL_FACE);
else glDisable(GL_CULL_FACE);
// Enable depth testing if flag is set
if (bDepth) glEnable(GL_DEPTH_TEST);
else glDisable(GL_DEPTH_TEST);
// 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);
// Reflejo
glPushMatrix();
glFrontFace(GL_CW); // swap orientation
glScalef(1.0f, -1.0f, 1.0f); // geometry is mirrored by ground
glTranslatef(0.0f, -2.0f*yground, 0.0f);
/*Método que dibuja los planetas y las lunas*/
planetas(anioA, dia, luna, 0.1, 1.5, 0.25, colores[0]);
planetas(anioB, dia, luna, 0.2, 3.0, 0.35, colores[1]);
planetas(anioC, dia, luna, 0.3, 4.5, 0.45, colores[2]);
sol();
Draw_Light();
glPopMatrix();
glFrontFace(GL_CCW); //return orientation
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
Piso();
glDisable(GL_BLEND);
//Sombra
glDisable(GL_DEPTH_TEST);
flag = 0;
Sombra_Sistema();
flag = 1;
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHT0);
/*Dibujando el Sol*/
sol();
/*Método que dibuja los planetas y las lunas*/
planetas(anioA, dia, luna, 0.1, 1.5, 0.25, colores[0]);
planetas(anioB, dia, luna, 0.2, 3.0, 0.35, colores[1]);
planetas(anioC, dia, luna, 0.3, 4.5, 0.45, colores[2]);
//Foco de Luz
Draw_Light();
glDisable(GL_LIGHT0);
// Flush drawing commands
glutSwapBuffers();
}
// Called by GLUT library when the window has changed size
void ChangeSize(GLsizei w, GLsizei h)
{
// Set Viewport to window dimensions
glViewport(0, 0, (GLsizei)w, (GLsizei)h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60.0, (GLfloat)w / (GLfloat)h, 1.5, 500.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0.0, 1.0, 6.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
}
void SpecialKeys(int key, int x, int y)
{
GLfloat dx, dz, s, s1;
switch (key){
case GLUT_KEY_F5:anioA -= 4; //Caso que hace avanzar los planetas sobre sus órbitas.
anioB -= 2;
anioC -= 1;
glutPostRedisplay();
break;
case GLUT_KEY_F6:dia--; //Caso que permite que los planetas giren sobre su propio eje
glutPostRedisplay();
break;
case GLUT_KEY_F7:luna -= 4; //Caso que permite que las lunas giren alrededor de sus planetas
glutPostRedisplay();
break;
case GLUT_KEY_F1:bCull = !bCull;
glutPostRedisplay();
break;
case GLUT_KEY_F2:bDepth = !bDepth;
glutPostRedisplay();
break;
case GLUT_KEY_F3:bOutline = !bOutline;
glutPostRedisplay();
break;
case GLUT_KEY_F4:
if (shademode == GL_FLAT){
shademode = GL_SMOOTH;
}
else {
if (shademode == GL_SMOOTH){
shademode = GL_FLAT;
}
}
glShadeModel(shademode);
glutPostRedisplay();
break;
case GLUT_KEY_UP: ex *= (1.0f + deltaR); ey *= (1.0f + deltaR); ez *= (1.0f + deltaR);
glutPostRedisplay();
break;
case GLUT_KEY_DOWN: ex *= (1.0f - deltaR); ey *= (1.0f - deltaR); ez *= (1.0f - deltaR);
glutPostRedisplay();
break;
case GLUT_KEY_LEFT:
dx = -ez; dz = ex;
s = sqrtf(ex*ex + ey*ey + ez*ez);
ex += delta*dx; ez += delta*dz;
s1 = sqrtf(ex*ex + ey*ey + ez*ez) / s;
ex /= s1; ey /= s1; ey /= s1;
glutPostRedisplay();
break;
case GLUT_KEY_RIGHT:
dx = -ez; dz = ex;
s = sqrtf(ex*ex + ey*ey + ez*ez);
ex -= delta*dx; ez -= delta*dz;
s1 = sqrtf(ex*ex + ey*ey + ez*ez) / s;
ex /= s1; ey /= s1; ey /= s1;
glutPostRedisplay();
break;
default: break;
}
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(1500, 600);
glutInitWindowPosition(100, 100);
glutCreateWindow(argv[0]);
glutDisplayFunc(Mundo);
glutReshapeFunc(ChangeSize);
glutSpecialFunc(SpecialKeys);
SetupRC();
glutMainLoop();
return 0;
}
¡Saludos!