2017-05-17 2 views
0

Détails: Ce shader trace un trajet orbital d'une planète autour d'une étoile. Mon intention est d'atténuer la couleur du chemin quand il s'éloigne de la caméra ouverte en utilisant les flotteurs uniformes "près" et "loin" pour aider à calculer la luminosité de la couleur. Lorsque j'essaie d'utiliser les variables float uniformes, le shader ne fonctionne pas du tout. Je n'ai aucune idée de ce qui pourrait être faux. (Je suis nouveau à OpenGL et C++).Les flottants uniformes dans ce vertex shader ne fonctionnent pas

shaders Vertex (Works sinon en utilisant des variables de flotteur uniformes)

#version 450 

layout(location=0) in vec3 vertex_position; 

uniform mat4 proj, view; //view and projection matrix 
uniform mat4 matrix;  // model matrix 

uniform float near; //closest orbit distance 
uniform float far; //farthest orbit distance 
uniform vec3 dist_orbit_center; 
out vec3 colour; 

void main() 
{ 
    vec3 dist_vector = dist_orbit_center + vertex_position; 
    float dist = length(dist_vector); 

    //Trying out some debugging. Ignoring dist for now 
    //float ratio = near/far; // Not working! 
    float ratio = 0.25/0.5; // Working! 

    colour = vec3(0.0, 1.0, 0.1) * ratio; 

    gl_Position = proj * view * matrix * vec4(vertex_position, 1.0); 
} 

de shader Fragment (Works sinon en utilisant des variables de flotteur uniformes)

#version 450 

in vec3 colour; 
out vec4 frag_colour; 

void main() 
{ 
    frag_colour=vec4 (colour, 1.0); 
} 

code C++ pour dessiner chemin d'orbite des satellites (Travailler à l'exception pour glUniform1f?)

if ((orb.flag)) 
{ 
    double near; 
    double far; 
    // get nearest and farthest point of orbit 
    distance_to_orbit(near, far, cam.pos, sun.pos, plan[orb.body].orbit_radius, plan[orb.body].orbit_axis, Debug); 
    GLfloat near_display = (float) (near/DISPLAY_FACTOR); 
    GLfloat far_display = (float) (far/DISPLAY_FACTOR); 

    glUseProgram(sh_orbit.program); 
    glBindVertexArray(sh_orbit.vao); 
    glUniformMatrix4fv (sh_orbit.view_mat_location, 1, GL_FALSE, cam.view_mat.m); 
    mat4 m = identity_mat4(); 
    mat4 m2; 
    m2 = translate(m, sun.display_pos); 
    glUniformMatrix4fv (sh_orbit.matrix_mat_location, 1, GL_FALSE, m2.m); 
    // For debugging. Not working. 
    near_display = 0.25; 
    glUniform1f(sh_orbit.near_location, near_display); 
    // For debugging. Not working. 
    far_display = 0.5; 
    glUniform1f(sh_orbit.far_location, far_display); 
    glUniform3fv(sh_orbit.dist_orbit_center_location, 1, sun.display_pos.v); 

    glDrawArrays(GL_LINE_STRIP, 0, 361); 
    glBindVertexArray(0); 
} 

Code C++ pour créer un chemin d'orbit de pla net pour shader de sommet (de travail)

void Setup_planet_orbit(int index) 
{ 
    orb.flag = 1; 
    orb.body = index; 
    vec3d axis = plan[orb.body].orbit_axis; 
    vec3d globe = plan[orb.body].origonal_pos; 

    for (int lp=0; lp<361; lp++) 
    { 
     globe = Rotate_point((double) lp * TO_RADIANS, axis, 
     plan[orb.body].origonal_pos); 
     sh_orbit.points[lp*3] = (float) (globe.v[0]/DISPLAY_FACTOR); 
     sh_orbit.points[lp*3+1] = (float) (globe.v[1]/DISPLAY_FACTOR); 
     sh_orbit.points[lp*3+2] = (float) (globe.v[2]/DISPLAY_FACTOR); 
    } 
    glUseProgram(sh_orbit.program); 
    glBindVertexArray(sh_orbit.vao); 
    glBindBuffer(GL_ARRAY_BUFFER, sh_orbit.points_vbo); 
    glBufferSubData(GL_ARRAY_BUFFER, 0, 361*3*sizeof(GLfloat), 
    sh_orbit.points); 
    glEnableVertexAttribArray(0); 
    glBindVertexArray(0); 
} 

code C++ pour initialiser shaders (travail)

