2017-08-05 3 views
0

Mon programme est un "système planète" en mouvement.Comment activer et désactiver mon cube OpenGL

enter image description here

Je veux obtenir la planète le plus (cube) à "disparaître" alternativement de transparent à complètement opaque. Je comprends que cela a à voir avec l'ajustement des valeurs alpha des sommets. Cependant, je ne suis pas familier avec le mélange et la transparence.

On m'a donné du code qui pourrait modifier les valeurs alpha d'un objet. Je l'ai intégré dans mon programme, mais maintenant mon programme se bloque. Quelqu'un peut-il me dire pourquoi il s'écrase et comment je peux changer mon code pour faire fondre la planète?

Voici le code que j'ajouté à mon programme

GLuint g_alphaIndex;   // for transparency of 4th planet 
float g_alpha = 0.5f;  // transparency of 4th planet 

static void init(GLFWwindow* window) 
{ 
    .... 
    glEnable(GL_BLEND); 
    glBlendEquationSeparate(GL_FUNC_ADD, GL_FUNC_ADD); 
    glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO); 
    ..... 
    ..... 
    g_alphaIndex = glGetUniformLocation(g_shaderProgramID, "uAlpha"); 
    ....  

} 

static void render_scene() 
{ 
    ...... 
    // Object 4 
    glUniform1fv(g_alphaIndex, 2, &g_alpha); 
    ...... 
} 


/* 
     In Fragment shader 
*/ 

uniform float uAlpha; 

void main() 
{ 
    // set output color 
    fColor = vec4(vColor, uAlpha); 
} 

Voici mon programme complet

#include <cstdio>  // for C++ i/o 
#include <iostream> 
#include <string> 
#include <cstddef> 
using namespace std; // to avoid having to use std:: 

#define GLEW_STATIC  // include GLEW as a static library 
#include <GLEW/glew.h> // include GLEW 
#include <GLFW/glfw3.h> // include GLFW (which includes the OpenGL header) 
#include <glm/glm.hpp> // include GLM (ideally should only use the GLM headers that are actually used) 
#include <glm/gtx/transform.hpp> 
using namespace glm; // to avoid having to use glm:: 

#include "shader.h" 
#include "camera.h" 

#define PI 3.14159265 
#define MAX_SLICES 50 
#define MIN_SLICES 8 
#define MAX_VERTICES (MAX_SLICES+2)*3 // a triangle fan should have a minimum of 3 vertices 
#define CIRCLE_RADIUS 3.0 
#define WINDOW_WIDTH 1000 
#define WINDOW_HEIGHT 1000 

// struct for vertex attributes 
struct Vertex 
{ 
    GLfloat position[3]; 
    GLfloat color[3]; 
}; 

// global variables 

GLfloat g_vertices_circle[MAX_VERTICES] = { 
    0.0f, 0.0f, 0.0f,  
    0.0f, 0.0f, 0.0f 
}; 

GLfloat g_colors_circle[MAX_VERTICES] = { 
    1.0f, 0.0f, 0.0f, 
    1.0f, 0.0f, 0.0f 
}; 

GLuint g_slices = MAX_SLICES; // number of circle slices 

Vertex g_vertices[] = { 
    // vertex 1 
    -0.5f, 0.5f, 0.5f, // position 
    1.0f, 0.0f, 1.0f, // colour 
    // vertex 2 
    -0.5f, -0.5f, 0.5f, // position 
    1.0f, 0.0f, 0.0f, // colour 
    // vertex 3 
    0.5f, 0.5f, 0.5f, // position 
    1.0f, 1.0f, 1.0f, // colour 
    // vertex 4 
    0.5f, -0.5f, 0.5f, // position 
    1.0f, 1.0f, 0.0f, // colour 
    // vertex 5 
    -0.5f, 0.5f, -0.5f, // position 
    0.0f, 0.0f, 1.0f, // colour 
    // vertex 6 
    -0.5f, -0.5f, -0.5f,// position 
    0.0f, 0.0f, 0.0f, // colour 
    // vertex 7 
    0.5f, 0.5f, -0.5f, // position 
    0.0f, 1.0f, 1.0f, // colour 
    // vertex 8 
    0.5f, -0.5f, -0.5f, // position 
    0.0f, 1.0f, 0.0f, // colour 
}; 

