Рисунок OpenGL с отключенным освещением теряет глубину

Сейчас рисую большую комнату, все хорошо и красиво:

введите здесь описание изображения

Но он синий, так что я думаю, хорошо, я просто сначала отключу освещение, а затем нарисую комнату, снова включу его позже, и все будет хорошо, верно?

введите здесь описание изображения

Я полагаю, что нет... Он полностью теряет свою "глубину".

Могу ли я не просто сделать:

glDisable(GL_LIGHTING);
glColor3f(51/255.0, 25/255.0,0.0);
drawstuffhere
glEnable(GL_LIGHTING);

Или на это повлияла моя первоначальная установка освещения?

glClearColor(0.0, 0.0, 0.0, 0.0); glEnable(GL_DEPTH_TEST); // Включить тестирование глубины.

// Turn on OpenGL lighting.
glEnable(GL_LIGHTING);

// Light property vectors.
float lightAmb[] = { 0.0, 0.0, 0.0, 1.0 };
float lightDifAndSpec0[] = { 1.0, 1.0, 1.0, 1.0 };
float lightDifAndSpec1[] = { 1.0, 1.0, 0.0, 1.0 };
float globAmb[] = { 0.2, 0.2, 0.2, 1.0 };

// Light0 properties.
glLightfv(GL_LIGHT0, GL_AMBIENT, lightAmb);
glLightfv(GL_LIGHT0, GL_DIFFUSE, lightDifAndSpec0);
glLightfv(GL_LIGHT0, GL_SPECULAR, lightDifAndSpec0);

// Light1 properties.
glLightfv(GL_LIGHT1, GL_AMBIENT, lightAmb);
glLightfv(GL_LIGHT1, GL_DIFFUSE, lightDifAndSpec1);
glLightfv(GL_LIGHT1, GL_SPECULAR, lightDifAndSpec1);

glEnable(GL_LIGHT0); // Enable particular light source.
glEnable(GL_LIGHT1); // Enable particular light source.
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, globAmb); // Global ambient light.
glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE); // Enable local viewpoint

// Cull back faces.
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);

РЕДАКТИРОВАТЬ: Исходный код: http://pastebin.com/DKGpWiFB

///////////////////////////////////////////////////////////////////////////////////////////      
// main.cpp
// 

/////////////////////////////////////////////////////////////////////////////////////////// 

#include <iostream>
#include <fstream>

#ifdef __APPLE__
#  include <GLUT/glut.h>
#else
#  include <GL/glut.h>
#endif

using namespace std;
//Structures
struct perspectives {
    float ex,ey,ez,cx,cy,cz;
    int x, y, z;
};

struct coordinates {
    float x, y, z;
};

// Globals.
static float a = .1; // Blue ambient reflectance.
static float d = 1.0; // Blue diffuse reflectance.
static float s = 1.0; // White specular reflectance. 
static float h = 50.0; // Shininess.
static float e = 0.0; // Blue emittance.
static float t = 0.0; // Quadratic attenuation factor.
static float zMove = 0.0; // z-direction component.
static char theStringBuffer[10]; // String buffer.
static long font = (long)GLUT_BITMAP_8_BY_13; // Font selection.
static bool cameraRotate = false;

struct perspectives camera = {0,0,12,0,0,0,0,1,0};
struct coordinates key = {0,0,11};

// Routine to draw a bitmap character string.
void writeBitmapString(void *font, char *string)
{  
    char *c;

    for (c = string; *c != '\0'; c++) glutBitmapCharacter(font, *c);
}

// Routine to convert floating point to char string.
void floatToString(char * destStr, int precision, float val) 
{
    sprintf(destStr,"%f",val);
    destStr[precision] = '\0';
}

