2017-08-14 3 views
0

Mon programme est une pièce avec une source de lumière au centre (la sphère).La couleur et le mouvement de l'objet OpenGL ne s'alternent pas correctement

enter image description here

Je veux faire un mode « disco » qui fera le déplacement de la sphère gauche et à droite le long de l'axe x. Et alternent également sa couleur entre le rouge et le bleu en même temps.

C'est la section de mon code qui active le mode. g_disco_mode est la variable qui est vraie une fois le mode choisi.

static void update_scene() 
{ 
    ... 

    // Disco mode 
    if (g_disco_mode) 
    { 
     bool movement_increase = true; 
     bool color_increase = true; 
     float floor = -0.1f; 
     float ceiling = 1.0f; 
     float increment = 0.01f; 

     // Movement of spotlight 
     if (movement_increase == true && g_lightProperties.direction[0] <= ceiling) 
     { 
      g_lightProperties.direction[0] += increment; 

      if (g_lightProperties.direction[0] >= ceiling) { movement_increase = false; } 
     } 

     if (movement_increase == false && g_lightProperties.direction[0] >= floor) 
     { 
      g_lightProperties.direction[0] -= increment; 

      if (g_lightProperties.direction[0] <= floor) { movement_increase = true; } 
     } 

     // Changing of color 
     g_spotlight_ambient[0] += 0.01f; 

     if (color_increase == true && g_spotlight_ambient[0] <= ceiling) 
     { 
      g_spotlight_ambient[0] += increment; 

      if (g_spotlight_ambient[0] >= ceiling) { color_increase = false; } 
     } 

     if (color_increase == false && g_spotlight_ambient[0] >= floor) 
     { 
      g_spotlight_ambient[0] -= increment; 

      if (g_spotlight_ambient[0] <= floor) { color_increase = true; } 
     } 
    } 
} 

J'ai écrit cette section de code tel que la sphère se déplacer vers la droite jusqu'à ce qu'il touche le ceiling puis déplacer vers la gauche jusqu'à ce qu'il touche le floor. Ceci est fait en incrémentant et décrémentant g_lightProperties.direction. Le changement de couleur fonctionne de la même manière. Cependant, lorsque j'exécute mon programme, la sphère se déplace à droite jusqu'à ce qu'elle atteigne ceiling puis s'arrête. Il ne bouge pas bouger vers la gauche. Pour la couleur, il continue à tourner au rouge et ne revient pas au bleu. Pourquoi est-ce si?

Mon programme

// Values for spotlight 
glm::vec3 g_spotlight_ambient(0.2f, 0.2f, 0.2f); 
glm::vec3 g_spotlight_diffuse(0.0f, 0.5f, 1.0f); 
glm::vec3 g_spotlight_specular(0.0f, 0.5f, 1.0f); 

bool g_switchOn = true;  // toggle the light on/off 
bool g_disco_mode = false; // makes the lights move around and change color 

static void init(GLFWwindow* window) 
{ 
    ... 

// initialise light and material properties 
    g_lightProperties.position = glm::vec4(0.0f, 2.0f, 0.0f, 1.0f); 
    g_lightProperties.ambient = glm::vec4(g_spotlight_ambient[0], g_spotlight_ambient[1], g_spotlight_ambient[2], 1.0f); 
    g_lightProperties.diffuse = glm::vec4(g_spotlight_diffuse[0], g_spotlight_diffuse[1], g_spotlight_diffuse[2], 1.0f); 
    g_lightProperties.specular = glm::vec4(g_spotlight_specular[0], g_spotlight_specular[1], g_spotlight_specular[2], 1.0f); 
    g_lightProperties.shininess = 10.0f; 
    g_lightProperties.attenuation = glm::vec3(1.0f, 0.0f, 0.0f); 
    g_lightProperties.cutoffAngle = 100.0f; 
    g_lightProperties.direction = glm::vec3(0.0f, -1.0f, 0.0f); 

    ... 
} 

