Shaders Not Found in Xcode: OpenGL 2.0

Discussion in 'Mac Programming' started by Blakeasd, Apr 20, 2013.

  1. macrumors 6502a

    Joined:
    Dec 29, 2009
    #1
    Hello.

    I am learning OpenGL, so I am trying to draw a triangle onto the screen. Here is my code:

    Code:
    
    
    #include <iostream>
    #include <stdlib.h>
    #include <GL/glew.h>
    #include <GLUT/glut.h>
    
    GLuint program;
    GLint attribute_coord2d;
    
    char *file_read(const char * filename){
        FILE *input = fopen(filename, "rb");
        if (input == NULL) return NULL;
        
        if (fseek(input, 0 , SEEK_END) == -1)return NULL;
        long size = ftell(input);
    
        if(size == -1) return NULL;
        if(fseek(input, 0, SEEK_SET) == -1) return NULL;
        
        /*if using c-compiler: dont cast malloc's return value*/
        char *content = (char*) malloc( (size_t) size +1  );
        if(content == NULL) return NULL;
        
        fread(content, 1, (size_t)size, input);
        if(ferror(input)) {
            free(content);
            return NULL;
        }
        
        fclose(input);
        content[size] = '\0';
        return content;
    }
    
    void print_log(GLuint object)
    {
        GLint log_length = 0;
        if (glIsShader(object))
            glGetShaderiv(object, GL_INFO_LOG_LENGTH, &log_length);
        else if (glIsProgram(object))
            glGetProgramiv(object, GL_INFO_LOG_LENGTH, &log_length);
        else {
            fprintf(stderr, "printlog: Not a shader or a program\n");
            return;
        }
        
        char* log = (char*)malloc(log_length);
        
        if (glIsShader(object))
            glGetShaderInfoLog(object, log_length, NULL, log);
        else if (glIsProgram(object))
            glGetProgramInfoLog(object, log_length, NULL, log);
        
        fprintf(stderr, "%s", log);
        free(log);
    }
    
    [B]GLuint create_shader(const char* filename, GLenum type)
    {
        const GLchar* source = file_read(filename);
        if (source == NULL) {
            fprintf(stderr, "Error opening %s: ", filename); perror("");
            return 0;
        }
        GLuint res = glCreateShader(type);
        const GLchar* sources[2] = {
    #ifdef GL_ES_VERSION_2_0
            "#version 100\n"
            "#define GLES2\n",
    #else
            "#version 120\n",
    #endif
            source };
        glShaderSource(res, 2, sources, NULL);
        free((void*)source);
        
        glCompileShader(res);
        GLint compile_ok = GL_FALSE;
        glGetShaderiv(res, GL_COMPILE_STATUS, &compile_ok);
        if (compile_ok == GL_FALSE) {
            fprintf(stderr, "%s:", filename);
            print_log(res);
            glDeleteShader(res);
            return 0;
        }
        
        return res;
    }
    [/B]
    
    int init_resoureces(void){
       
        GLint compile_ok = GL_FALSE, link_ok = GL_FALSE;
        
        
        GLuint vs, fs;
    [B]    if ((vs = create_shader("triangle.v.glsl", GL_VERTEX_SHADER))   == 0) return 0;
        if ((fs = create_shader("triangle.f.glsl", GL_FRAGMENT_SHADER)) == 0) return 0;[/B]
        
        if(!compile_ok){
            fprintf(stderr, "Error in fragment shader\n");
            return 0;
        }
        
        program = glCreateProgram();
        glAttachShader(program, vs);
        glAttachShader(program, fs);
        glLinkProgram(program);
        glGetProgramiv(program, GL_LINK_STATUS, &link_ok);
        if (!link_ok){
            fprintf(stderr, "glLinkProgram:");
            return 0;
        }
        
        const char* attribute_name = "coord2d";
        attribute_coord2d = glGetAttribLocation(program, attribute_name);
        
        if (attribute_coord2d == -1){
        
            fprintf(stderr, "Could not bind attribute %s\n", attribute_name);
            return 0;
        
        }
        
        
        
        return 1;
    }
    
    void onDisplay(){
    
       //Clear the background as white
        glClearColor(1.0, 1.0, 1.0, 1.0);
        glClear(GL_COLOR_BUFFER_BIT);
        glUseProgram(program);
        glEnableVertexAttribArray(attribute_coord2d);
        GLfloat triangle_vertices[] = {
            0.0, 0.8,
            -0.8, -0.8,
            0.8, -0.8
            
        };
        
        glVertexAttribPointer(attribute_coord2d, 2, GL_FLOAT, GL_FALSE, 0, triangle_vertices);
        glDrawArrays(GL_TRIANGLES, 0, 3);
        glDisableVertexAttribArray(attribute_coord2d);
        
        glutSwapBuffers();
        
    }
    
    void free_resources(){
    
    
    }
    
    
    
    int main(int argc,  char * argv[])
    {
    
       
        
        glutInit(&argc, argv);
        
        glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
        glutInitWindowSize(640, 480);
        glutCreateWindow("My First Triangle");
        
        GLenum glew_status = glewInit();
        if (glew_status != GLEW_OK){
        
            fprintf(stderr, "Error: %s\n", glewGetErrorString(glew_status));
            return EXIT_FAILURE;
        }
        
        if (1 == init_resoureces()) {
            glutDisplayFunc(onDisplay);
            glutMainLoop();
        }
        
        
        free_resources();
        return EXIT_SUCCESS;
        
    
    }
    
    
    The problem is with create_shader. When I try to load my shaders, named triangle.v.glsl and triangle.f.glsl I get an error stating that there is no such file/directory. I see the files in the sidebar of Xcode, though!

    Does anyone know what I'm doing incorrectly?

    Thanks!
     
  2. macrumors regular

    Joined:
    Jun 7, 2009
    #2
    You can open up the built bundle to see if they are actually there. Check the project settings and the build steps and ensure the files are listed in the "copy to bundle" list.
     
  3. thread starter macrumors 6502a

    Joined:
    Dec 29, 2009
    #3
    I just added them to the "Copy Files" tab under "Build Phases" for my target, but I get the same error.
     
  4. macrumors 604

    ArtOfWarfare

    Joined:
    Nov 26, 2007
    #4
    Where are they being copied to? I don't have Xcode up in front of me right now but I believe there's a drop down and text field for you to enter the path that the files should be copied into.
     
  5. macrumors regular

    Joined:
    Jun 7, 2009
    #5
    I didn't realize that this was a console app before, so there is no bundle. In any case, the files need to end up the current directory of your product.

    The Copy Files phase settings allow you to change the destination to the Products Directory. Also, you may need to clear anything in the Subpath box, and disable the "Copy only when installing" option.
     
  6. macrumors 603

    Joined:
    Aug 9, 2009
    #6
  7. thread starter macrumors 6502a

    Joined:
    Dec 29, 2009
    #7
    I cleared the subpath and unchecked "Copy only when installing"


    This worked,

    Thanks!
     

Share This Page