NongusStudios
NongusStudios

Reputation: 139

OpenGL not drawing triangle in C++

I am learning openGL in C++ and I got to the point where I could draw a triangle. I decided to put the creation of the triangle into a class so that all the code wasn't just in one file and now when I execute the draw function nothing happens. I've been looking through this code for a while now I can't figure out why this happens.

The program dosen't crash it just draws a black background. Also OpenGL does not return any errors.

Here is my main function:

int main(int argc, char* args[]){
    GLrenderer renderer;
    setRendererSettings(&renderer);
    renderer.init();

    //triangle tri = createTriangle();
    //compileShaders();

    glslShader triangle("VertexShader.glsl", "FragShader.glsl");
    std::vector<GLfloat> vertices = {
        -1.0f, -1.0f, 0.0f,
        -1.0f, 1.0f, 0.0f,
        1.0f, -1.0f, 0.0f
    };
    triangle.createShape(vertices);
    triangle.compileShaders();

    while(renderer.shouldRun()){
        input(&renderer);

        glClearColor(0, 0, 0, 1);
        glClear(GL_COLOR_BUFFER_BIT);

        triangle.draw();

        renderer.swapBuffers();
    }
    renderer.destroy();
    return 0;
}

Here is my GLrenderer header

class GLrenderer {
private:
    SDL_Window* window;
    SDL_GLContext GLcontext;
    bool isRunning = false;
    bool initSDL();
    bool initGL();
public:
    GLrenderer();
    int width = 1, height = 1;
    int winX = 0, winY = 0;
    int versionMajor = 3, versionMinor = 3;
    const char* title = "OpenGL window";
    Uint32 flags = SDL_WINDOW_OPENGL|SDL_WINDOW_SHOWN;
    bool init();
    bool shouldRun();
    void setShouldRun(bool value);
    void destroy();
    void swapBuffers();
    SDL_Window* getWindow();
};

The source for GLrenderer

GLrenderer::GLrenderer() {}

bool GLrenderer::init(){
    if(!initSDL()) return false;
    if(!initGL()) return false;
    isRunning = true;
    return true;
}

bool GLrenderer::initSDL(){
    if(SDL_Init(SDL_INIT_EVERYTHING) < 0){
        printf("Failed to init SDL.\n");
        return false;
    }
    window = SDL_CreateWindow(
        title,
        winX, winY,
        width, height,
        flags
    );

    if(window == NULL){
        printf("Failed to create SDL_Window.\n");
        return false;
    }

    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, versionMajor);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, versionMinor);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);

    GLcontext = SDL_GL_CreateContext(window);

    if(!GLcontext){
        printf("Failed to create OpenGl context.\n");
        return false;
    }

    SDL_GL_MakeCurrent(window, GLcontext);

    return true;
}

bool GLrenderer::initGL(){
    glewExperimental = GL_TRUE;
    if(glewInit() != GLEW_OK){
        printf("Failed to init glew.\n");
        return false;
    }
    return true;
}

bool GLrenderer::shouldRun(){
    return isRunning;
}

void GLrenderer::setShouldRun(bool value){
    isRunning = value;
}

void GLrenderer::destroy(){
    SDL_DestroyWindow(window);
    SDL_GL_DeleteContext(GLcontext);
    SDL_Quit();
}

SDL_Window* GLrenderer::getWindow(){
    return window;
}

void GLrenderer::swapBuffers(){
    SDL_GL_SwapWindow(window);
}

Header for my class im using to create the triangle

class glslShader;
std::string readShader(std::string file);

class glslShader {
private:
    GLuint ShaderProgram, VAO, VBO;
    std::string vertexFile, fragFile;
public:
    glslShader(std::string _vertexFile, std::string _fragFile);
    void createShape(std::vector<GLfloat> vertices);
    bool compileShaders();
    void draw();
};

And finally the source for that header