// function used to update the scene 
static void update_scene() 
{ 
    static float rotateAngle = 0.0f; 
    static float cutOffAngle = g_lightProperties.cutoffAngle; 

    rotateAngle -= 1.0f; 

    // update model matrix 
    g_modelMatrix_mesh[0] = glm::rotate(glm::radians(rotateAngle), glm::vec3(0.0f, 1.0f, 0.0f)) 
      * glm::translate(glm::vec3(-0.4f, 0.1f, 0.0f)) * glm::scale(glm::vec3(0.3f, 0.3f, 0.3f)); 
    g_modelMatrix_mesh[1] = glm::rotate(glm::radians(rotateAngle), glm::vec3(0.0f, 1.0f, 0.0f)) 
      * glm::translate(glm::vec3(0.4f, 0.3f, 0.0f)) * glm::scale(glm::vec3(0.2f, 0.2f, 0.2f)); 
    g_modelMatrix_mesh[2] = glm::translate(g_lightProperties.direction) 
      * glm::translate(glm::vec3(0.0f, 2.0f, 0.0f)) * glm::scale(glm::vec3(0.2f, 0.2f, 0.2f)); 

    // update spotlight 
    g_lightProperties.ambient = glm::vec4(g_spotlight_ambient[0], g_spotlight_ambient[1], g_spotlight_ambient[2], 1.0f); 
    g_lightProperties.diffuse = glm::vec4(g_spotlight_diffuse[0], g_spotlight_diffuse[1], g_spotlight_diffuse[2], 1.0f); 
    g_lightProperties.specular = glm::vec4(g_spotlight_specular[0], g_spotlight_specular[1], g_spotlight_specular[2], 1.0f); 

    // Disco mode 
    if (g_disco_mode) 
    { 
     bool movement_increase = true; 
     bool color_increase = true; 
     float floor = -0.1f; 
     float ceiling = 1.0f; 
     float increment = 0.01f; 

     // Movement of spotlight 
     if (movement_increase == true && g_lightProperties.direction[0] <= ceiling) 
     { 
      g_lightProperties.direction[0] += increment; 

      if (g_lightProperties.direction[0] >= ceiling) { movement_increase = false; } 
     } 

     if (movement_increase == false && g_lightProperties.direction[0] >= floor) 
     { 
      g_lightProperties.direction[0] -= increment; 

      if (g_lightProperties.direction[0] <= floor) { movement_increase = true; } 
     } 

     // Changing of color 
     g_spotlight_ambient[0] += 0.01f; 

     if (color_increase == true && g_spotlight_ambient[0] <= ceiling) 
     { 
      g_spotlight_ambient[0] += increment; 

      if (g_spotlight_ambient[0] >= ceiling) { color_increase = false; } 
     } 

     if (color_increase == false && g_spotlight_ambient[0] >= floor) 
     { 
      g_spotlight_ambient[0] -= increment; 

      if (g_spotlight_ambient[0] <= floor) { color_increase = true; } 
     } 
    } 

} 

// function used to render the scene 
static void render_scene() 
{ 
    glBindVertexArray(g_VAO[0]);  // make VAO active 

// Material Properties - Planes 
    glUniform4fv(g_materialAmbientIndex, 1, &g_materialProperties.ambient[0]); 
    glUniform4fv(g_materialDiffuseIndex, 1, &g_materialProperties.diffuse[0]); 
    glUniform4fv(g_materialSpecularIndex, 1, &g_materialProperties.specular[0]); 

    glUniform4fv(g_lightPositionIndex, 1, &g_lightProperties.position[0]); 
    glUniform4fv(g_lightAmbientIndex, 1, &g_lightProperties.ambient[0]); 
    glUniform4fv(g_lightDiffuseIndex, 1, &g_lightProperties.diffuse[0]); 
    glUniform4fv(g_lightSpecularIndex, 1, &g_lightProperties.specular[0]); 
    glUniform1fv(g_lightShininessIndex, 1, &g_lightProperties.shininess); 
    glUniform3fv(g_lightAttenuationIndex, 1, &g_lightProperties.attenuation[0]); 
    glUniform1fv(g_lightCutoffAngleIndex, 1, &g_lightProperties.cutoffAngle); 
    glUniform3fv(g_lightDirectionIndex, 1, &g_lightProperties.direction[0]); 

    ... 
} 