GLuint g_indices[] = { 
    0, 1, 2, // triangle 1 
    2, 1, 3, // triangle 2 
    4, 5, 0, // triangle 3 
    0, 5, 1, // ... 
    2, 3, 6, 
    6, 3, 7, 
    4, 0, 6, 
    6, 0, 2, 
    1, 5, 3, 
    3, 5, 7, 
    5, 4, 7, 
    7, 4, 6, // triangle 12 
}; 

GLuint g_IBO = 0;    // index buffer object identifier 
GLuint g_VBO[3];    // vertex buffer object identifier 
GLuint g_VAO[2];    // vertex array object identifier 
GLuint g_shaderProgramID = 0; // shader program identifier 
GLuint g_MVP_Index = 0;   // location in shader 
GLuint g_alphaIndex;   // for transparency of 4th planet 
glm::mat4 g_modelMatrix[5];  // planets object model matrices 
glm::mat4 g_modelMatrixCircle[5];// circle model matrices 
glm::mat4 g_modelMatrixSubPlanets[5];// object matrices for sub-planets (moon, disc etc) 
glm::mat4 g_viewMatrix;   // view matrix 
glm::mat4 g_projectionMatrix; // projection matrix 

Camera g_camera;   // camera 

float g_orbitSpeed[5] = { 0.3f, 0.5f, 0.4f, 0.2f, 0.1f };  // for speed of rotation around sun 
float g_rotationSpeed[5] = { 0.07f, 0.7f, 3.0f, 5.0f, 1.0f }; // for speed of rotation on own axis 
float g_scaleSize[5] = { 0.5f, 0.5f, 0.5f, 0.5f, 0.5f };  // for scaling the orbiting planets 
float g_axisOfRotation[5] = { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, }; // for offsetting the axis of rotation 
float g_alpha = 0.5f;  // transparency of 4th planet 
bool g_enableAnimation = true; 

void generate_circle() 
{ 
    float angle = PI * 2/static_cast<float>(g_slices); // used to generate x and y coordinates 
    float scale_factor = static_cast<float>(WINDOW_HEIGHT)/WINDOW_WIDTH; // scale to make it a circle instead of an elipse 
    int index = 0; // vertex index 

    g_vertices_circle[3] = CIRCLE_RADIUS * scale_factor; // set x coordinate of vertex 1 

    // generate vertex coordinates for triangle fan 
    for (int i = 2; i < g_slices + 2; i++) 
    { 
     // multiply by 3 because a vertex has x, y, z coordinates 
     index = i * 3; 

     g_vertices_circle[index] = CIRCLE_RADIUS * cos(angle) * scale_factor; 
     g_vertices_circle[index + 1] = CIRCLE_RADIUS * sin(angle); 
     g_vertices_circle[index + 2] = 0.0f; 

     //Color for edges. See stackoverflow 
     g_colors_circle[index] = 1.0f; 
     g_colors_circle[index + 1] = 0.0f; 
     g_colors_circle[index + 2] = 0.0f; 

     // update to next angle 
     angle += PI * 2/static_cast<float>(g_slices); 
    } 

    // Gets rid of line from middle of circle 
    g_vertices_circle[0] = g_vertices_circle[3]; 
    g_vertices_circle[1] = g_vertices_circle[4]; 
    g_vertices_circle[2] = g_vertices_circle[5]; 
} 

