GLSL Shading with obj file

Hi, I’m trying to use shaders to draw an obj file and I don’t know why the object isn’t getting rendered to the screen. This is my first time trying to do something like this so sorry if this seems like a simple issue! I think it’s probably the way I’m binding the buffers or something. The code works when I do a simple triangle in this vertex buffer data:


    static const GLfloat g_vertex_buffer_data[] = {
        -1.0f, -1.0f, 0.0f,
        1.0f, -1.0f, 0.0f,
        0.0f,  1.0f, 0.0f,
    };

but not when I try to parse through the vertices of my obj file. But when I just do glBegin(GL_LINES) on my 3d model (class used to store obj vertices), the object correctly renders to the screen so I know the file itself isn’t wrong. Maybe it’s also because I don’t exactly know what’s going on with the buffers and the entire process of using the shader program after compiling and linking. The last parameter of drawArrays also confuses me a little. I believe it’s the total amount of vertices that need to be drawn which is why mine is such a high number but I could be wrong. Any help would be appreciated, thanks!

---------------------MAIN CODE --------------------------


#include <GL\glew.h>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <fstream>
#include <vector>
#include <sstream>
#include <iterator>
#include <GL\freeglut.h>
#include <string>
#include "model.h"

using namespace std;

// Read our shaders into the appropriate buffers
GLuint useShaders(const char * vertex_file_path, const char * fragment_file_path, 
                model &m) {

    GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER);
    GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);

    // Read the Vertex Shader code from the file
    std::string VertexShaderCode;
    std::ifstream VertexShaderStream(vertex_file_path, std::ios::in);
    if (VertexShaderStream.is_open()) {
        std::stringstream sstr;
        sstr << VertexShaderStream.rdbuf();
        VertexShaderCode = sstr.str();
        VertexShaderStream.close();
    }
    else {
        printf("Impossible to open %s. Are you in the right directory ? Don't forget to read the FAQ !
", vertex_file_path);
        getchar();
        return 0;
    }

    // Read the Fragment Shader code from the file
    std::string FragmentShaderCode;
    std::ifstream FragmentShaderStream(fragment_file_path, std::ios::in);
    if (FragmentShaderStream.is_open()) {
        std::stringstream sstr;
        sstr << FragmentShaderStream.rdbuf();
        FragmentShaderCode = sstr.str();
        FragmentShaderStream.close();
    }

    GLint Result = GL_FALSE;
    int InfoLogLength;

    // Compile Vertex Shader
    printf("Compiling shader : %s
", vertex_file_path);
    char const * VertexSourcePointer = VertexShaderCode.c_str();
    glShaderSource(VertexShaderID, 1, &VertexSourcePointer, NULL);
    glCompileShader(VertexShaderID);

    // Check Vertex Shader
    glGetShaderiv(VertexShaderID, GL_COMPILE_STATUS, &Result);
    glGetShaderiv(VertexShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
    if (InfoLogLength > 0) {
        std::vector<char> VertexShaderErrorMessage(InfoLogLength + 1);
        glGetShaderInfoLog(VertexShaderID, InfoLogLength, NULL, &VertexShaderErrorMessage[0]);
        printf("%s
", &VertexShaderErrorMessage[0]);
    }

    // Compile Fragment Shader
    printf("Compiling shader : %s
", fragment_file_path);
    char const * FragmentSourcePointer = FragmentShaderCode.c_str();
    glShaderSource(FragmentShaderID, 1, &FragmentSourcePointer, NULL);
    glCompileShader(FragmentShaderID);

    // Check Fragment Shader
    glGetShaderiv(FragmentShaderID, GL_COMPILE_STATUS, &Result);
    glGetShaderiv(FragmentShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
    if (InfoLogLength > 0) {
        std::vector<char> FragmentShaderErrorMessage(InfoLogLength + 1);
        glGetShaderInfoLog(FragmentShaderID, InfoLogLength, NULL, &FragmentShaderErrorMessage[0]);
        printf("%s
", &FragmentShaderErrorMessage[0]);
    }

    // Link the program
    printf("Linking program
");
    GLuint ProgramID = glCreateProgram();
    glAttachShader(ProgramID, VertexShaderID);
    glAttachShader(ProgramID, FragmentShaderID);
    glLinkProgram(ProgramID);

    // Check the program
    glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result);
    glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength);
    if (InfoLogLength > 0) {
        std::vector<char> ProgramErrorMessage(InfoLogLength + 1);
        glGetProgramInfoLog(ProgramID, InfoLogLength, NULL, &ProgramErrorMessage[0]);
        printf("%s
", &ProgramErrorMessage[0]);
    }

    glDetachShader(ProgramID, VertexShaderID);
    glDetachShader(ProgramID, FragmentShaderID);

    glDeleteShader(VertexShaderID);
    glDeleteShader(FragmentShaderID);

    glUseProgram(ProgramID);

    GLuint VertexArrayID;
    glGenVertexArrays(1, &VertexArrayID);
    glBindVertexArray(VertexArrayID);

/*    static const GLfloat g_vertex_buffer_data[] = {
        -1.0f, -1.0f, 0.0f,
        1.0f, -1.0f, 0.0f,
        0.0f,  1.0f, 0.0f,
    };*/

    vector<double> g_vertex_buffer_data;

    for (model::Vector3 f : m.faces) {
        g_vertex_buffer_data.push_back(m.verts[f.x - 1].x);
        g_vertex_buffer_data.push_back(m.verts[f.x - 1].y);
        g_vertex_buffer_data.push_back(m.verts[f.x - 1].z);
        g_vertex_buffer_data.push_back(m.verts[f.y - 1].x);
        g_vertex_buffer_data.push_back(m.verts[f.y - 1].y);
        g_vertex_buffer_data.push_back(m.verts[f.y - 1].z);
        g_vertex_buffer_data.push_back(m.verts[f.z - 1].x);
        g_vertex_buffer_data.push_back(m.verts[f.z - 1].y);
        g_vertex_buffer_data.push_back(m.verts[f.z - 1].z);
    }

    static const GLfloat g_vertex_buffer_data[] = {
        -1.0f, -1.0f, 0.0f,
        1.0f, -1.0f, 0.0f,
        0.0f,  1.0f, 0.0f,
    };

    GLuint vertexbuffer;
    // Generate 1 buffer, put the resulting identifier in vertexbuffer
    glGenBuffers(1, &vertexbuffer);
    // The following commands will talk about our 'vertexbuffer' buffer
    glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
    // Give our vertices to OpenGL.
    glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), &g_vertex_buffer_data[0], GL_STATIC_DRAW);
    //glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW);

    glEnableVertexAttribArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);
    glVertexAttribPointer(
        0,                  // attribute 0. No particular reason for 0, but must match the layout in the shader.
        3,                  // size
        GL_FLOAT,           // type
        GL_FALSE,           // normalized?
        0,                  // stride
        (void*)0            // array buffer offset
    );
//    glBindVertexArray(vertexArray);
    //glColor3f(1, 1, 1);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(60, 1, 1, 500000);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    gluLookAt(0, 0, 10, 0, 0, 0, 0, 1, 0);
    glFrustum(-1.0, 1.0, -1.0, 1.0, 1.5, 200.0);


    glDrawArrays(GL_POINTS, 0, 18960); // Starting from vertex 0; 3 vertices total -> 1 triangle
    glDisableVertexAttribArray(0);

}

void readFile(const char* fileName, vector<vector<string>> &v) {
    string line;
    ifstream myFile(fileName);
    if (myFile.is_open()) {
        while (getline(myFile, line)) {
            if (!line.empty()) {
                istringstream buf(line);
                istream_iterator<string> beg(buf), end;
                vector<string> tokens(beg, end);
                v.push_back(tokens);
            }
        }
    }
}

void display() {
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(60, 1, 1, 500000);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    gluLookAt(0, 0, 10, 0, 0, 0, 0, 1, 0);

    vector<vector<string>> list;
    readFile("teapot.obj", list);
    model m(list);
    //m.draw();

    useShaders("vertexShader.txt", "fragmentShader.txt", m);

    glutSwapBuffers();

}

int main(int argc, char** argv) {
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
    glutInitWindowSize(500, 500);
    glutInitWindowPosition(100, 100);
    glutCreateWindow("window");
    glClearColor(0.0, 0.0, 0.0, 0.0);
    glutDisplayFunc(display);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glFrustum(-1.0, 1.0, -1.0, 1.0, 1.5, 200.0);
    glMatrixMode(GL_MODELVIEW);
    GLenum err = glewInit();
    if (GLEW_OK != err) {
    //    cout << "error" << endl;
    }
    glutMainLoop();
    return 0;
}

------------- MODEL CLASS -------------


#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include "model.h"

model::model() {
}

model::model(vector<vector<string>> &s) {
    for (vector<vector<string>>::iterator it = s.begin(); it != s.end(); it++) {
        double x;
        double y;
        double z;
        vector<string> vs = *it;

        x = atof(vs[1].c_str());
        y = atof((*it)[2].c_str());
        z = atof((*it)[3].c_str());
        Vector3 v(x, y, z);

        if ((*it)[0] == "v") {
            verts.push_back(v);
        }
        if ((*it)[0] == "f") {
            faces.push_back(v);
        }

    }
}

void model::draw() {
    for (Vector3 f : faces) {
        glBegin(GL_LINE_LOOP);
        glVertex3f(verts[f.x - 1].x, verts[f.x - 1].y, verts[f.x - 1].z);
        glVertex3f(verts[f.y - 1].x, verts[f.y - 1].y, verts[f.y - 1].z);
        glVertex3f(verts[f.z - 1].x, verts[f.z - 1].y, verts[f.z - 1].z);
        glEnd();
    }
}

-------------MODEL H--------------------------


#ifndef H_model_H
#define H_model_H

#include <GL\glew.h>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <vector>
#include <GL\freeglut.h>

using namespace std;

class model {

    public:

        struct Vector3 {
            double x;
            double y;
            double z;
            Vector3() {}
            Vector3(double n, double n2, double n3) {
                x = n;
                y = n2;
                z = n3;
            }
        };
        Vector3 v3;

        struct Color {
            char r;
            char g;
            char b;
        };

        model();
        model(vector<vector<string>> &s);
        ~model() {}
        void draw();
        vector<Vector3> verts;
        vector<Vector3> faces;
        vector<Color> color;
};

#endif