bool fileExsists(std::string file){
    std::fstream test(file);
    return test.good();
}

std::string readShader(std::string file){
    if(!fileExsists(file)){
        printf("Not able to locate shader\n");
        return "";
    }
    const int maxLine = 130;
    std::string shader = "";
    std::fstream shaderFile(file);
    while(!shaderFile.eof()){
        char line[maxLine];
        shaderFile.getline(line, 130);
        shader += line;
        shader += "\n";
    }

    return shader;
}

glslShader::glslShader(std::string _vertexFile, std::string _fragFile) : vertexFile{_vertexFile}, fragFile{_fragFile} {}

void glslShader::createShape(std::vector<GLfloat> vertices){
    glGenVertexArrays(1, &VAO);
    glBindVertexArray(VAO);
        glGenBuffers(1, &VBO);
        glBindBuffer(GL_ARRAY_BUFFER, VBO);
        glBufferData(GL_ARRAY_BUFFER, sizeof(vertices.data()), vertices.data(), GL_STATIC_DRAW);
        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
        glEnableVertexAttribArray(0);
        glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindVertexArray(0);
}

bool addShader(GLuint program, const char* shaderSRC, GLenum type){
    GLuint shader = glCreateShader(type);

    const GLchar* src[1];
    src[0] = shaderSRC;
    GLint size[1];
    size[0] = strlen(shaderSRC);

    glShaderSource(shader, 1, src, size);

    GLint result = 0;
    GLchar log[1024];

    glCompileShader(shader);

    glGetShaderiv(shader, GL_COMPILE_STATUS, &result);
    if(!result){
        glGetShaderInfoLog(shader, 1024, NULL, log);
        printf("ERROR: Failed to compile shader: &s\n", log);
        return false;
    }

    glAttachShader(program, shader);
    return true;
}

bool glslShader::compileShaders(){
    ShaderProgram = glCreateProgram();
    if (!ShaderProgram){
        printf("ERROR: Failed to create shader program.\n");
        return false;
    }

    if (!addShader(ShaderProgram, readShader("VertexShader.glsl").c_str(), GL_VERTEX_SHADER)){
        printf("ERROR: failed to create vertex shader.\n");
        return false;
    }
    if (!addShader(ShaderProgram, readShader("FragShader.glsl").c_str(), GL_FRAGMENT_SHADER)){
        printf("ERROR: failed to create fragment shader.\n");
        return false;
    }

    GLint result = 0;
    GLchar log[1024];

    glLinkProgram(ShaderProgram);
    glGetProgramiv(ShaderProgram, GL_LINK_STATUS, &result);
    if(!result){
        glGetProgramInfoLog(ShaderProgram, sizeof(log), NULL, log);
        printf("ERROR: Failed to link program: %s", log);
        return false;
    }

    glValidateProgram(ShaderProgram);
    glGetProgramiv(ShaderProgram, GL_VALIDATE_STATUS, &result);
    if (!result){
        glGetProgramInfoLog(ShaderProgram, sizeof(log), NULL, log);
        printf("ERROR: Failed to validate program: %s\n", log);
        return false;
    }

    return true;
}

void glslShader::draw(){
    glUseProgram(ShaderProgram);
    glBindVertexArray(VAO);
        glDrawArrays(GL_TRIANGLES, 0, 3);
    glBindVertexArray(0);
    glUseProgram(0);
}

I am certain its not my shader code because I am using the same shaders that I used to render my last triangle before I was using a class.

Upvotes: 0

Views: 158

Answers (1)

NongusStudios
NongusStudios

Reputation: 139

glBufferData(GL_ARRAY_BUFFER, sizeof(_verticies.data()), _verticies.data(), GL_STATIC_DRAW);

Should have been:

glBufferData(GL_ARRAY_BUFFER, _verticies.size() * sizeof(Glfloat), _verticies.data(), GL_STATIC_DRAW);

Upvotes: 2

Related Questions