static void init(GLFWwindow* window) 
{ 
    glClearColor(0.0, 0.0, 0.0, 1.0); // set clear background colour 

    glEnable(GL_DEPTH_TEST); // enable depth buffer test 
    glEnable(GL_BLEND); 
    glBlendEquationSeparate(GL_FUNC_ADD, GL_FUNC_ADD); 
    glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO); 

    // create and compile our GLSL program from the shader files 
    g_shaderProgramID = loadShaders("MVP_VS.vert", "ColorFS.frag"); 

    // find the location of shader variables 
    GLuint positionIndex = glGetAttribLocation(g_shaderProgramID, "aPosition"); 
    GLuint colorIndex = glGetAttribLocation(g_shaderProgramID, "aColor"); 
    g_MVP_Index = glGetUniformLocation(g_shaderProgramID, "uModelViewProjectionMatrix"); 
    g_alphaIndex = glGetUniformLocation(g_shaderProgramID, "uAlpha"); 

    // initialise model matrix to the identity matrix 
    g_modelMatrix[0] = g_modelMatrix[1] = g_modelMatrix[2] = g_modelMatrix[3] = g_modelMatrix[4] = glm::mat4(1.0f); 
    g_modelMatrixCircle[0] = g_modelMatrixCircle[1] = g_modelMatrixCircle[2] = g_modelMatrixCircle[3] = g_modelMatrixCircle[4] = glm::mat4(1.0f); 
    g_modelMatrixSubPlanets[2] = g_modelMatrixSubPlanets[3] = glm::mat4(1.0f);; 

    // set camera's view matrix 
    g_camera.setViewMatrix(glm::vec3(0, 3, 14), glm::vec3(0, 0, 0), glm::vec3(0, 1, 0)); 

    int width, height; 
    glfwGetFramebufferSize(window, &width, &height); 
    float aspectRatio = static_cast<float>(width)/height; 

    // set camera's projection matrix 
    g_camera.setProjectionMatrix(glm::perspective(45.0f, aspectRatio, 0.1f, 100.0f)); 

    // initialise projection matrix 
    g_projectionMatrix = glm::perspective(45.0f, aspectRatio, 0.1f, 100.0f); 

    // generate identifier for VBO and copy data to GPU 
    glGenBuffers(1, &g_VBO[0]); 
    glBindBuffer(GL_ARRAY_BUFFER, g_VBO[0]); 
    glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertices), g_vertices, GL_STATIC_DRAW); 

    // generate identifier for IBO and copy data to GPU 
    glGenBuffers(1, &g_IBO); 
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_IBO); 
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(g_indices), g_indices, GL_STATIC_DRAW); 

    // generate identifiers for VAO 
    glGenVertexArrays(1, &g_VAO[0]); 

    // create VAO and specify VBO data 
    glBindVertexArray(g_VAO[0]); 
    glBindBuffer(GL_ARRAY_BUFFER, g_VBO[0]); 
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_IBO); 
    // interleaved attributes 
    glVertexAttribPointer(positionIndex, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), reinterpret_cast<void*>(offsetof(Vertex, position))); 
    glVertexAttribPointer(colorIndex, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), reinterpret_cast<void*>(offsetof(Vertex, color))); 

    glEnableVertexAttribArray(positionIndex); // enable vertex attributes 
    glEnableVertexAttribArray(colorIndex); 

    /*------------------------Circle----------------------*/ 

    // generate vertices of triangle fan 
    generate_circle(); 

    // create VBO and buffer the data 
    glGenBuffers(1, &g_VBO[1]); 
    glBindBuffer(GL_ARRAY_BUFFER, g_VBO[1]); 
    glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 3 * (g_slices + 2), g_vertices_circle, GL_STATIC_DRAW); 

    glGenBuffers(1, &g_VBO[2]); 
    glBindBuffer(GL_ARRAY_BUFFER, g_VBO[2]); 
    glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 3 * (g_slices + 2), g_colors_circle, GL_STATIC_DRAW); 

    // create VAO and specify VBO data 
    glGenVertexArrays(1, &g_VAO[1]); 
    glBindVertexArray(g_VAO[1]); 
    glBindBuffer(GL_ARRAY_BUFFER, g_VBO[1]); 
    glVertexAttribPointer(positionIndex, 3, GL_FLOAT, GL_FALSE, 0, 0); // specify the form of the data 
    glBindBuffer(GL_ARRAY_BUFFER, g_VBO[2]); 
    glVertexAttribPointer(colorIndex, 3, GL_FLOAT, GL_FALSE, 0, 0); // specify the form of the data 

    glEnableVertexAttribArray(positionIndex); // enable vertex attributes 
    glEnableVertexAttribArray(colorIndex); 

    /*----------------------------------------------------*/ 
} 

//Generates a random value between 0.1 and 0.9 
double generateRandomFloat(float min, float max) 
{ 
    return min + static_cast <float> (rand())/(static_cast <float> (RAND_MAX/(max - min))); 
} 

