Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





[OpenGL] Problemas con Iluminacion

Iniciado por MrLennon, 08 de Diciembre de 2014, 10:59:32 PM

« anterior - próximo »

MrLennon

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.


#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!

Gallo

supongo que es por la luz ambiental que es roja.

GLfloat ambientDifusse[] = { 0.7f, 0.0f, 0.0f, 1.0f };

De todas formas toda esta funcionalidad pertenece a OpenGL 1.0 y hoy en día ya no se hace así, se utilizan shaders, te recomiendo que si estas siguiendo algún tutorial o libro busques algo mas actualizado, algo de OpenGL 2 o 3 al menos, pero sobretodo que utilice vertex y fragment shaders.

Lo que cambia de esa versión a como se hace ahora es que las operaciones de push y pop matrix ya no las hace OpenGL si no que se delega en el usuario, pero hay muchas libs que te pueden ayudar a esto com GLM, los vertices de los modelos 3D no se envían continuamente a la gráfica si no que se almacena al principio en su memoria y se usa una referencia para pintarlos, y las funciones referentes a iluminación y material ya no son implementaciones de OpenGL si no que pasan a ser shaders escritos por ti. Puede que te parezca que es avanzarse demasiado pero no es avanzado, simplemente es como se hace ahora, las funciones que estas utilizando ya se consideran deprecadas en las nuevas versiones de OpenGL y han sido reemplazadas.

Por cierto, glut está bastante bien y para empezar creo que es suficiente, pero quizá mas adelante te interese utilizar algo como GLFW http://www.glfw.org/, en mi opinion es mas completa.

También necesitarás algo como GLEW o gl3w, para inicializar las funciones de OpenGL, ya que no se linkan como antes.

Si estas interesado en un libro que te pueda enseñar mejor, te recomendaria OpenGL Superbible: http://www.amazon.com/OpenGL-SuperBible-Comprehensive-Tutorial-Reference/dp/0321902947

La sexta edición es de OpenGL 4, pero si no tienes una máquina moderna o buscas aprender 2 y 3, entonces te recomiendo la 5ª edición, que es sobre OpenGL 3, pero contiene mucho código de OpenGL 2, aunque personalmente me gusta mucho mas el material proporcionado en la sexta edición, pese a ser una versión quizá demasiado nueva por ahora (la 4), la presentación y el material son mucho mejores que en la quinta edición.

Dicho esto, en mi opinion hoy en dia lo mas "rápido y sencillo" para aprender OpenGL, realmente no es OpenGL si no WebGL, la API en javascript basada en OpenGL ES 2,  hay muchos tutoriales sobre esta API y es gemela de OpenGL, lo que aprendas en una prácticamente se aplica en la otra, solo que al ser en navegador y con javascript te ahorras bastante código no relacionado directamente con OpenGL, como gestionar la ventana, el input, o cargar texturas, te viene dado, de hecho aquí tienes un ejemplo de lo que quieres hacer, en WebGL (recomiendo abrir con Chrome): http://www.webdev20.pl/skins/default/js/demos/solar_system/index.html

Saludos.






Stratos es un servicio gratuito, cuyos costes se cubren en parte con la publicidad.
Por favor, desactiva el bloqueador de anuncios en esta web para ayudar a que siga adelante.
Muchísimas gracias.