//Routine to draw a ball of light
void drawMoon()
{//TODO
        // Light position vectors.  
    float lightPos[] = { 3, 4, -.2, 1.0 };

    glDisable(GL_LIGHTING);

    // Light0 and its sphere positioned.
    glPushMatrix();
    glLightfv(GL_LIGHT1, GL_POSITION, lightPos);
    glTranslatef(lightPos[0], lightPos[1], lightPos[2]);
    glColor3f(1.0, 1.0, 1.0); 
    glutSolidSphere(2, 20, 20);
    glPopMatrix();


    glEnable(GL_LIGHTING);
}

//Routine to draw starry sky
void drawStars()
{
    //TODO
}

void drawPumpkin()
{
    //TODO
}

void drawKey()
{
    //TODO
}


//Routine to draw walls
void drawWalls()
{
    //glDisable(GL_LIGHTING);
    glColor3f(51/255.0,25/255.0,0);
    glPushMatrix();
    //glRotatef(0,0,0,1);
    glScalef(1,1,3);
    glBegin(GL_QUADS);
    /* Floor */
    glVertex3f(-1,-1,-1);
    glVertex3f(-1,-1,1);
    glVertex3f(1,-1,1);
    glVertex3f(1,-1,-1);
    /* Ceiling */
    glVertex3f(-1,1,-1);
    glVertex3f(1,1,-1);
    glVertex3f(1,1,1);
    glVertex3f(-1,1,1);
    /* Walls */

    /* front outer */
    /* left half */
    glVertex3f(-1,-1,1);
    glVertex3f(-.45,-1,1);
    glVertex3f(-.45,1,1);
    glVertex3f(-1,1,1);

    /* right half */
    glVertex3f(.45,-1,1);
    glVertex3f(1,-1,1);
    glVertex3f(1,1,1);
    glVertex3f(.45,1,1);

    /* top half */

    glVertex3f(-1,.5,1);
    glVertex3f(1,.5,1);
    glVertex3f(1,1,1);
    glVertex3f(-1,1,1);
    /* end front outer */

    /* front door */
    //TODO

    /* end front door */

    /* back inner */
    /* left half */
    glVertex3f(-1,-1,-1);
    glVertex3f(-.45,-1,-1);
    glVertex3f(-.45,1,-1);
    glVertex3f(-1,1,-1);

    /* right half */
    glVertex3f(.45,-1,-1);
    glVertex3f(1,-1,-1);
    glVertex3f(1,1,-1);
    glVertex3f(.45,1,-1);

    /* top half */

    glVertex3f(-1,.5,-1);
    glVertex3f(1,.5,-1);
    glVertex3f(1,1,-1);
    glVertex3f(-1,1,-1);
    /* end inner */

    glVertex3f(1,1,1);
    glVertex3f(1,1,-1);
    glVertex3f(1,-1,-1);
    glVertex3f(1,-1,1);


    glVertex3f(-1,1,1);
    glVertex3f(-1,-1,1);
    glVertex3f(-1,-1,-1);
    glVertex3f(-1,1,-1);
    glEnd();

    glPopMatrix();
    //glEnable(GL_LIGHTING);
}

void drawLight()
{
    // Light position vectors.  
    float lightPos0[] = { 0.0, .75, -.5, 1.0 };

    glDisable(GL_LIGHTING);

    // Light0 and its sphere positioned.
    glPushMatrix();
    glLightfv(GL_LIGHT0, GL_POSITION, lightPos0);
    glTranslatef(lightPos0[0], lightPos0[1], lightPos0[2]);
    glColor3f(1.0, 1.0, 1.0); 
    glutWireSphere(0.05, 8, 8);
    glPopMatrix();


    glEnable(GL_LIGHTING);
}