// function used to update the scene 
static void update_scene() 
{ 
    // static variables for rotation angles 
    static float orbitAngle[5] = { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, }; 
    static float rotationAngle[5] = { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }; 
    float scaleFactor = 0.05; 

    orbitAngle[0] += g_orbitSpeed[0] * scaleFactor; 
    orbitAngle[1] += g_orbitSpeed[1] * scaleFactor; 
    orbitAngle[2] += g_orbitSpeed[2] * scaleFactor; 
    orbitAngle[3] += g_orbitSpeed[3] * scaleFactor; 
    orbitAngle[4] += g_orbitSpeed[4] * scaleFactor; 

    // update rotation angles 
    rotationAngle[0] += g_rotationSpeed[0] * scaleFactor; 
    rotationAngle[1] += g_rotationSpeed[1] * scaleFactor; 
    rotationAngle[2] += g_rotationSpeed[2] * scaleFactor; 
    rotationAngle[3] += g_rotationSpeed[3] * scaleFactor; 
    rotationAngle[4] += g_rotationSpeed[4] * scaleFactor; 

    // update model matrix (planets) 
    g_modelMatrix[0] = glm::rotate(rotationAngle[0], glm::vec3(0.0f, 1.0f, 0.0f)); 

    g_modelMatrix[1] = glm::translate(glm::vec3(g_axisOfRotation[1], 0.0f, 0.0f)) //moves the axis of rotation along x-axis 
     * glm::rotate(orbitAngle[1], glm::vec3(0.0f, 1.0f, 0.0f)) 
     * glm::translate(glm::vec3(2.0f, 0.0f, 0.0f)) 
     * glm::rotate(rotationAngle[1], glm::vec3(0.0f, -1.0f, 0.0f))  //enables rotation on own axis. try comment 
     * glm::rotate(glm::radians(45.0f), glm::vec3(1.0f, 0.0f, 0.0f))  //rotates into a diamond shape 
     * glm::rotate(glm::radians(45.0f), glm::vec3(0.0f, 0.0f, 1.0f))  //rotates into a diamond shape 
     * glm::scale(glm::vec3(g_scaleSize[1], g_scaleSize[1], g_scaleSize[1])); 

    g_modelMatrix[2] = glm::translate(glm::vec3(g_axisOfRotation[2], 0.0f, 0.0f)) 
     * glm::rotate(orbitAngle[2], glm::vec3(0.0f, -1.0f, 0.0f)) 
     * glm::translate(glm::vec3(4.0f, 0.0f, 0.0f)) 
     * glm::rotate(rotationAngle[2], glm::vec3(0.0f, 1.0f, 0.0f)) 
     * glm::scale(glm::vec3(g_scaleSize[2], g_scaleSize[2], g_scaleSize[2])); 

    g_modelMatrix[3] = glm::translate(glm::vec3(g_axisOfRotation[3], 0.0f, 0.0f)) 
     * glm::rotate(orbitAngle[3], glm::vec3(0.0f, 1.0f, 0.0f)) 
     * glm::translate(glm::vec3(6.0f, 0.0f, 0.0f)) 
     * glm::rotate(rotationAngle[3], glm::vec3(0.0f, 1.0f, 0.0f)) 
     * glm::scale(glm::vec3(g_scaleSize[3], g_scaleSize[3], g_scaleSize[3])); 

    g_modelMatrix[4] = glm::translate(glm::vec3(g_axisOfRotation[4], 0.0f, 0.0f)) 
     * glm::rotate(orbitAngle[4], glm::vec3(0.0f, -1.0f, 0.0f)) // -y changes orbit to clock-wise 
     * glm::translate(glm::vec3(8.0f, 0.0f, 0.0f)) 
     * glm::rotate(rotationAngle[4], glm::vec3(0.0f, -1.0f, 0.0f)) 
     * glm::scale(glm::vec3(g_scaleSize[4], g_scaleSize[4], g_scaleSize[4])); 

    // update model matrix (orbit paths ie.circles) 
    g_modelMatrixCircle[1] = glm::translate(glm::vec3(g_axisOfRotation[1], 0.0f, 0.0f)) * glm::scale(glm::vec3(0.68f, 0.68f, 0.68f)) * glm::rotate(glm::radians(90.0f), glm::vec3(1.0f, 0.0f, 0.0f)); 
    g_modelMatrixCircle[2] = glm::translate(glm::vec3(g_axisOfRotation[2], 0.0f, 0.0f)) * glm::scale(glm::vec3(1.35f, 1.35f, 1.35f)) * glm::rotate(glm::radians(90.0f), glm::vec3(1.0f, 0.0f, 0.0f)); 
    g_modelMatrixCircle[3] = glm::translate(glm::vec3(g_axisOfRotation[3], 0.0f, 0.0f)) * glm::scale(glm::vec3(2.0f, 2.0f, 2.0f)) * glm::rotate(glm::radians(90.0f), glm::vec3(1.0f, 0.0f, 0.0f)); 
    g_modelMatrixCircle[4] = glm::translate(glm::vec3(g_axisOfRotation[4], 0.0f, 0.0f)) * glm::scale(glm::vec3(2.7f, 2.7f, 2.7f)) * glm::rotate(glm::radians(90.0f), glm::vec3(1.0f, 0.0f, 0.0f)); 

    // update model matrix (mini planets eg. moon) 
    g_modelMatrixSubPlanets[2] = glm::translate(glm::vec3(g_axisOfRotation[1], 0.0f, 0.0f)) 
     * glm::scale(glm::vec3(0.35f, 0.35f, 0.35f)) 
     * glm::rotate(glm::radians(90.0f), glm::vec3(1.0f, 0.0f, 0.0f)); 

    g_modelMatrixSubPlanets[3] = glm::translate(glm::vec3(g_axisOfRotation[3], 0.0f, 0.0f)) 
     * glm::rotate(orbitAngle[3], glm::vec3(0.0f, 1.0f, 0.0f)) 
     * glm::translate(glm::vec3(6.0f, 0.0f, 0.0f)) 
     * glm::rotate(rotationAngle[3], glm::vec3(0.0f, 1.0f, 0.0f)) 
     * glm::scale(glm::vec3(g_scaleSize[3], g_scaleSize[3], g_scaleSize[3])); 
} 