bool Get_orbit_shader() 
{ 
    float*& point = sh_orbit.points; 
    point = (float*)malloc (3 * 361 * sizeof (float)); 

    string vertshader=readFile("orbit.vert.txt"); 
    const char* vertex_shader = vertshader.c_str(); 

    string fragshader=readFile("orbit.frag.txt"); 
    const char* fragment_shader = fragshader.c_str(); 
    // Compile vertex shader program 
    GLuint vs = glCreateShader(GL_VERTEX_SHADER); 
    glShaderSource(vs, 1, &vertex_shader, NULL); 
    glCompileShader(vs); 
    int params=-1; 
    glGetShaderiv (vs, GL_COMPILE_STATUS, &params); 
    if (GL_TRUE != params) 
    { 
     fprintf(stderr, "ERROR: GL shader index %i did not compile\n", vs); 
     print_shader_info_log(vs); 
     return false; 
    } 
    // Compile fragment shader program 
    GLuint fs = glCreateShader(GL_FRAGMENT_SHADER); 
    glShaderSource(fs, 1, &fragment_shader, NULL); 
    glCompileShader(fs); 
    glGetShaderiv (fs, GL_COMPILE_STATUS, &params); 
    if (GL_TRUE != params) 
    { 
     fprintf(stderr, "ERROR: GL shader index %i did not compile\n", fs); 
     print_shader_info_log(fs); 
     return false; 
    } 
    // Link vertex and shader program 
    sh_orbit.program = glCreateProgram(); 
    glAttachShader(sh_orbit.program, fs); 
    glAttachShader(sh_orbit.program, vs); 
    glLinkProgram(sh_orbit.program); 
    //Check if linked correctly. 
    glGetProgramiv(sh_orbit.program, GL_LINK_STATUS, &params); 
    if (GL_TRUE !=params) 
    { 
     fprintf (stderr, "ERROR: could not link shader programme GL index 
     %u\n", 
     sh_orbit.program); 
     print_programme_info_log(sh_orbit.program); 
     return false; 
    } 
    print_all(sh_orbit.program); 
    mat4 matrix = identity_mat4(); 

    glUseProgram(sh_orbit.program); 
    glGenVertexArrays(1, &sh_orbit.vao); 
    glBindVertexArray(sh_orbit.vao); 

    sh_orbit.view_mat_location = glGetUniformLocation(sh_orbit.program, 
    "view"); 
    glUniformMatrix4fv (sh_orbit.view_mat_location, 1, GL_FALSE, 
    cam.view_mat.m); 

    sh_orbit.proj_mat_location = glGetUniformLocation (sh_orbit.program, 
    "proj"); 
    glUniformMatrix4fv (sh_orbit.proj_mat_location, 1, GL_FALSE, 
    cam.proj_mat.m); 

    sh_orbit.proj_mat_location = glGetUniformLocation (sh_orbit.program, 
    "matrix"); 
    glUniformMatrix4fv (sh_orbit.matrix_mat_location, 1, GL_FALSE, matrix.m); 

    sh_orbit.near_location = glGetUniformLocation(sh_orbit.program, "near"); 
    glUniform1f (sh_orbit.near_location, 0); 

    sh_orbit.far_location = glGetUniformLocation (sh_orbit.program, "far"); 
    glUniform1f (sh_orbit.far_location, 0); 

    vec3 load; 
    sh_orbit.dist_orbit_center_location = glGetUniformLocation 
    (sh_orbit.program, "dist_orbit_center"); 
    glUniform3f (sh_orbit.dist_orbit_center_location, load.v[0], load.v[1], 
    load.v[2]); 

    glGenBuffers(1, &sh_orbit.points_vbo); 
    glBindBuffer(GL_ARRAY_BUFFER, sh_orbit.points_vbo); 
    glBufferData(GL_ARRAY_BUFFER, 361*3*sizeof(GLfloat), sh_orbit.points, 
    GL_DYNAMIC_DRAW); 
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL); 

    glEnableVertexAttribArray(0); 
    glBindVertexArray(0); 

    return true; 
} 

code C++ pour trouver le point de l'orbite le plus proche et le plus éloigné dans l'espace 3D (de travail)

/// Find closest and farthest distance to a 3d disk 
/// projection of P-C onto plane is Q-C = P-C - Dot(N,P-C)*N 
void distance_to_orbit(double &near, double &far, vec3d point, vec3d center, 
double radius, vec3d normal, FILE* Debug) 
{ 
    vec3d PmC; 
    vec3d QmC; 
    vec3d diff; 
    double lengthQmC; 
    double sqr_dist; 
    double dist; 
    double temp; 
    vec3d Closest; 
    vec3d Farthest; 
    vec3d vec_temp; 

    PmC = point - center; 
    double Dot = dot_d(normal, PmC); 
    vec_temp = normal * Dot; //Distance to plane that circle is on. 
    QmC = PmC - vec_temp; 
    lengthQmC = length(QmC); 

    vec_temp = QmC * (radius/lengthQmC); 
    Closest = center + vec_temp; 

    diff = point - Closest; 
    sqr_dist = dot_d(diff, diff); 
    near = sqrt(sqr_dist);  //distance to nearest point of 3d disc 

    vec_temp = center - Closest; 
    vec_temp *= 2.0f; 
    diff = Closest + vec_temp; 
    far = get_distance_d(point, diff); //distance to farthest point of 3d 
    disc 
} 

Répondre

0

Ne réglez-vous pas far (et near) sur 0 en glUniform1f (sh_orbit.far_location, 0); et en divisant par zéro?

+0

Je mets des nombres non zéro mais ne fonctionne toujours pas. Bonne prise cependant. Le programme utilise quatre autres shaders donc je vais leur ajouter des flotteurs uniformes et voir si le même problème se produit. –

+0

Votre code ne contient pas non plus de traitement des erreurs. vous devriez appeler 'glGetError' après tous les autres appels gl et vérifier le résultat retourné. – VTT

+0

Ajouté un contrôle d'erreur. Apparaît provenir de cette ligne de code. mat4 m = identité_mat4(); mat4 m2; m2 = translate (m, sun.display_pos); glUniformMatrix4fv (sh_orbit.matrix_mat_location, 1, GL_FALSE, m2.m); –