Why isn't my triangle showing?

Hello, I’m a new member on this forum and a complete OpenGL beginner. I’ve been following the learnopengl tutorial, with some slight variation.

Anyway, I can’t, no matter how I try, manage to get a triangle to show as in the first tutorial. I hate to ask, but it’s clear that I’m missing something very obvious. If anyone could help, I’d be very appreciative.

#include <iostream>
#include <stdio.h>
#include <SDL2/SDL.h>
//#include <SDL2/SDL_ttf.h>
#include <GL/glew.h>
#include <GL/gl.h>
#include <fstream>

#define MESSAGE_LENGTH 512

//using namespace std;
SDL_Window *mainWindow;
SDL_GLContext context;
bool running, saving=false;
int ye_updatedNumber=0;
int mainWindowHeight, mainWindowWidth;
unsigned int shaderProgram, VAO;

// Start Vertex code
float vertices[]={
    .5f, .5f, 0.,
    .5f, .5f, 0.,
    0., .5f, 0.
};
// End Vertex code

void showError(const char *message, int priority){
    std::cout << "[" << priority << "] " << message << "
";
}

int showFatalError(int code){
    switch (code) {
    case 2:
        std::cout << "Unknown problem starting...";
        break;
    case 3:
        std::cout << "Could not load SDL. " << SDL_GetError();
        break;
    case 4:
        std::cout << "Could not start graphical window. " << SDL_GetError();
        break;
    case 6:
        std::cout << "Could not load shader. ";
        break;
    case 7:
        std::cout << "Could not start GLEW.";
        break;
    default:
        std::cout << "UNKNOWN ERROR!";
        break;
    }
    SDL_ClearError();
    return -1;
}

void checkSDLError(){
    std::cout << SDL_GetError();
    SDL_ClearError();
}

int startProgram(){
    return 1;
}

int terminateProgram(){
    std::cout << "Shutting down...";

    SDL_GL_DeleteContext(context);
    SDL_DestroyWindow(mainWindow);

    SDL_Quit();
    running=false;
    return 0;
}

int loadShaders(){
    // START GL SHADER PREPERATION
    std::cout << "Getting shader data.
";
    int shaderCompileStatus;
    char infoLog[MESSAGE_LENGTH];
    //*fragmentShaderData, *vertexShaderData;
    std::cout << "Supported GLSL: " << glGetString(GL_SHADING_LANGUAGE_VERSION) << "
";
    unsigned int vertexShader, fragShaderID;// Used for giving IDs to VBO buffers.
    const char *vertexShaderData="#version 130
"
   "//layout (location = 0) in vec3 aPos;
"
    "out vec4 aPos;
"
    "void main(){
"
        "gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);
"
    "}";

    const char *fragmentShaderData="#version 130
"
            "precision highp float;
"
            "out vec4 FragColor;
"
            "void main(){
"
            "    FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);
"
            "}";
    //glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    std::cout  << "Loading shaders...
";
    // Vertex Shader code
    vertexShader=glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertexShader, 1, &vertexShaderData, NULL);
    glCompileShader(vertexShader);
    glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &shaderCompileStatus);
    if(!shaderCompileStatus){
        glGetShaderInfoLog(vertexShader, MESSAGE_LENGTH, NULL, infoLog);
        showError("Failed to load Vertex shader. ", 1);
        showError(infoLog, 1);
    }
    //std::cout << glGetError() << glewGetErrorString(glGetError()) << "
";
    // End Vertex Shader code
    // Fragment Shader code
    fragShaderID=glCreateShader(GL_FRAGMENT_SHADER);
    std::cout << "Frag shader is " << fragShaderID << "
";
    glShaderSource(fragShaderID, 1, &fragmentShaderData, NULL);
    glCompileShader(fragShaderID);
    glGetShaderiv(fragShaderID, GL_COMPILE_STATUS, &shaderCompileStatus);
    if(!shaderCompileStatus){
        glGetShaderInfoLog(fragShaderID, MESSAGE_LENGTH, NULL, infoLog);
        showError("Failed to load Fragment shader. ", 1);
        showError(infoLog, 1);
    }
    // End Fragment Shader code
    shaderProgram=glCreateProgram();

    glBindAttribLocation(shaderProgram, 0, "aPos");//Replaces layout(location=0)... isnce some OpenGL can't handle that.

    std::cout << "Shader program is " << shaderProgram << "
";
    glAttachShader(shaderProgram, vertexShader);
    glAttachShader(shaderProgram, fragShaderID);
    glLinkProgram(shaderProgram);
    glGetProgramiv(shaderProgram, GL_LINK_STATUS, &shaderCompileStatus);
    if(!shaderCompileStatus){
        glGetProgramInfoLog(shaderProgram, MESSAGE_LENGTH, NULL, infoLog);
        showError("Failed to load shader. ", 1);
        showError(infoLog, 1);
    }
    glDeleteShader(vertexShader);
    glDeleteShader(fragShaderID);
    // END GL SHADER PREPARATION
    return 0;
}