// function used to render the scene 
static void render_scene() 
{ 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // clear colour buffer and depth buffer 

    glUseProgram(g_shaderProgramID); // use the shaders associated with the shader program 

    glm::mat4 MVP = glm::mat4(1.0f); //ModelViewProjection matrix to be shared. Initialized to identity 

//Circle 1 
    MVP = g_camera.getProjectionMatrix() * g_camera.getViewMatrix() * g_modelMatrixCircle[1]; 
    glUniformMatrix4fv(g_MVP_Index, 1, GL_FALSE, &MVP[0][0]); 
    glBindVertexArray(g_VAO[1]);   // make VAO active 
    glDrawArrays(GL_LINE_LOOP, 0, g_slices + 2); // display the vertices based on the primitive type 

//Circle 2            
    MVP = g_camera.getProjectionMatrix() * g_camera.getViewMatrix() * g_modelMatrixCircle[2]; 
    glUniformMatrix4fv(g_MVP_Index, 1, GL_FALSE, &MVP[0][0]); 
    glDrawArrays(GL_LINE_LOOP, 0, g_slices + 2); // display the vertices based on the primitive type 

//Circle 3            
    MVP = g_camera.getProjectionMatrix() * g_camera.getViewMatrix() * g_modelMatrixCircle[3]; 
    glUniformMatrix4fv(g_MVP_Index, 1, GL_FALSE, &MVP[0][0]); 
    glDrawArrays(GL_LINE_LOOP, 0, g_slices + 2); // display the vertices based on the primitive type 

//Circle 4            
    MVP = g_camera.getProjectionMatrix() * g_camera.getViewMatrix() * g_modelMatrixCircle[4];; 
    glUniformMatrix4fv(g_MVP_Index, 1, GL_FALSE, &MVP[0][0]); 
    glDrawArrays(GL_LINE_LOOP, 0, g_slices + 2); // display the vertices based on the primitive type 

// Circle for Object 2 
    MVP = g_camera.getProjectionMatrix() * g_camera.getViewMatrix() * g_modelMatrix[2] * g_modelMatrixSubPlanets[2]; 
    glUniformMatrix4fv(g_MVP_Index, 1, GL_FALSE, &MVP[0][0]); 
    glDrawArrays(GL_TRIANGLE_FAN, 0, g_slices + 2); // display the vertices based on the primitive type 

    glBindVertexArray(g_VAO[0]);  // make VAO active 

// Object 1 
    MVP = g_camera.getProjectionMatrix() * g_camera.getViewMatrix() * g_modelMatrix[0]; 
    glUniformMatrix4fv(g_MVP_Index, 1, GL_FALSE, &MVP[0][0]); 
    glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, 0); // display the vertices based on their indices and primitive type 