// Initialization routine.
void setup(void)
{
    //Set globals

    a = 1- abs(camera.ez/15.0);

    glClearColor(0.0, 0.0, 0.0, 0.0);
    glEnable(GL_DEPTH_TEST); // Enable depth testing.

    // Turn on OpenGL lighting.
    glEnable(GL_LIGHTING);

    // Light property vectors.
    float lightAmb[] = { 0.0, 0.0, 0.0, 1.0 };
    float lightDifAndSpec0[] = { 1.0, 1.0, 1.0, 1.0 };
    float lightDifAndSpec1[] = { 1.0, 1.0, 0.0, 1.0 };
    float globAmb[] = { 0.2, 0.2, 0.2, 1.0 };

    // Light0 properties.
    glLightfv(GL_LIGHT0, GL_AMBIENT, lightAmb);
    glLightfv(GL_LIGHT0, GL_DIFFUSE, lightDifAndSpec0);
    glLightfv(GL_LIGHT0, GL_SPECULAR, lightDifAndSpec0);

    // Light1 properties.
    glLightfv(GL_LIGHT1, GL_AMBIENT, lightAmb);
    glLightfv(GL_LIGHT1, GL_DIFFUSE, lightDifAndSpec1);
    glLightfv(GL_LIGHT1, GL_SPECULAR, lightDifAndSpec1);

    glEnable(GL_LIGHT0); // Enable particular light source.
    glEnable(GL_LIGHT1); // Enable particular light source.
    glLightModelfv(GL_LIGHT_MODEL_AMBIENT, globAmb); // Global ambient light.
    glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE); // Enable local viewpoint

    // Cull back faces.
    glEnable(GL_CULL_FACE);
    glCullFace(GL_BACK);
}

// Drawing routine.
void drawScene()
{  


    // Material property vectors.
    float matAmb[] = {0.0, 0.0, a, 1.0};
    float matDif[] = {0.0, 0.0, d, 1.0};
    float matSpec[] = { s, s, s, 1.0 };
    float matShine[] = { h };
    float matEmission[] = {0.0, 0.0, e, 1.0};

    glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();

    // Light quadratic attenuation factor.
    glLightf(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, t);
    glLightf(GL_LIGHT1, GL_QUADRATIC_ATTENUATION, t);


    //gluLookAt(0.0, ey, ez, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);

    gluLookAt(camera.ex,camera.ey, camera.ez,
        camera.cx,camera.cy,camera.cz,
        camera.x,camera.y,camera.z);
    //gluLookAt(0,0,0,0,0,0,0,1,0);
    // Draw light source spheres after disabling lighting.
    drawLight();

    // Material properties of sphere.
    glMaterialfv(GL_FRONT, GL_AMBIENT, matAmb);
    glMaterialfv(GL_FRONT, GL_DIFFUSE, matDif);
    glMaterialfv(GL_FRONT, GL_SPECULAR, matSpec);
    glMaterialfv(GL_FRONT, GL_SHININESS, matShine);
    glMaterialfv(GL_FRONT, GL_EMISSION, matEmission);
    // Sphere.
    glTranslatef(0.0, 0.0, zMove); // Move the sphere.

    //glutSolidCube(1.5);
    drawWalls();
    drawMoon();

    glutSwapBuffers();
}