void initBuffers(){
    unsigned int VBO, vertexLocation;

    glGenVertexArrays(1, &VAO);

    std::cout << "Creating buffers...
";
    glGenBuffers(1, &VBO);
    glBindVertexArray(VAO);// Bind vertex array object.

    glBindBuffer(GL_ARRAY_BUFFER, VBO); // Copy vertices into buffer for OpenGL to use.
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    vertexLocation=0;
    glVertexAttribPointer(vertexLocation, 3, GL_FLOAT, GL_FALSE, 3*sizeof(float), (void*)0);//Set vertex attribute pointers
    glEnableVertexAttribArray(vertexLocation);//Enable generic vertex attribute array

    glBindBuffer(GL_ARRAY_BUFFER, 0);

    //glUseProgram(shaderProgram);// Set OpenGL to use shader object when we want to render.
    glBindVertexArray(VAO);
    //glDeleteProgram(shaderProgram);

    //Move the below to a more appropriate function.

    //glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3*sizeof(float), (void*)0);
    glEnableVertexAttribArray(0);

    //glDrawArrays(GL_TRIANGLES, 0, 3);


}

int main()
{
    //glfwW
    bool glewExperimental=true;
    std::cout << glewExperimental;
    if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_GAMECONTROLLER) < 0)
        return showFatalError(2);

    mainWindow=SDL_CreateWindow(
                "Test Window",
                SDL_WINDOWPOS_CENTERED,
                SDL_WINDOWPOS_CENTERED,
                512, 512,
                SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE);

    context=SDL_GL_CreateContext(mainWindow);
    //SDL_SetWindowResizable

    if(mainWindow==NULL)
        return showFatalError(3);

    std::cout << "Hello World!" << std::endl;
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK,
                        SDL_GL_CONTEXT_PROFILE_CORE);// Ignore old, deprecated SDL.
    //SDL_GL_SetAttribute(SDL_GL_O)

    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);//Draw off-screen and copy to screen.
    //SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24)
    checkSDLError();

    glClearColor(.5, .5, .5, .5);

    glewInit();

    loadShaders();
    initBuffers();

    SDL_Event event;
    running=true;
    while(running){
        SDL_PollEvent(&event);
        if(event.type==SDL_QUIT){
            std::cout << "Bye";
            terminateProgram();
        }else if (event.type==SDL_KEYDOWN){
            switch(event.key.keysym.sym){
            case SDLK_ESCAPE:
                terminateProgram();
            }
        }else if (event.type==SDL_WINDOWEVENT) {
            switch (event.window.event) {
            case SDL_WINDOWEVENT_RESIZED:
            case SDL_WINDOWEVENT_SIZE_CHANGED:
                SDL_GetWindowSize(mainWindow, &mainWindowWidth, &mainWindowHeight);
                glViewport(0, 0, mainWindowWidth, mainWindowHeight);
                glClearColor(.5, .5, .5, .5);
                std::cout << "Why are you resizing? 
";
                break;
            default:
                break;
            }
        }

        //glClearColor(.5, .5, .5, 1);
        glClear(GL_COLOR_BUFFER_BIT);

        glUseProgram(shaderProgram);
        glBindVertexArray(VAO);// Bind vertex array object.
        glDrawArrays(GL_TRIANGLES, 0, 3);

        SDL_GL_SwapWindow(mainWindow);

        SDL_Delay(5);
    }
    terminateProgram();
    return 0;
}

Hello, I’m a new member on this forum and a complete OpenGL beginner.

Welcome to the forum! You posted a lot of code and searching for the relevant pieces makes it for a lazy guy like me hard to stay focussed :p.

This might be the/an issue:


    vertexLocation=0;
    glVertexAttribPointer(vertexLocation, 3, GL_FLOAT, GL_FALSE, 3*sizeof(float), (void*)0);//Set vertex attribute pointers
    glEnableVertexAttribArray(vertexLocation);//Enable generic vertex attribute array

You need to enable attibutes before you do something with them. So try switching both lines. Otherwise I didn’t see anything in particular at first glance.

Here are some hints that might make it easier for you and us to debug your code:

  • If you don’t use git or subversion, make a copy of your code and start removing pieces of code that are not relevant to the problem. This makes it easier to track the exact location of your problem, especially if you post it to a forum. If there are more than 20 lines a lot of people stop reading. TL;DR. Irrelevant in this case are things like the shutdown function, a lot of the cout’s, your error code analysis (Errorcode to output) etc.

  • Put glGetError after glDrawArrays(GL_TRIANGLES, 0, 3). If it returns something other than GL_NO_ERROR, start moving glGetError upwards until it disappears. This is how you track down the exact location of the problem (if it is an API error). However, with OpenGL 4.3 there is a better way to find errors, but it is a little bit more complicated so stick to glGetError for now.

  • Use string literals (C++11) with your shader code. The "…
    " for every shader line makes it hard to read. With string literals you can write:


    const char* fragmentShaderCode = R"glsl(
            #version 430

            in vec3 Color;

            out vec4 FragColor;
            void main(void)
            {
                FragColor = vec4(Color,1.0);
            }
            )glsl";

instead of the ugly version


    const char* fragmentShaderCode= 
            "#version 430
"
            "
"
            "in vec3 Color;
"
            "
"
            "out vec4 FragColor;
"
            "void main(void)
"
            "{
"
            "    FragColor = vec4(Color,1.0);
"
            "}
";

You need to enable attibutes before you do something with them.

This is untrue. The array state for an attribute array can be set regardless of whether it is enabled.

Okay, thx for the clarification.