// Object 2 
    MVP = g_camera.getProjectionMatrix() * g_camera.getViewMatrix() * g_modelMatrix[1]; 
    glUniformMatrix4fv(g_MVP_Index, 1, GL_FALSE, &MVP[0][0]); 
    glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, 0); // display the vertices based on their indices and primitive type 

// Object 3 
    MVP = g_camera.getProjectionMatrix() * g_camera.getViewMatrix() * g_modelMatrix[2]; 
    glUniformMatrix4fv(g_MVP_Index, 1, GL_FALSE, &MVP[0][0]); 
    glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, 0); // display the vertices based on their indices and primitive type 

// Object 4 
    MVP = g_camera.getProjectionMatrix() * g_camera.getViewMatrix() * g_modelMatrix[3]; 
    glUniformMatrix4fv(g_MVP_Index, 1, GL_FALSE, &MVP[0][0]); 
    glUniform1fv(g_alphaIndex, 2, &g_alpha); 
    glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, 0); // display the vertices based on their indices and primitive type 

// Object 5 
    MVP = g_camera.getProjectionMatrix() * g_camera.getViewMatrix() * g_modelMatrix[4]; 
    glUniformMatrix4fv(g_MVP_Index, 1, GL_FALSE, &MVP[0][0]); 
    glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, 0); // display the vertices based on their indices and primitive type 

// Moon for Object 3 
    MVP = g_camera.getProjectionMatrix() * g_camera.getViewMatrix() * g_modelMatrixSubPlanets[3] * g_modelMatrix[4]; 
    glUniformMatrix4fv(g_MVP_Index, 1, GL_FALSE, &MVP[0][0]); 
    glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, 0); // display the vertices based on their indices and primitive type 

    glFlush(); // flush the pipeline 
} 

static void cursor_position_callback(GLFWwindow* window, double xpos, double ypos) 
{ 
    // variables to store mouse cursor coordinates 
    static double previous_xpos = xpos; 
    static double previous_ypos = ypos; 
    double delta_x = xpos - previous_xpos; 
    double delta_y = ypos - previous_ypos; 

    // pass mouse movement to camera class 
    g_camera.updateYaw(delta_x); 
    g_camera.updatePitch(delta_y); 

    // update previous mouse coordinates 
    previous_xpos = xpos; 
    previous_ypos = ypos; 
} 