int main(void) 
{ 
    TwBar *TweakBar;   // pointer to a tweak bar 

    ... 

    // initialise AntTweakBar 
    TwInit(TW_OPENGL_CORE, NULL); 

    // give tweak bar the size of graphics window 
    TwWindowSize(g_windowWidth, g_windowHeight); 
    TwDefine(" TW_HELP visible=false "); // disable help menu 
    TwDefine(" GLOBAL fontsize=3 ");  // set large font size 

    // create a tweak bar 
    TweakBar = TwNewBar("Main"); 
    TwDefine(" Main label='Controls' refresh=0.02 text=light size='220 600' "); 

    // create display entries 
    TwAddVarRW(TweakBar, "Wireframe", TW_TYPE_BOOLCPP, &g_wireFrame, " group='Display' "); 

    // display a separator 
    TwAddSeparator(TweakBar, NULL, NULL); 

    // create spotlight entries 
    TwAddVarRW(TweakBar, "Cutoff", TW_TYPE_FLOAT, &g_lightProperties.cutoffAngle, " group='Spotlight' min=-180.0 max=180.0 step=1.0 "); 
    TwAddVarRW(TweakBar, "Direction: x", TW_TYPE_FLOAT, &g_lightProperties.direction[0], " group='Spotlight' min=-1.0 max=1.0 step=0.1"); 
    TwAddVarRW(TweakBar, "Direction: y", TW_TYPE_FLOAT, &g_lightProperties.direction[1], " group='Spotlight' min=-1.0 max=1.0 step=0.1"); 
    TwAddVarRW(TweakBar, "Direction: z", TW_TYPE_FLOAT, &g_lightProperties.direction[2], " group='Spotlight' min=-1.0 max=1.0 step=0.1"); 
    // create transformation entries 
    TwAddVarRW(TweakBar, "A Red", TW_TYPE_FLOAT, &g_spotlight_ambient[0], " group='Ambient' min=-1.0 max=1.0 step=0.01"); 
    TwAddVarRW(TweakBar, "A Green", TW_TYPE_FLOAT, &g_spotlight_ambient[1], " group='Ambient' min=-1.0 max=1.0 step=0.01"); 
    TwAddVarRW(TweakBar, "A Blue", TW_TYPE_FLOAT, &g_spotlight_ambient[2], " group='Ambient' min=-1.0 max=1.0 step=0.01"); 

    TwAddVarRW(TweakBar, "D Red", TW_TYPE_FLOAT, &g_spotlight_diffuse[0], " group='Diffuse' min=-1.0 max=1.0 step=0.01"); 
    TwAddVarRW(TweakBar, "D Green", TW_TYPE_FLOAT, &g_spotlight_diffuse[1], " group='Diffuse' min=-1.0 max=1.0 step=0.01"); 
    TwAddVarRW(TweakBar, "D Blue", TW_TYPE_FLOAT, &g_spotlight_diffuse[2], " group='Diffuse' min=-1.0 max=1.0 step=0.01"); 

    TwAddVarRW(TweakBar, "S Red", TW_TYPE_FLOAT, &g_spotlight_specular[0], " group='Specular' min=-1.0 max=1.0 step=0.01"); 
    TwAddVarRW(TweakBar, "S Green", TW_TYPE_FLOAT, &g_spotlight_specular[1], " group='Specular' min=-1.0 max=1.0 step=0.01"); 
    TwAddVarRW(TweakBar, "S Blue", TW_TYPE_FLOAT, &g_spotlight_specular[2], " group='Specular' min=-1.0 max=1.0 step=0.01"); 

    TwAddVarRW(TweakBar, "Light", TW_TYPE_BOOLCPP, &g_switchOn, " group='Toggle ON/OFF' "); 
    TwAddVarRW(TweakBar, "Disco", TW_TYPE_BOOLCPP, &g_disco_mode, " group='Toggle ON/OFF' "); 

    // initialise rendering states 
    init(window); 

    // the rendering loop 
    while (!glfwWindowShouldClose(window)) 
    { 
     g_camera.update(window); // update camera 

     if (g_wireFrame) 
      glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); 

     update_scene();  // update the scene 
     render_scene();  // render the scene 

     glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); 

     TwDraw();   // draw tweak bar(s) 

     glfwSwapBuffers(window); // swap buffers 
     glfwPollEvents();   // poll for events 
    } 

    ... 
} 
+1

Si pas le second cas être '&& g_lightProperties.direction [0]> = floor'? Sinon, cela ne sera appelé qu'une seule fois. – BDL

+0

@BDL merci de le signaler. Je l'ai changé dans mon code mais il a toujours le même problème – Zolly

+0

Dans le imbriqué si: 'movement_increase == false;' devrait être 'movement_increase = false;'. Veuillez déboguer votre code vous-même. Nous ne sommes pas ici pour faire votre travail pour vous. Imprimez ce qui se passe ou définissez des points d'arrêt et vérifiez. – BDL

Répondre

0

Vous devez vérifier si le plafond ou le plancher est atteint et vous devez changer la direction

Votre code devrait ressembler en quelque sorte comme ceci:

if (movement_increase) 
{ 
    // if less than ceiling keep increasing 
    movement_increase = g_lightProperties.direction[0] < ceiling; 
} 
else 
{ 
    // if less or equal floor change to increasing 
    movement_increase = g_lightProperties.direction[0] <= floor; 
} 
g_lightProperties.direction[0] += movement_increase ? increment : -increment; 

if (color_increase) 
    color_increase = g_spotlight_ambient[0] < 1.0; 
else 
    color_increase = g_spotlight_ambient[0] <= 0.0; 
g_spotlight_ambient[0] += color_increase ? increment : -increment; 

À part cela, les variables movement_increase et color_increase sont des variables locales, elles seront donc initialisées de manière continue. Soit vous utilisez varibales global ou vous les delcare static:

static bool movement_increase = true; 
static bool color_increase = true; 
+0

merci rabbid, je l'ai essayé mais il donne le même résultat qu'avant – Zolly

+0

@Zolly j'ai étendu ma réponse. – Rabbid76

+0

merci qui a fonctionné! – Zolly