示例#1
0
/**
  init will take a vertex shader file and fragment shader file, and then attempt to create a valid
  shader program from these. It will also check for any shader compilation issues along the way.
  */
void Shader::init(const char *vsFile, const char *fsFile) {
    if (inited) // If we have already initialized the shader
        return;

    inited = true; // Mark that we have initialized the shader

    shader_vp = glCreateShader(GL_VERTEX_SHADER); // Create a vertex shader
    shader_fp = glCreateShader(GL_FRAGMENT_SHADER); // Create a fragment shader

    std::string vsText = text_file_read(vsFile); // Read in the vertex shader
    std::string fsText = text_file_read(fsFile); // Read in the fragment shader

    const char *vertexText = vsText.c_str();
    const char *fragmentText = fsText.c_str();

    if (vertexText == NULL) {
        std::cout << "vertex shader shader file not found." << std::endl; // Output the error
        return;
    }

    if (fragmentText == NULL) {
        std::cout << "fragment shader file not found." << std::endl; // Output the error
        return;
    }

    glShaderSource(shader_vp, 1, &vertexText, 0); // Set the source for the vertex shader to the loaded text
    glCompileShader(shader_vp); // Compile the vertex shader
    validate_shader(shader_vp, vsFile); // Validate the vertex shader

    glShaderSource(shader_fp, 1, &fragmentText, 0); // Set the source for the fragment shader to the loaded text
    glCompileShader(shader_fp); // Compile the fragment shader
    validate_shader(shader_fp, fsFile); // Validate the fragment shader

    shader_id = glCreateProgram(); // Create a GLSL program
    glAttachShader(shader_id, shader_vp); // Attach a vertex shader to the program
    glAttachShader(shader_id, shader_fp); // Attach the fragment shader to the program

    glBindAttribLocation(shader_id, 0, "in_Position"); // Bind a constant attribute location for positions of vertices
    glBindAttribLocation(shader_id, 1, "in_Color"); // Bind another constant attribute location, this time for color

    glLinkProgram(shader_id); // Link the vertex and fragment shaders in the program
    validate_program(shader_id); // Validate the shader program
}
示例#2
0
void load_config(Config *c, char *filename)
{
    assert(c != NULL);
    assert(filename != NULL);

    int ini_size;
    char *ini_data = text_file_read(filename, &ini_size);
    // TODO: test data was read in.

    char buffer[MAX_LINE_LEN];
    enum ConfigSections current_section = UNKNOWN_SECTION;
    char *key;
    char *value;
    while (get_next_line(ini_data, ini_size, buffer, MAX_LINE_LEN) == TRUE) {
        switch(buffer[0]) {
        case COMMENT_TOKEN:
            break; // Ignore this.
        case EMPTY_LINE_TOKEN:
            break; // Ignore this.
        case SPACE_TOKEN:
            break; // Ignore this.
        case SECTION_START_TOKEN:
            current_section = UNKNOWN_SECTION;
            value = strtok(&buffer[1], "]");
            assert(value != NULL);

            if (strncmp(value, "app", sizeof("app")) == 0) {
                current_section = APP_SECTION;
            }
            if (strncmp(value, "object", sizeof("object")) == 0) {
                current_section = OBJECT_SECTION;
            }
            if (strncmp(value, "textures", sizeof("textures")) == 0) {
                current_section = TEXTURES_SECTION;
            }
            if (strncmp(value, "vert_shader", sizeof("vert_shader")) == 0) {
                current_section = VERT_SECTION;
            }
            if (strncmp(value, "frag_shader", sizeof("frag_shader")) == 0) {
                current_section = FRAG_SECTION;
            }

            break;
        default:
            if (current_section != APP_SECTION &&
                    current_section != OBJECT_SECTION &&
                    current_section != TEXTURES_SECTION &&
                    current_section != VERT_SECTION &&
                    current_section != FRAG_SECTION) {
                continue;
            }

            key = strtok(&buffer[0], "=");
            assert(key != NULL);

            value = strtok(NULL, "\0");
            assert(value != NULL);

            if (current_section == APP_SECTION) {
                if (strncmp(key, "object_file", sizeof("object_file")) == 0) {
                    strncpy(c->app.object_filename, value, MAX_FILENAME_LEN);
                }
            }

            if (current_section == OBJECT_SECTION) {
                if (strncmp(key, "vert_shader_file", sizeof("vert_shader_file")) == 0) {
                    strncpy(c->object.vert_shader_filename, value, MAX_FILENAME_LEN);
                }
                else if (strncmp(key, "frag_shader_file", sizeof("frag_shader_file")) == 0) {
                    strncpy(c->object.frag_shader_filename, value, MAX_FILENAME_LEN);
                }
            }

            if (current_section == TEXTURES_SECTION) {
                assert(c->texture_count + 1 != MAX_TEXTURE_COUNT);
                TextureConfig *t;
                t = &(c->textures[c->texture_count]);
                strncpy(t->name, key, MAX_LINE_LEN);
                strncpy(t->filename, value, MAX_LINE_LEN);
                c->texture_count++;
            }

            if (current_section == VERT_SECTION || current_section == FRAG_SECTION) {
                char *type;
                enum UniformDataTypes etype;
                char *name;
                type = strtok(key, " ");
                name = strtok(NULL, "=");
                int i = 0;
                char *p;
                float x = 0.0;
                float y = 0.0;
                float z = 0.0;
                float w = 0.0;
                etype = UNIFORM_UNKNOWN;

                if (strncmp(type, "int", sizeof("int")) == 0) {
                    etype = UNIFORM_INT;
                    i = atoi(value);
                }

                if (strncmp(type, "float", sizeof("float")) == 0) {
                    etype = UNIFORM_FLOAT;
                    x = atof(value);
                }
                if (strncmp(type, "vec2", sizeof("vec2")) == 0) {
                    etype = UNIFORM_VEC2;
                    p = strtok(value, ",");
                    x = atof(p);
                    p = strtok(NULL, "\0");
                    y = atof(p);;
                }
                if (strncmp(type, "vec3", sizeof("vec3")) == 0) {
                    etype = UNIFORM_VEC3;
                    p = strtok(value, ",");
                    x = atof(p);
                    p = strtok(NULL, ",");
                    y = atof(p);;
                    p = strtok(NULL, "\0");
                    z = atof(p);;
                }

                if (strncmp(type, "vec4", sizeof("vec4")) == 0) {
                    etype = UNIFORM_VEC4;
                    p = strtok(value, ",");
                    x = atof(p);
                    p = strtok(NULL, ",");
                    y = atof(p);;
                    p = strtok(NULL, ",");
                    z = atof(p);;
                    p = strtok(NULL, "\0");
                    w = atof(p);;
                }

                UniformConfig *uconfig;
                if (current_section == VERT_SECTION) {
                    assert(c->vert_uniform_count + 1 != MAX_UNIFORM_COUNT);
                    uconfig = &(c->vert_uniforms[c->vert_uniform_count]);
                    c->vert_uniform_count++;
                } else {
                    assert(c->frag_uniform_count + 1 != MAX_UNIFORM_COUNT);
                    uconfig = &(c->frag_uniforms[c->frag_uniform_count]);
                    c->frag_uniform_count++;
                }

                uconfig->type = etype;
                strncpy(uconfig->name, name, MAX_LINE_LEN);
                uconfig->i = i;
                uconfig->x = x;
                uconfig->y = y;
                uconfig->z = z;
                uconfig->w = w;
            }
        }
    }
}
示例#3
0
void load_shader(Shader *s, char *vert_filename, char *frag_filename)
{
    assert(s != NULL);
    assert(vert_filename != NULL);
    assert(frag_filename != NULL);

    strncpy(s->vert_filename, (vert_filename), MAX_FILENAME_LEN);
    strncpy(s->frag_filename, (frag_filename), MAX_FILENAME_LEN);

    s->vert_program_id = glCreateShader(GL_VERTEX_SHADER);
    if (s->vert_program_id == 0) {
        set_error_msg(&s->status, "Could not create vert shader.");
        return;
    }

    s->frag_program_id = glCreateShader(GL_FRAGMENT_SHADER);
    if (s->frag_program_id == 0) {
        set_error_msg(&s->status, "Could not create frag shader.");
        return;
    }

    char *vs = NULL;
    int vs_size;
    vs = text_file_read(s->vert_filename, &vs_size);
    if (vs == NULL) {
        set_error_msg(&s->status, "Could not read vert shader '%s'.",
            s->vert_filename);
        return;
    }

    char *fs = NULL;
    int fs_size;
    fs = text_file_read(s->frag_filename, &fs_size);
    if (fs == NULL) {
        set_error_msg(&s->status, "Could not read frag shader '%s'.",
            s->frag_filename);
        return;
    }

    GLenum glerror;
    GLint result;
    const char * vv = vs;
    const char * ff = fs;

    glShaderSource(s->vert_program_id, 1, &vv, NULL);
    if ((glerror = glGetError()) != GL_NO_ERROR) {
        set_error_msg(&s->status, "Could set vert shader source. (%d)",
            glerror);
        return;
    }

    glShaderSource(s->frag_program_id, 1, &ff, NULL);
    if ((glerror = glGetError()) != GL_NO_ERROR) {
        set_error_msg(&s->status, "Could set frag shader source. (%d)",
            glerror);
        return;
    }

    glCompileShader(s->vert_program_id);
    glGetShaderiv(s->vert_program_id, GL_COMPILE_STATUS, &result);
    if (result != GL_TRUE) {
        set_error_msg(&s->status, "Could not compile vert shader.");
        return;
    }

    glCompileShader(s->frag_program_id);
    glGetShaderiv(s->frag_program_id, GL_COMPILE_STATUS, &result);
    if (result != GL_TRUE) {
        set_error_msg(&s->status, "Could not compile frag shader.");
        return;
    }

    free(vs); free(fs);

    print_shader_log(s->vert_program_id);
    print_shader_log(s->frag_program_id);

    s->program_id = glCreateProgram();
    if (s->program_id == 0) {
        set_error_msg(&s->status, "Could not create program.");
        return;
    }

    glAttachShader(s->program_id, s->vert_program_id);
    if ((glerror = glGetError()) != GL_NO_ERROR) {
        set_error_msg(&s->status, "Could not attach vert shader. (%d)",
            glerror);
        return;
    }

    glAttachShader(s->program_id, s->frag_program_id);
    if ((glerror = glGetError()) != GL_NO_ERROR) {
        set_error_msg(&s->status, "Could not attach frag shader. (%d)",
            glerror);
        return;
    }

    glBindFragDataLocation(s->program_id, 0, "FracColor");
    if ((glerror = glGetError()) != GL_NO_ERROR) {
        set_error_msg(&s->status, "Could not bind frag data location. (%d)",
            glerror);
        return;
    }

    glLinkProgram(s->program_id);
    glGetProgramiv(s->program_id, GL_LINK_STATUS, &result);
    if ((glerror = glGetError()) != GL_NO_ERROR || result == GL_FALSE) {
        set_error_msg(&s->status, "Could not bind frag data location. (%d,%d)",
            glerror, result);
        return;
    }

    print_program_log(s->program_id);

    s->vertex_loc = glGetAttribLocation(s->program_id, "MCvertex");
    s->normal_loc = glGetAttribLocation(s->program_id, "MCnormal");
    s->tangent_loc = glGetAttribLocation(s->program_id, "MCtangent");
    s->tex_coords_loc = glGetAttribLocation(s->program_id, "TexCoord0");

    s->proj_matrix_loc = glGetUniformLocation(s->program_id, "MVPMatrix");
    s->view_matrix_loc = glGetUniformLocation(s->program_id, "MVMatrix");
    s->rot_matrix_loc = glGetUniformLocation(s->program_id, "RotMatrix");
}