// OpenGL window reshape routine.
void resize (int w, int h)
{
    glViewport (0, 0, (GLsizei)w, (GLsizei)h);
    glMatrixMode (GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(60.0, (float)w/(float)h, 1.0, 100.0);
    glMatrixMode(GL_MODELVIEW);
}

// Keyboard input processing routine.
void keyInput(unsigned char key, int x, int y)
{

    int mod = glutGetModifiers();

    if (mod!=0)
    {
        switch(mod)
        {
            //Shift key
        case 1 : cameraRotate=true; break;
            //ALT key
        case 4 : ; break;
        mod = 0;
        }

    }


    switch (key) 
    {
    case 27:
        exit(0);
        break;
    case 'a':
        if (a > 0.0) a -= 0.05;
        glutPostRedisplay();
        break;
    case 'A':
        if (a < 1.0) a += 0.05;
        glutPostRedisplay();
        break;
    case 'd':
        if (d > 0.0) d -= 0.05;
        glutPostRedisplay();
        break;
    case 'D':
        if (d < 1.0) d += 0.05;
        glutPostRedisplay();
        break;
    case 's':
        if (s > 0.0) s -= 0.05;
        glutPostRedisplay();
        break;
    case 'S':
        if (s < 1.0) s += 0.05;
        glutPostRedisplay();
        break;
    case 'e':
        if (e > 0.0) e -= 0.05;
        glutPostRedisplay();
        break;
    case 'E':
        if (e < 1.0) e += 0.05;
        glutPostRedisplay();
        break;
    case 'h':
        if (h > 0.0) h -= 1.0;
        glutPostRedisplay();
        break;
    case 'H':
        if (h < 128.0) h += 1.0;
        glutPostRedisplay();
        break;
    case 't':
        if (t > 0.0) t -= 0.005;
        glutPostRedisplay();
        break;
    case 'T':
        t += 0.005;
        glutPostRedisplay();
        break;
    default:
        break;
    }
}

// Callback routine for non-ASCII key entry.
void specialKeyInput(int key, int x, int y)
{

    if (key == GLUT_KEY_UP){
        if(camera.ez - .1 >= 0)
        {camera.ez += -0.1;
        camera.ex += 0;}
    }
    if (key == GLUT_KEY_DOWN){
        camera.ez += 0.1;
        camera.ex += 0;
    }
    if (key == GLUT_KEY_LEFT){
        camera.cx -= .1;
    }
    if (key == GLUT_KEY_RIGHT){
        camera.cx += .1;
    }
    printf("This is my ez %f\n", camera.ez);


    a = 1- abs(camera.ez/5.0);
    glutPostRedisplay();
}

// Routine to output interaction instructions to the C++ window.
void printInteraction(void)
{
}

// Main routine.
int main(int argc, char **argv) 
{
    printInteraction();
    glutInit(&argc, argv);
    glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); 
    glutInitWindowSize (600, 600);
    glutInitWindowPosition (100, 100);
    glutCreateWindow ("scaryRoom.cpp");
    setup();
    glutDisplayFunc(drawScene);
    glutReshapeFunc(resize);
    glutKeyboardFunc(keyInput);
    glutSpecialFunc(specialKeyInput);
    glutMainLoop();

    return 0;
}

person Stupid.Fat.Cat    schedule 02.11.2013    source источник


Ответы (1)


OpenGL — это API рисования на основе состояний. Как только вы нарисуете что-то, OpenGL этого не запомнит. Все происходит во время рисования, и если в момент рисования нет настройки освещения, то все.

Я понятия не имею, почему твоя комната такая голубая; Я должен был бы увидеть полный код для этого. Однако я могу дать вам совет, что вы не должны пытаться «инициализировать» вещи в определенное время, а затем «жить» с этим. OpenGL — это конечный автомат, предназначенный для установки каждого важного атрибута прямо перед тем, как он вам действительно понадобится. Поэтому я предлагаю вам перенести настройки освещения и цвета как можно ближе к фактическому рисунку.

Обновлять

Вы устанавливаете материальное состояние в своей функции drawScene. Они повлияют на все, нарисованное после установки этих состояний, пока вы их не измените. Вы хотели, чтобы они воздействовали только на сферу, но они повлияют и на все остальное. Обратите внимание, что glColor не повлияет на рисование с подсветкой, если только вы не включите и не установите так называемое состояние color material.

Однако я настоятельно рекомендую вам вообще не заморачиваться с загадочным конвейером фиксированных функций. Вы уже столкнулись с несколькими ловушками :) Я предлагаю вам изучить современный OpenGL, который также избегает всех этих странных особенностей. Очень хорошее руководство можно найти по адресу http://arcsynchronous.org/gltut.

person datenwolf    schedule 02.11.2013
comment
Поможет ли предоставление исходного кода (я обновил вопрос до pastebin с исходным кодом)? Я не слишком знаком с тем, как работает OpenGL, не говоря уже об освещении. - person Stupid.Fat.Cat; 02.11.2013
comment
@Stupid.Fat.Cat: Обычно вы вставляете исходный код в вопрос дословно (pastebins уходят, а SO вопросы - нет). И да, это помогает. - person datenwolf; 02.11.2013