// key press or release callback function 
static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) 
{ 
    // quit if the ESCAPE key was press 
    if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) 
    { 
     // set flag to close the window 
     glfwSetWindowShouldClose(window, GL_TRUE); 
     return; 
    } 
    // toggle animation 
    else if (key == GLFW_KEY_P && action == GLFW_PRESS) { 
     static int count = 1; 

     if(count % 2 == 0) 
      g_enableAnimation = true; 
     else 
      g_enableAnimation = false; 

     count++; 
    } 
    // render in perspective view 
    else if (key == GLFW_KEY_1 && action == GLFW_PRESS) { 
     cout << "Perspective-View" << endl << endl; 
     // set camera's view matrix 
     g_camera.setViewMatrix(glm::vec3(0, 3, 14), glm::vec3(0, 0, 0), glm::vec3(0, 1, 0)); 
     render_scene(); 
    } 
    // render from top view 
    else if (key == GLFW_KEY_2 && action == GLFW_PRESS) { 
     cout << "Top-View" << endl << endl; 
     // set camera's view matrix 
     g_camera.setViewMatrix(glm::vec3(0, 15.0f, 0), glm::vec3(0, 0, 0), glm::vec3(0, 0, -1.0f)); 
     render_scene(); 
    } 
    // render from eye-level view 
    else if (key == GLFW_KEY_3 && action == GLFW_PRESS) { 
     cout << "Eye-level View" << endl << endl; 
     // set camera's view matrix 
     g_camera.setViewMatrix(glm::vec3(0, 0, 10), glm::vec3(0, 0, 0), glm::vec3(0, 1, 0)); 
     render_scene(); 
    } 
    // Randomize size, orbit speed, axis rotation speed of planets 
    else if (key == GLFW_KEY_R && action == GLFW_PRESS) { 

     // Randomize planet size 
     g_scaleSize[1] = generateRandomFloat(0.1, 0.75); 
     g_scaleSize[2] = generateRandomFloat(0.1, 0.75); 
     g_scaleSize[3] = generateRandomFloat(0.1, 0.75); 
     g_scaleSize[4] = generateRandomFloat(0.1, 0.75); 

     // Randomize speed of rotation (on planets own axis) 
     g_rotationSpeed[1] = generateRandomFloat(0.1, 2.0); 
     g_rotationSpeed[2] = generateRandomFloat(0.1, 2.0); 
     g_rotationSpeed[3] = generateRandomFloat(0.1, 2.0); 
     g_rotationSpeed[4] = generateRandomFloat(0.1, 2.0); 

     // Randomize speed of rotation around sun 
     g_orbitSpeed[1] = generateRandomFloat(0.1, 0.7); 
     g_orbitSpeed[2] = generateRandomFloat(0.1, 0.7); 
     g_orbitSpeed[3] = generateRandomFloat(0.1, 0.7); 
     g_orbitSpeed[4] = generateRandomFloat(0.1, 0.7); 

     // Randomize offset for axis of rotation 
     g_axisOfRotation[1] = generateRandomFloat(-0.5, 0.5); 
     g_axisOfRotation[2] = generateRandomFloat(-0.5, 0.5); 
     g_axisOfRotation[3] = generateRandomFloat(-0.5, 0.5); 
     g_axisOfRotation[4] = generateRandomFloat(-0.5, 0.5); 

     // Display info for each planet 
     cout << "PLANET 1 - \tSize: " << g_scaleSize[1] << "\tSpeed: " << g_rotationSpeed[1] 
      << "\tOrbit Speed: " << g_orbitSpeed[1] << "\tAxis offset: " << g_axisOfRotation[1] << endl; 
     cout << "PLANET 2 - \tSize: " << g_scaleSize[2] << "\tSpeed: " << g_rotationSpeed[2] 
      << "\tOrbit Speed: " << g_orbitSpeed[2] << "\tAxis offset: " << g_axisOfRotation[2] << endl; 
     cout << "PLANET 3 - \tSize: " << g_scaleSize[3] << "\tSpeed: " << g_rotationSpeed[3] 
      << "\tOrbit Speed: " << g_orbitSpeed[3] << "\tAxis offset: " << g_axisOfRotation[3] << endl; 
     cout << "PLANET 4 - \tSize: " << g_scaleSize[4] << "\tSpeed: " << g_rotationSpeed[4] 
      << "\tOrbit Speed: " << g_orbitSpeed[4] << "\tAxis offset: " << g_axisOfRotation[4] << endl; 
     cout << endl; 

     render_scene(); 
    } 
} 

// error callback function 
static void error_callback(int error, const char* description) 
{ 
    cerr << description << endl; // output error description 
} 

