2017-05-17 11 views
0

Details: Dieser Shader zeichnet einen Orbitpfad eines Planeten um einen Stern. Meine Absicht ist es, die Farbe des Weges zu dimmen, wenn er sich von der OpenGL-Kamera entfernt, indem man die gleichförmigen Schwimmer "nahe" und "weit" benutzt, um die Farbhelligkeit zu berechnen. Wenn ich versuche, die uniformen Float-Variablen zu verwenden, funktioniert der Shader überhaupt nicht. Ich habe keine Ahnung, was falsch sein könnte. (Ich bin neu bei OpenGL und C++).Die Uniform Floats in diesem Vertex-Shader funktionieren nicht

Vertex-Shader (Works, wenn nicht einheitlich float Variablen)

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

Fragment-Shader (Works, wenn nicht einheitlich float Variablen)

#version 450 

in vec3 colour; 
out vec4 frag_colour; 

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

C++ Code Planeten umkreisen Weg zum Zeichnen (Arbeiten mit Ausnahme für 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); 
} 

C++ - Code zum Erstellen des Orbitpfads von pla net für Vertex-Shader (Arbeits)

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

C++ Code für Shader-Initialisierung (Arbeits)

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

C++ Code für nächsten und entferntesten Punkt der Umlaufbahn im 3D-Raum (Arbeits)

finden
/// 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 
} 

Antwort

0

Setzen Sie nicht far (und near) auf 0 in glUniform1f (sh_orbit.far_location, 0); Ausdruck und bekommen Division durch Null?

+0

Ich habe nicht Null-Zahlen, aber immer noch nicht funktioniert. Guter Fang aber. Das Programm benutzt vier andere Shader, also werde ich ihnen uniforme Floats hinzufügen und sehen, ob das gleiche Problem auftritt. –

+0

Auch Ihr Code enthält keine Fehlerbehandlung. Sie sollten 'glGetError' nach jedem anderen Aufruf aufrufen und das Ergebnis überprüfen. – VTT

+0

Eine Fehlerüberprüfung hinzugefügt. Scheint aus dieser Codezeile zu kommen. mat4 m = Identität_mat4(); mat4 m2; m2 = übersetzen (m, sun.display_pos); glUniformMatrix4fv (sh_orbit.matrix_mat_location, 1, GL_FALSE, m2.m); –