代码之家  ›  专栏  ›  技术社区  ›  Zolly

OpenGL对象的颜色和移动未正确交替

  •  0
  • Zolly  · 技术社区  · 8 年前

    enter image description here

    我想制作一个“disco”模式,使球体沿x轴左右移动。同时在红色和蓝色之间交替。

    g_disco_mode 是选择模式后为真的变量。

    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; }
            }   
        }
    }
    

    ceiling 然后向左移动,直到碰到 floor g_lightProperties.direction . 颜色的变化也以类似的方式工作。但是,当我运行程序时,球体会向右移动,直到碰到 天花板

    我的程序

    // 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 回复  |  直到 8 年前
        1
  •  0
  •   Rabbid76    8 年前

    或者 地板

    您的代码应该看起来像这样:

    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;
    

    除此之外,变量 movement_increase color_increase static :

     static bool movement_increase = true;
     static bool color_increase = true;