int main(void) 
{ 
    GLFWwindow* window = NULL; // pointer to a GLFW window handle 

    glfwSetErrorCallback(error_callback); // set error callback function 

    // initialise GLFW 
    if (!glfwInit()) 
    { 
     // if failed to initialise GLFW 
     exit(EXIT_FAILURE); 
    } 

    // minimum OpenGL version 3.3 
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); 
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); 

    // create a window and its OpenGL context 
    window = glfwCreateWindow(1500, 1000, "Assignment 2", NULL, NULL); 

    // if failed to create window 
    if (window == NULL) 
    { 
     glfwTerminate(); 
     exit(EXIT_FAILURE); 
    } 

    glfwMakeContextCurrent(window); // set window context as the current context 
    glfwSwapInterval(1);   // swap buffer interval 

    // initialise GLEW 
    if (glewInit() != GLEW_OK) 
    { 
     // if failed to initialise GLEW 
     cerr << "GLEW initialisation failed" << endl; 
     exit(EXIT_FAILURE); 
    } 

    // set key callback function 
    glfwSetKeyCallback(window, key_callback); 
    glfwSetCursorPosCallback(window, cursor_position_callback); 

    // use sticky mode to avoid missing state changes from polling 
    glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE); 

    // use mouse to move camera, hence use disable cursor mode 
    glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); 

    // initialise rendering states 
    init(window); 

    // variables for simple time management 
    float lastUpdateTime = glfwGetTime(); 
    float currentTime = lastUpdateTime; 

    // the rendering loop 
    while (!glfwWindowShouldClose(window)) 
    { 
     currentTime = glfwGetTime(); 

     g_camera.update(window); // update camera 

     // only update if more than 0.02 seconds since last update 
     if (currentTime - lastUpdateTime > 0.02) 
     { 
      if (g_enableAnimation) { update_scene(); }  // update the scene 
      render_scene();  // render the scene 

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

      lastUpdateTime = currentTime; // update last update time 
     } 
    } 

    // clean up 
    glDeleteProgram(g_shaderProgramID); 
    glDeleteBuffers(1, &g_IBO); 
    glDeleteBuffers(1, &g_VBO[0]); 
    glDeleteBuffers(1, &g_VBO[1]); 
    glDeleteVertexArrays(1, &g_VAO[0]); 
    glDeleteVertexArrays(1, &g_VAO[1]); 

    // close the window and terminate GLFW 
    glfwDestroyWindow(window); 
    glfwTerminate(); 

    exit(EXIT_SUCCESS); 
} 

Fragment Shader

#version 330 core 

// interpolated values from the vertex shaders 
in vec3 vColor; 

// uniform input data 
uniform float uAlpha; 

// output data 
out vec3 fColor; 

void main() 
{ 
    // set output color 
    fColor = vec4(vColor, uAlpha); 
} 

Vertex Shader

#version 330 core 

// input data (different for all executions of this shader) 
in vec3 aPosition; 
in vec3 aColor; 

// ModelViewProjection matrix 
uniform mat4 uModelViewProjectionMatrix; 

// output data (will be interpolated for each fragment) 
out vec3 vColor; 

void main() 
{ 
    // set vertex position 
    gl_Position = uModelViewProjectionMatrix * vec4(aPosition, 1.0); 

    // the color of each vertex will be interpolated 
    // to produce the color of each fragment 
    vColor = aColor; 
} 

Répondre

0

Dans le programme de vertex shaders que vous avez déclaré l'uniforme uAlpha avec le type float.

uniform float uAlpha; 

Vous lire correctement l'index de localisation uniforme de uAlpha:

g_alphaIndex = glGetUniformLocation(g_shaderProgramID, "uAlpha"); 

Votre erreur est lorsque vous spécifiez la valeur d'une variable uniforme:

glUniform1fv(g_alphaIndex, 2, &g_alpha); 

Note, la deuxième paramter de glUniform1fv est le nombre d'éléments.

Le OpenGL Reference page du Khronos Group dit clairement sur le 2ème paramètre count:

Pour le vecteur (glUniform*v) commandes, spécifie le nombre d'éléments qui doivent être modifiés. Cela doit être 1 si la variable uniforme ciblée n'est pas un tableau et 1 ou plus s'il s'agit d'un tableau.

Notez que vous essayez de régler le 1er et le 2ème élément d'un tableau uniforme avec le type de float, mais vous ne déclare une variable unique et uniforme de type float. Il s'agit d'un comportement indéfini pouvant provoquer un blocage.

Changer votre code en quelque sorte comme ça:

glUniform1fv(g_alphaIndex, 1, &g_alpha); 
1

Dans votre fragment shader, la couleur out est "vec3" tandis que vous l'asignez avec "vec4".

Il existe plusieurs façons de déboguer le code opengl et les shaders, ce qui pourrait vous aider.

0.after compilation ou reliant les shaders, vous pouvez obtenir compiler résultat ou résultat de liaison par glGetShaderInfoLog()

1.Utilisez glGetError() pour récupérer le code d'erreur, sorcière contient des informations d'erreur spécifique en cas d'erreur exists.Once vous appelez cette fonction, l'état d'erreur dans le contexte sera effacé.

2.out mis résultat intermédiaire dans shaders, pour voir s'il y a quelque chose de mal dans les calculs d'ombrage